From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje. Note that embryo wont be used, but I'm not sure yet if you can build edje without it. --- .../evas/src/modules/engines/fb/evas_engine.c | 317 +++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 libraries/evas/src/modules/engines/fb/evas_engine.c (limited to 'libraries/evas/src/modules/engines/fb/evas_engine.c') diff --git a/libraries/evas/src/modules/engines/fb/evas_engine.c b/libraries/evas/src/modules/engines/fb/evas_engine.c new file mode 100644 index 0000000..7681b00 --- /dev/null +++ b/libraries/evas/src/modules/engines/fb/evas_engine.c @@ -0,0 +1,317 @@ +#include "evas_common.h" +#include "evas_private.h" +#include "evas_engine.h" +#include "Evas_Engine_FB.h" + +int _evas_engine_fb_log_dom = -1; + +/* function tables - filled in later (func and parent func) */ +static Evas_Func func, pfunc; + +/* engine struct data */ +typedef struct _Render_Engine Render_Engine; + +struct _Render_Engine +{ + Tilebuf *tb; + Outbuf *ob; + Tilebuf_Rect *rects; + Eina_Inlist *cur_rect; + int end : 1; +}; + +/* prototypes we will use here */ +static void *_output_setup(int w, int h, int rot, int vt, int dev, int refresh); + +static void *eng_info(Evas *e); +static void eng_info_free(Evas *e, void *info); +static int eng_setup(Evas *e, void *info); +static void eng_output_free(void *data); +static void eng_output_resize(void *data, int w, int h); +static void eng_output_tile_size_set(void *data, int w, int h); +static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h); +static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h); +static void eng_output_redraws_clear(void *data); +static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch); +static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h); +static void eng_output_flush(void *data); +static void eng_output_idle_flush(void *data); + +/* internal engine routines */ +static void * +_output_setup(int w, int h, int rot, int vt, int dev, int refresh) +{ + Render_Engine *re; + + re = calloc(1, sizeof(Render_Engine)); + if (!re) + return NULL; + /* if we haven't initialized - init (automatic abort if already done) */ + evas_common_cpu_init(); + + evas_common_blend_init(); + evas_common_image_init(); + evas_common_convert_init(); + evas_common_scale_init(); + evas_common_rectangle_init(); + evas_common_polygon_init(); + evas_common_line_init(); + evas_common_font_init(); + evas_common_draw_init(); + evas_common_tilebuf_init(); + + evas_fb_outbuf_fb_init(); + + /* get any stored performance metrics from device (xserver) */ + re->ob = evas_fb_outbuf_fb_setup_fb(w, h, rot, OUTBUF_DEPTH_INHERIT, vt, dev, refresh); + re->tb = evas_common_tilebuf_new(evas_fb_outbuf_fb_get_width(re->ob), evas_fb_outbuf_fb_get_height(re->ob)); + /* no backbuf! */ + evas_fb_outbuf_fb_set_have_backbuf(re->ob, 0); + /* in preliminary tests 16x16 gave highest framerates */ + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + return re; +} + +/* engine api this module provides */ +static void * +eng_info(Evas *e) +{ + Evas_Engine_Info_FB *info; + info = calloc(1, sizeof(Evas_Engine_Info_FB)); + if (!info) return NULL; + info->magic.magic = rand(); + info->render_mode = EVAS_RENDER_MODE_BLOCKING; + return info; + e = NULL; +} + +static void +eng_info_free(Evas *e __UNUSED__, void *info) +{ + Evas_Engine_Info_FB *in; + in = (Evas_Engine_Info_FB *)info; + free(in); +} + +static int +eng_setup(Evas *e, void *in) +{ + Render_Engine *re; + Evas_Engine_Info_FB *info; + + info = (Evas_Engine_Info_FB *)in; + re = _output_setup(e->output.w, + e->output.h, + info->info.rotation, + info->info.virtual_terminal, + info->info.device_number, + info->info.refresh); + e->engine.data.output = re; + if (!e->engine.data.output) return 0; + e->engine.data.context = e->engine.func->context_new(e->engine.data.output); + + return 1; +} + +static void +eng_output_free(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_fb_outbuf_fb_free(re->ob); + evas_common_tilebuf_free(re->tb); + if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); + free(re); + + evas_common_font_shutdown(); + evas_common_image_shutdown(); +} + +static void +eng_output_resize(void *data, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_fb_outbuf_fb_reconfigure(re->ob, w, h, + evas_fb_outbuf_fb_get_rot(re->ob), + OUTBUF_DEPTH_INHERIT); + evas_common_tilebuf_free(re->tb); + re->tb = evas_common_tilebuf_new(w, h); + if (re->tb) + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); +} + +static void +eng_output_tile_size_set(void *data, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_set_tile_size(re->tb, w, h); +} + +static void +eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_add_redraw(re->tb, x, y, w, h); +} + +static void +eng_output_redraws_rect_del(void *data, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_del_redraw(re->tb, x, y, w, h); +} + +static void +eng_output_redraws_clear(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + evas_common_tilebuf_clear(re->tb); +} + +static void * +eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) +{ + Render_Engine *re; + RGBA_Image *surface; + Tilebuf_Rect *rect; + int ux, uy, uw, uh; + + re = (Render_Engine *)data; + if (re->end) + { + re->end = 0; + return NULL; + } + if (!re->rects) + { + re->rects = evas_common_tilebuf_get_render_rects(re->tb); + re->cur_rect = EINA_INLIST_GET(re->rects); + } + if (!re->cur_rect) return NULL; + rect = (Tilebuf_Rect *)re->cur_rect; + ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h; + re->cur_rect = re->cur_rect->next; + if (!re->cur_rect) + { + evas_common_tilebuf_free_render_rects(re->rects); + re->rects = NULL; + re->end = 1; + } + + surface = evas_fb_outbuf_fb_new_region_for_update(re->ob, + ux, uy, uw, uh, + cx, cy, cw, ch); + *x = ux; *y = uy; *w = uw; *h = uh; + return surface; +} + +static void +eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +#ifdef BUILD_PIPE_RENDER + evas_common_pipe_map_begin(surface); +#endif + evas_fb_outbuf_fb_push_updated_region(re->ob, surface, x, y, w, h); + evas_fb_outbuf_fb_free_region_for_update(re->ob, surface); + evas_common_cpu_end_opt(); +} + +static void +eng_output_flush(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static void +eng_output_idle_flush(void *data) +{ + Render_Engine *re; + + re = (Render_Engine *)data; +} + +static Eina_Bool +eng_canvas_alpha_get(void *data, void *context __UNUSED__) +{ + Render_Engine *re; + + re = (Render_Engine *)data; + return (re->ob->priv.fb.fb->fb_var.transp.length > 0); +} + +/* module advertising code */ +static int +module_open(Evas_Module *em) +{ + if (!em) return 0; + /* get whatever engine module we inherit from */ + if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0; + _evas_engine_fb_log_dom = eina_log_domain_register + ("evas-fb", EVAS_DEFAULT_LOG_COLOR); + if (_evas_engine_fb_log_dom < 0) + { + EINA_LOG_ERR("Can not create a module log domain."); + return 0; + } + + /* store it for later use */ + func = pfunc; + /* now to override methods */ +#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) + ORD(info); + ORD(info_free); + ORD(setup); + ORD(canvas_alpha_get); + ORD(output_free); + ORD(output_resize); + ORD(output_tile_size_set); + ORD(output_redraws_rect_add); + ORD(output_redraws_rect_del); + ORD(output_redraws_clear); + ORD(output_redraws_next_update_get); + ORD(output_redraws_next_update_push); + ORD(output_flush); + ORD(output_idle_flush); + /* now advertise out own api */ + em->functions = (void *)(&func); + return 1; +} + +static void +module_close(Evas_Module *em __UNUSED__) +{ + eina_log_domain_unregister(_evas_engine_fb_log_dom); +} + +static Evas_Module_Api evas_modapi = +{ + EVAS_MODULE_API_VERSION, + "fb", + "none", + { + module_open, + module_close + } +}; + +EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, fb); + +#ifndef EVAS_STATIC_BUILD_FB +EVAS_EINA_MODULE_DEFINE(engine, fb); +#endif -- cgit v1.1