diff options
author | Cedric BAIL <c.bail@partner.samsung.com> | 2014-06-25 10:47:08 +0200 |
---|---|---|
committer | Cedric BAIL <c.bail@partner.samsung.com> | 2014-07-04 15:11:22 +0200 |
commit | e4a4304dc4158159ad62fc318f29248d9b2945f9 (patch) | |
tree | 3e77faa3a237a22dc338a72c706abd5cf7821103 | |
parent | 325d760c554d9bc1e2b531382c0182ad439024c7 (diff) | |
download | efl-e4a4304dc4158159ad62fc318f29248d9b2945f9.tar.gz |
evas: simplify DRM backend to use Software generic infrastructure more.
-rw-r--r-- | src/modules/evas/engines/drm/evas_engine.c | 401 | ||||
-rw-r--r-- | src/modules/evas/engines/drm/evas_engine.h | 64 | ||||
-rw-r--r-- | src/modules/evas/engines/drm/evas_outbuf.c | 40 |
3 files changed, 102 insertions, 403 deletions
diff --git a/src/modules/evas/engines/drm/evas_engine.c b/src/modules/evas/engines/drm/evas_engine.c index 4bed29a623..68f586ae33 100644 --- a/src/modules/evas/engines/drm/evas_engine.c +++ b/src/modules/evas/engines/drm/evas_engine.c @@ -5,24 +5,13 @@ typedef struct _Render_Engine Render_Engine; struct _Render_Engine { - Evas_Engine_Info_Drm *info; - - Tilebuf *tb; - Tilebuf_Rect *rects; - Tilebuf_Rect *prev_rects[3]; - - Outbuf *ob; + Render_Engine_Software_Generic generic; - short mode; - - Eina_Inlist *cur_rect; - - Eina_Bool end : 1; - Eina_Bool lost_back : 1; + Evas_Engine_Info_Drm *info; }; /* local function prototypes */ -static void *_output_setup(Evas_Engine_Info_Drm *info, int w, int h, int swap); +static void *_output_setup(Evas_Engine_Info_Drm *info, int w, int h); /* function tables - filled in later (func and parent func) */ static Evas_Func func, pfunc; @@ -32,56 +21,51 @@ int _evas_engine_drm_log_dom; /* local functions */ static void * -_output_setup(Evas_Engine_Info_Drm *info, int w, int h, int swap) +_output_setup(Evas_Engine_Info_Drm *info, int w, int h) { Render_Engine *re; + Outbuf *ob; /* try to allocate space for our render engine structure */ if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL; - /* try to create a new tilebuffer */ - if (!(re->tb = evas_common_tilebuf_new(w, h))) - { - free(re); - return NULL; - } - - /* set tilesize */ - evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + /* try to create new outbuf */ + if (!(ob = evas_outbuf_setup(info, w, h))) + goto on_error; + + if(!evas_render_engine_software_generic_init(&re->generic, ob, + evas_outbuf_buffer_state_get, + evas_outbuf_get_rot, + evas_outbuf_reconfigure, + evas_outbuf_update_region_new, + evas_outbuf_update_region_push, + evas_outbuf_update_region_free, + NULL, + evas_outbuf_flush, + evas_outbuf_free, + w, h)) + goto on_error; /* if we have no drm device, get one */ if (info->info.fd < 0) { /* try to init drm (this includes openening the card & tty) */ if (!evas_drm_init(info)) - { - if (re->tb) evas_common_tilebuf_free(re->tb); - free(re); - return NULL; - } + goto on_error; } - if (swap) - { - /* free any existing outbuf */ - if (re->ob) evas_outbuf_free(re->ob); - - /* try to create new outbuf */ - if (!(re->ob = evas_outbuf_setup(info, w, h))) - { - if (re->tb) evas_common_tilebuf_free(re->tb); + /* return the allocated render_engine structure */ + return re; - /* shutdown drm card & tty */ - evas_drm_shutdown(info); + on_error: + evas_render_engine_software_generic_clean(&re->generic); - free(re); - return NULL; - } - } + /* shutdown drm card & tty */ + evas_drm_shutdown(info); - /* return the allocated render_engine structure */ - return re; + free(re); + return NULL; } /* engine api functions */ @@ -101,7 +85,7 @@ eng_info(Evas *evas EINA_UNUSED) return info; } -static void +static void eng_info_free(Evas *evas EINA_UNUSED, void *einfo) { Evas_Engine_Info_Drm *info; @@ -111,7 +95,7 @@ eng_info_free(Evas *evas EINA_UNUSED, void *einfo) free(info); } -static int +static int eng_setup(Evas *evas, void *einfo) { Evas_Engine_Info_Drm *info; @@ -125,17 +109,15 @@ eng_setup(Evas *evas, void *einfo) if (!(epd = eo_data_scope_get(evas, EVAS_CANVAS_CLASS))) return 0; /* set canvas reference - * - * NB: We do this here so that on a vt switch, we can disable + * + * NB: We do this here so that on a vt switch, we can disable * rendering (or re-enable) for this canvas */ info->info.evas = evas; /* check for valid engine output */ if (!(re = epd->engine.data.output)) { - static int swap = -1; - - /* NB: If we have no valid output then assume we have not been + /* NB: If we have no valid output then assume we have not been * initialized yet and call any needed common init routines */ evas_common_cpu_init(); evas_common_blend_init(); @@ -149,25 +131,20 @@ eng_setup(Evas *evas, void *einfo) evas_common_draw_init(); evas_common_tilebuf_init(); - /* check if swapping is disabled */ - if (swap == -1) - { - if (getenv("EVAS_DRM_NO_SWAP")) swap = 0; - else swap = 1; - } - /* try to create a new render_engine */ - if (!(re = _output_setup(info, epd->output.w, epd->output.h, swap))) + if (!(re = _output_setup(info, epd->output.w, epd->output.h))) return 0; } else { - /* if we have an existing outbuf, free it */ - if (re->ob) evas_outbuf_free(re->ob); + Outbuf *ob; /* try to create a new outbuf */ - if (!(re->ob = evas_outbuf_setup(info, epd->output.w, epd->output.h))) - return 0; + ob = evas_outbuf_setup(info, epd->output.w, epd->output.h); + if (ob) return 0; + + /* if we have an existing outbuf, free it */ + evas_render_engine_software_generic_update(&re->generic, ob); } /* update the info structure pointer */ @@ -181,299 +158,26 @@ eng_setup(Evas *evas, void *einfo) if (!epd->engine.data.context) { /* create a context if needed */ - epd->engine.data.context = + epd->engine.data.context = epd->engine.func->context_new(epd->engine.data.output); } return 1; } -static void +static void eng_output_free(void *data) { - Render_Engine *re; + Render_Engine *re = data; - if ((re = data)) - { - if (re->ob) evas_outbuf_free(re->ob); - if (re->tb) evas_common_tilebuf_free(re->tb); - if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); - if (re->prev_rects[0]) - evas_common_tilebuf_free_render_rects(re->prev_rects[0]); - if (re->prev_rects[1]) - evas_common_tilebuf_free_render_rects(re->prev_rects[1]); - if (re->prev_rects[2]) - evas_common_tilebuf_free_render_rects(re->prev_rects[2]); - - evas_drm_shutdown(re->info); - - free(re); - } + evas_drm_shutdown(re->info); + evas_render_engine_software_generic_clean(&re->generic); + free(re); evas_common_font_shutdown(); evas_common_image_shutdown(); } -static void -eng_output_resize(void *data, int w, int h) -{ - Render_Engine *re; - - /* try to get the render_engine */ - if (!(re = (Render_Engine *)data)) return; - - evas_outbuf_reconfigure(re->info, re->ob, w, h); - - if (re->tb) evas_common_tilebuf_free(re->tb); - if ((re->tb = evas_common_tilebuf_new(w, h))) - 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; - - /* try to get the render_engine */ - if (!(re = (Render_Engine *)data)) return; - if (re->tb) 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; - - /* try to get the render_engine */ - if (!(re = (Render_Engine *)data)) return; - if (re->tb) 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; - - /* try to get the render_engine */ - if (!(re = (Render_Engine *)data)) return; - if (re->tb) evas_common_tilebuf_del_redraw(re->tb, x, y, w, h); -} - -static void -eng_output_redraws_clear(void *data) -{ - Render_Engine *re; - - /* try to get the render_engine */ - if (!(re = (Render_Engine *)data)) return; - if (re->tb) evas_common_tilebuf_clear(re->tb); -} - -static Tilebuf_Rect * -_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3) -{ - Tilebuf_Rect *r, *rects; - - if (r1) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r) - evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h); - } - if (r2) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r) - evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h); - } - if (r3) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r) - evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h); - } - rects = evas_common_tilebuf_get_render_rects(tb); - -/* - // bounding box -> make a bounding box single region update of all regions. - // yes we could try and be smart and figure out size of regions, how far - // apart etc. etc. to try and figure out an optimal "set". this is a tradeoff - // between multiple update regions to render and total pixels to render. - if (rects) - { - px1 = rects->x; py1 = rects->y; - px2 = rects->x + rects->w; py2 = rects->y + rects->h; - EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) - { - if (r->x < x1) px1 = r->x; - if (r->y < y1) py1 = r->y; - if ((r->x + r->w) > x2) px2 = r->x + r->w; - if ((r->y + r->h) > y2) py2 = r->y + r->h; - } - evas_common_tilebuf_free_render_rects(rects); - rects = calloc(1, sizeof(Tilebuf_Rect)); - if (rects) - { - rects->x = px1; - rects->y = py1; - rects->w = px2 - px1; - rects->h = py2 - py1; - } - } - */ - evas_common_tilebuf_clear(tb); - return rects; -} - -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 *img; - Tilebuf_Rect *rect; - - /* try to get the render_engine */ - if (!(re = (Render_Engine *)data)) return NULL; - -#define CLEAR_PREV_RECTS(x) \ - do { \ - if (re->prev_rects[x]) \ - evas_common_tilebuf_free_render_rects(re->prev_rects[x]); \ - re->prev_rects[x] = NULL; \ - } while (0) - - if (re->end) - { - re->end = EINA_FALSE; - return NULL; - } - - if (!re->rects) - { - re->mode = evas_outbuf_buffer_state_get(re->ob); - if ((re->rects = evas_common_tilebuf_get_render_rects(re->tb))) - { - if ((re->lost_back) || (re->mode == MODE_FULL)) - { - re->lost_back = EINA_FALSE; - evas_common_tilebuf_add_redraw(re->tb, - 0, 0, re->ob->w, re->ob->h); - evas_common_tilebuf_free_render_rects(re->rects); - re->rects = evas_common_tilebuf_get_render_rects(re->tb); - } - - evas_common_tilebuf_clear(re->tb); - CLEAR_PREV_RECTS(2); - re->prev_rects[2] = re->prev_rects[1]; - re->prev_rects[1] = re->prev_rects[0]; - re->prev_rects[0] = re->rects; - re->rects = NULL; - - switch (re->mode) - { - case MODE_FULL: - case MODE_COPY: - re->rects = - _merge_rects(re->tb, re->prev_rects[0], NULL, NULL); - break; - case MODE_DOUBLE: - re->rects = - _merge_rects(re->tb, re->prev_rects[0], re->prev_rects[1], NULL); - break; - case MODE_TRIPLE: - re->rects = - _merge_rects(re->tb, re->prev_rects[0], re->prev_rects[1], re->prev_rects[2]); - break; - default: - break; - } - } - - /* NB: Not sure this is entirely needed here as it's already done - * inside _merge_rects */ - evas_common_tilebuf_clear(re->tb); - re->cur_rect = EINA_INLIST_GET(re->rects); - } - - if (!re->cur_rect) return NULL; - rect = (Tilebuf_Rect *)re->cur_rect; - if (re->rects) - { - switch (re->mode) - { - case MODE_COPY: - case MODE_DOUBLE: - case MODE_TRIPLE: - rect = (Tilebuf_Rect *)re->cur_rect; - *x = rect->x; - *y = rect->y; - *w = rect->w; - *h = rect->h; - *cx = rect->x; - *cy = rect->y; - *cw = rect->w; - *ch = rect->h; - re->cur_rect = re->cur_rect->next; - break; - case MODE_FULL: - re->cur_rect = NULL; - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = re->ob->w; - if (h) *h = re->ob->h; - if (cx) *cx = 0; - if (cy) *cy = 0; - if (cw) *cw = re->ob->w; - if (ch) *ch = re->ob->h; - break; - default: - break; - } - img = - evas_outbuf_update_region_new(re->ob, *x, *y, *w, *h, - cx, cy, cw, ch); - if (!re->cur_rect) - { - /* evas_common_tilebuf_free_render_rects(re->rects); */ - /* re->rects = NULL; */ - re->end = EINA_TRUE; - } - - return img; - } - - return NULL; -} - -static void -eng_output_redraws_next_update_push(void *data, void *img, int x, int y, int w, int h, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - if (!(re = (Render_Engine *)data)) return; -#if defined(BUILD_PIPE_RENDER) - evas_common_pipe_map_begin(img); -#endif - evas_outbuf_update_region_push(re->ob, img, x, y, w, h); - - /* NB: No reason to free region here. That is done on flush anyway */ - /* evas_outbuf_update_region_free(re->ob, img); */ - - evas_common_cpu_end_opt(); -} - -static void -eng_output_flush(void *data, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - if (!(re = (Render_Engine *)data)) return; - evas_outbuf_flush(re->ob); - if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); - re->rects = NULL; -} - /* module api functions */ static int module_open(Evas_Module *em) @@ -503,15 +207,6 @@ module_open(Evas_Module *em) EVAS_API_OVERRIDE(info_free, &func, eng_); EVAS_API_OVERRIDE(setup, &func, eng_); EVAS_API_OVERRIDE(output_free, &func, eng_); - EVAS_API_OVERRIDE(output_resize, &func, eng_); - EVAS_API_OVERRIDE(output_tile_size_set, &func, eng_); - EVAS_API_OVERRIDE(output_redraws_rect_add, &func, eng_); - EVAS_API_OVERRIDE(output_redraws_rect_del, &func, eng_); - EVAS_API_OVERRIDE(output_redraws_clear, &func, eng_); - EVAS_API_OVERRIDE(output_redraws_next_update_get, &func, eng_); - EVAS_API_OVERRIDE(output_redraws_next_update_push, &func, eng_); - EVAS_API_OVERRIDE(output_flush, &func, eng_); - /* EVAS_API_OVERRIDE(output_idle_flush, &func, eng_); */ /* advertise our engine functions */ em->functions = (void *)(&func); diff --git a/src/modules/evas/engines/drm/evas_engine.h b/src/modules/evas/engines/drm/evas_engine.h index 675c9e50ac..cf4e22206a 100644 --- a/src/modules/evas/engines/drm/evas_engine.h +++ b/src/modules/evas/engines/drm/evas_engine.h @@ -17,6 +17,8 @@ #include <unistd.h> #include <fcntl.h> +#include "../software_generic/Evas_Engine_Software_Generic.h" + extern int _evas_engine_drm_log_dom; # ifdef ERR @@ -51,22 +53,6 @@ typedef struct _Buffer Buffer; typedef struct _Plane Plane; typedef struct _Outbuf Outbuf; -enum -{ - MODE_FULL, - MODE_COPY, - MODE_DOUBLE, - MODE_TRIPLE -}; - -enum -{ - OUTBUF_DEPTH_NONE, - OUTBUF_DEPTH_ARGB_32BPP_8888_8888, - OUTBUF_DEPTH_RGB_32BPP_8888_8888, - OUTBUF_DEPTH_LAST -}; - struct _Buffer { int w, h; @@ -100,37 +86,43 @@ struct _Plane struct _Outbuf { + Evas_Engine_Info_Drm *info; + int w, h; - unsigned int rotation, depth; - Eina_Bool destination_alpha : 1; - Eina_Bool vsync : 1; + int rotation; + unsigned int depth; - struct - { - int fd; - unsigned int conn, crtc, fb; + struct + { + Buffer buffer[NUM_BUFFERS]; - Buffer buffer[NUM_BUFFERS]; - int curr, num; + Eina_List *pending_writes; + Eina_List *planes; - drmModeModeInfo mode; - drmEventContext ctx; - Eina_Bool pending_flip : 1; +# ifdef HAVE_DRM_HW_ACCEL + void *surface; +# endif - Eina_List *pending_writes; + int fd; + unsigned int conn, crtc, fb; - Eina_List *planes; + int curr, num; -# ifdef HAVE_DRM_HW_ACCEL - void *surface; -# endif - } priv; + drmModeModeInfo mode; + drmEventContext ctx; + + Eina_Bool pending_flip : 1; + } priv; + + Eina_Bool destination_alpha : 1; + Eina_Bool vsync : 1; }; Outbuf *evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h); void evas_outbuf_free(Outbuf *ob); -void evas_outbuf_reconfigure(Evas_Engine_Info_Drm *info, Outbuf *ob, int w, int h); -int evas_outbuf_buffer_state_get(Outbuf *ob); +void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); +Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob); +int evas_outbuf_get_rot(Outbuf *ob); RGBA_Image *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); diff --git a/src/modules/evas/engines/drm/evas_outbuf.c b/src/modules/evas/engines/drm/evas_outbuf.c index 80f031dbf7..1e33315626 100644 --- a/src/modules/evas/engines/drm/evas_outbuf.c +++ b/src/modules/evas/engines/drm/evas_outbuf.c @@ -133,10 +133,12 @@ evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h) /* set back buffer as first one to draw into */ /* ob->priv.curr = (ob->priv.num - 1); */ + ob->info = info; + return ob; } -void +void evas_outbuf_free(Outbuf *ob) { int i = 0; @@ -149,22 +151,25 @@ evas_outbuf_free(Outbuf *ob) free(ob); } -void -evas_outbuf_reconfigure(Evas_Engine_Info_Drm *info, Outbuf *ob, int w, int h) +void +evas_outbuf_reconfigure(Outbuf *ob, + int w, int h, + int rot, + Outbuf_Depth depth) { int i = 0; /* check for changes */ - if ((ob->w == w) && (ob->h == h) && - (ob->destination_alpha == info->info.destination_alpha) && - (ob->rotation == info->info.rotation) && - (ob->depth == info->info.depth)) + if ((ob->w == w) && (ob->h == h) && + (ob->destination_alpha == ob->info->info.destination_alpha) && + (ob->rotation == rot) && + (ob->depth == depth)) return; /* set new outbuf properties */ - ob->rotation =info->info. rotation; - ob->depth = info->info.depth; - ob->destination_alpha = info->info.destination_alpha; + ob->rotation = rot; + ob->depth = depth; + ob->destination_alpha = ob->info->info.destination_alpha; /* handle rotation */ if ((ob->rotation == 0) || (ob->rotation == 180)) @@ -196,7 +201,7 @@ evas_outbuf_reconfigure(Evas_Engine_Info_Drm *info, Outbuf *ob, int w, int h) } } -int +Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob) { int i = 0, n = 0, count = 0; @@ -399,10 +404,11 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int rect.w, rect.h, x + rx, y + ry, NULL); } -void -evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update) +void +evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, + RGBA_Image *update EINA_UNUSED) { - evas_cache_image_drop(&update->cache_entry); + /* evas_cache_image_drop(&update->cache_entry); */ } void @@ -478,3 +484,9 @@ evas_outbuf_flush(Outbuf *ob) /* force a buffer swap */ _evas_outbuf_buffer_swap(ob, rects, n); } + +int +evas_outbuf_get_rot(Outbuf *ob) +{ + return ob->info->info.rotation; +} |