diff --git a/src/modules/evas/engines/buffer/evas_engine.c b/src/modules/evas/engines/buffer/evas_engine.c index 516e055f9b..1e47cb55db 100644 --- a/src/modules/evas/engines/buffer/evas_engine.c +++ b/src/modules/evas/engines/buffer/evas_engine.c @@ -107,6 +107,7 @@ _output_setup(int w, evas_buffer_outbuf_buf_swap_mode_get, evas_buffer_outbuf_buf_rot_get, evas_buffer_outbuf_reconfigure, + NULL, evas_buffer_outbuf_buf_new_region_for_update, evas_buffer_outbuf_buf_push_updated_region, evas_buffer_outbuf_buf_free_region_for_update, diff --git a/src/modules/evas/engines/drm/evas_engine.c b/src/modules/evas/engines/drm/evas_engine.c index 4bed29a623..41dd8aba6b 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 { + Render_Engine_Software_Generic generic; + Evas_Engine_Info_Drm *info; - - Tilebuf *tb; - Tilebuf_Rect *rects; - Tilebuf_Rect *prev_rects[3]; - - Outbuf *ob; - - short mode; - - Eina_Inlist *cur_rect; - - Eina_Bool end : 1; - Eina_Bool lost_back : 1; }; /* 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,52 @@ 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; - } + /* try to create new outbuf */ + if (!(ob = evas_outbuf_setup(info, w, h))) + goto on_error; - /* set tilesize */ - evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + if(!evas_render_engine_software_generic_init(&re->generic, ob, + evas_outbuf_buffer_state_get, + evas_outbuf_get_rot, + evas_outbuf_reconfigure, + NULL, + 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; - } - } - - 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); - - /* shutdown drm card & tty */ - evas_drm_shutdown(info); - - free(re); - return NULL; - } + goto on_error; } /* return the allocated render_engine structure */ return re; + + on_error: + evas_render_engine_software_generic_clean(&re->generic); + + /* shutdown drm card & tty */ + evas_drm_shutdown(info); + + free(re); + return NULL; } /* engine api functions */ @@ -101,7 +86,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 +96,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 +110,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 +132,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, epd->output.w, epd->output.h); } /* update the info structure pointer */ @@ -181,299 +159,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 +208,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..43d6febc88 100644 --- a/src/modules/evas/engines/drm/evas_engine.h +++ b/src/modules/evas/engines/drm/evas_engine.h @@ -17,6 +17,8 @@ #include #include +#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,41 +86,47 @@ 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; - - drmModeModeInfo mode; - drmEventContext ctx; - Eina_Bool pending_flip : 1; - - Eina_List *pending_writes; - - Eina_List *planes; + Eina_List *pending_writes; + Eina_List *planes; # ifdef HAVE_DRM_HW_ACCEL - void *surface; + void *surface; # endif - } priv; + + int fd; + unsigned int conn, crtc, fb; + + int curr, num; + + 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); -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_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); +void *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); -void evas_outbuf_flush(Outbuf *ob); +void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); Eina_Bool evas_drm_init(Evas_Engine_Info_Drm *info); Eina_Bool evas_drm_shutdown(Evas_Engine_Info_Drm *info); diff --git a/src/modules/evas/engines/drm/evas_outbuf.c b/src/modules/evas/engines/drm/evas_outbuf.c index 80f031dbf7..6a2a4be631 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; @@ -221,7 +226,7 @@ evas_outbuf_buffer_state_get(Outbuf *ob) return MODE_FULL; } -RGBA_Image * +void * evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) { RGBA_Image *img = NULL; @@ -399,25 +404,28 @@ 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 -evas_outbuf_flush(Outbuf *ob) +void +evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode) { - Eina_Rectangle *rects; + Eina_Rectangle *r; RGBA_Image *img; unsigned int n = 0, i = 0; + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; + /* get number of pending writes */ n = eina_list_count(ob->priv.pending_writes); if (n == 0) return; /* allocate rectangles */ - if (!(rects = alloca(n * sizeof(Eina_Rectangle)))) return; + if (!(r = alloca(n * sizeof(Eina_Rectangle)))) return; /* loop the pending writes */ EINA_LIST_FREE(ob->priv.pending_writes, img) @@ -432,35 +440,35 @@ evas_outbuf_flush(Outbuf *ob) /* based on rotation, set rectangle position */ if (ob->rotation == 0) { - rects[i].x = x; - rects[i].y = y; + r[i].x = x; + r[i].y = y; } else if (ob->rotation == 90) { - rects[i].x = y; - rects[i].y = (ob->w - x - w); + r[i].x = y; + r[i].y = (ob->w - x - w); } else if (ob->rotation == 180) { - rects[i].x = (ob->w - x - w); - rects[i].y = (ob->h - y - h); + r[i].x = (ob->w - x - w); + r[i].y = (ob->h - y - h); } else if (ob->rotation == 270) { - rects[i].x = (ob->h - y - h); - rects[i].y = x; + r[i].x = (ob->h - y - h); + r[i].y = x; } /* based on rotation, set rectangle size */ if ((ob->rotation == 0) || (ob->rotation == 180)) { - rects[i].w = w; - rects[i].h = h; + r[i].w = w; + r[i].h = h; } else if ((ob->rotation == 90) || (ob->rotation == 270)) { - rects[i].w = h; - rects[i].h = w; + r[i].w = h; + r[i].h = w; } eina_rectangle_free(rect); @@ -476,5 +484,11 @@ evas_outbuf_flush(Outbuf *ob) } /* force a buffer swap */ - _evas_outbuf_buffer_swap(ob, rects, n); + _evas_outbuf_buffer_swap(ob, r, n); +} + +int +evas_outbuf_get_rot(Outbuf *ob) +{ + return ob->info->info.rotation; } diff --git a/src/modules/evas/engines/fb/evas_engine.c b/src/modules/evas/engines/fb/evas_engine.c index 215bee4582..3a02a69345 100644 --- a/src/modules/evas/engines/fb/evas_engine.c +++ b/src/modules/evas/engines/fb/evas_engine.c @@ -57,6 +57,7 @@ _output_setup(int w, int h, int rot, int vt, int dev, int refresh) if (!evas_render_engine_software_generic_init(&re->generic, ob, NULL, evas_fb_outbuf_fb_get_rot, evas_fb_outbuf_fb_reconfigure, + NULL, evas_fb_outbuf_fb_new_region_for_update, evas_fb_outbuf_fb_push_updated_region, evas_fb_outbuf_fb_free_region_for_update, diff --git a/src/modules/evas/engines/fb/evas_engine.h b/src/modules/evas/engines/fb/evas_engine.h index d4fcb3ef27..424d47cbbe 100644 --- a/src/modules/evas/engines/fb/evas_engine.h +++ b/src/modules/evas/engines/fb/evas_engine.h @@ -57,7 +57,7 @@ Outbuf *evas_fb_outbuf_fb_setup_fb (int w, int h, int rot, Ou void evas_fb_outbuf_fb_blit (Outbuf *buf, int src_x, int src_y, int w, int h, int dst_x, int dst_y); void evas_fb_outbuf_fb_update (Outbuf *buf, int x, int y, int w, int h); -RGBA_Image *evas_fb_outbuf_fb_new_region_for_update (Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); +void *evas_fb_outbuf_fb_new_region_for_update (Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); void evas_fb_outbuf_fb_free_region_for_update (Outbuf *buf, RGBA_Image *update); void evas_fb_outbuf_fb_push_updated_region (Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h); void evas_fb_outbuf_fb_reconfigure (Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth); diff --git a/src/modules/evas/engines/fb/evas_outbuf.c b/src/modules/evas/engines/fb/evas_outbuf.c index 5196507084..0c22cf5712 100644 --- a/src/modules/evas/engines/fb/evas_outbuf.c +++ b/src/modules/evas/engines/fb/evas_outbuf.c @@ -240,7 +240,7 @@ evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h) } } -RGBA_Image * +void * evas_fb_outbuf_fb_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) { if (buf->priv.back_buf) diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index 4e8d595fb0..5838e1e2c1 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -23,43 +23,14 @@ #define EVAS_GL_UPDATE_TILE_SIZE 16 -enum { - MERGE_BOUNDING, - MERGE_FULL -}; - -static int partial_render_debug = -1; -static int partial_rect_union_mode = -1; -static int swap_buffer_debug_mode = -1; -static int swap_buffer_debug = 0; - -enum { - MODE_FULL, - MODE_COPY, - MODE_DOUBLE, - MODE_TRIPLE, - MODE_QUADRUPLE -}; +static int safe_native = -1; typedef struct _Render_Engine Render_Engine; struct _Render_Engine { - Tilebuf_Rect *rects; - Tilebuf_Rect *rects_prev[4]; - Eina_Inlist *cur_rect; - - Evas_GL_X11_Window *win; - Evas_Engine_Info_GL_X11 *info; - Evas *evas; - Tilebuf *tb; - int end; - int mode; - int w, h; - int vsync; - int lost_back; - int prev_age; - int frame_cnt; + Render_Engine_Software_Generic generic; + Eina_Bool evgl_initted : 1; struct { @@ -72,9 +43,14 @@ struct _Render_Engine E3D_Renderer *renderer_3d; }; +const char *debug_dir; +int swap_buffer_debug_mode = -1; +int swap_buffer_debug = 0; +int partial_render_debug = -1; +int extn_have_buffer_age = 1; + static int initted = 0; static int gl_wins = 0; -static int extn_have_buffer_age = 1; #ifdef GL_GLES static int extn_have_y_inverted = 1; #endif @@ -87,8 +63,6 @@ typedef int (*glsym_func_int) (); typedef unsigned int (*glsym_func_uint) (); typedef const char *(*glsym_func_const_char_ptr) (); -static Eina_Bool eng_preload_make_current(void *data, void *doit); - #ifdef GL_GLES #ifndef EGL_NATIVE_PIXMAP_KHR @@ -195,11 +169,11 @@ evgl_eng_display_get(void *data) } #ifdef GL_GLES - if (re->win) - return (void*)re->win->egl_disp; + if (re->generic.ob) + return (void*)re->generic.ob->egl_disp; #else - if (re->info) - return (void*)re->info->info.display; + if (re->generic.ob->info) + return (void*)re->generic.ob->info->info.display; #endif else return NULL; @@ -218,11 +192,11 @@ evgl_eng_evas_surface_get(void *data) } #ifdef GL_GLES - if (re->win) - return (void*)re->win->egl_surface[0]; + if (re->generic.ob) + return (void*)re->generic.ob->egl_surface[0]; #else - if (re->win) - return (void*)re->win->win; + if (re->generic.ob) + return (void*)re->generic.ob->win; #endif else return NULL; @@ -245,7 +219,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush) #ifdef GL_GLES EGLContext ctx = (EGLContext)context; EGLSurface sfc = (EGLSurface)surface; - EGLDisplay dpy = re->win->egl_disp; //eglGetCurrentDisplay(); + EGLDisplay dpy = re->generic.ob->egl_disp; //eglGetCurrentDisplay(); if ((!context) && (!surface)) { @@ -284,7 +258,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush) if ((!context) && (!surface)) { - ret = glXMakeCurrent(re->info->info.display, None, NULL); + ret = glXMakeCurrent(re->generic.ob->info->info.display, None, NULL); if (!ret) { ERR("glXMakeCurrent() failed!"); @@ -301,7 +275,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush) if (flush) eng_window_use(NULL); // Do a make current - ret = glXMakeCurrent(re->info->info.display, sfc, ctx); + ret = glXMakeCurrent(re->generic.ob->info->info.display, sfc, ctx); if (!ret) { @@ -340,8 +314,8 @@ evgl_eng_native_window_create(void *data) attr.do_not_propagate_mask = NoEventMask; attr.event_mask = 0; - win = XCreateWindow(re->info->info.display, - DefaultRootWindow(re->info->info.display), + win = XCreateWindow(re->generic.ob->info->info.display, + DefaultRootWindow(re->generic.ob->info->info.display), 0, 0, 2, 2, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackingStore | CWOverrideRedirect | @@ -376,7 +350,7 @@ evgl_eng_native_window_destroy(void *data, void *native_window) return 0; } - XDestroyWindow(re->info->info.display, (Window)native_window); + XDestroyWindow(re->generic.ob->info->info.display, (Window)native_window); native_window = NULL; @@ -402,8 +376,8 @@ evgl_eng_window_surface_create(void *data, void *native_window) EGLSurface surface = EGL_NO_SURFACE; // Create resource surface for EGL - surface = eglCreateWindowSurface(re->win->egl_disp, - re->win->egl_config, + surface = eglCreateWindowSurface(re->generic.ob->egl_disp, + re->generic.ob->egl_config, (EGLNativeWindowType)native_window, NULL); if (!surface) @@ -418,7 +392,7 @@ evgl_eng_window_surface_create(void *data, void *native_window) // We don't need to create new one for GLX Window surface; - surface = re->win->win; + surface = re->generic.ob->win; return (void *)surface; */ @@ -446,7 +420,7 @@ evgl_eng_window_surface_destroy(void *data, void *surface) return 0; } - eglDestroySurface(re->win->egl_disp, (EGLSurface)surface); + eglDestroySurface(re->generic.ob->egl_disp, (EGLSurface)surface); #endif return 1; @@ -476,16 +450,16 @@ evgl_eng_context_create(void *data, void *share_ctx) // Share context already assumes that it's sharing with evas' context if (share_ctx) { - context = eglCreateContext(re->win->egl_disp, - re->win->egl_config, + context = eglCreateContext(re->generic.ob->egl_disp, + re->generic.ob->egl_config, (EGLContext)share_ctx, context_attrs); } else { - context = eglCreateContext(re->win->egl_disp, - re->win->egl_config, - re->win->egl_context[0], // Evas' GL Context + context = eglCreateContext(re->generic.ob->egl_disp, + re->generic.ob->egl_config, + re->generic.ob->egl_context[0], // Evas' GL Context context_attrs); } @@ -502,16 +476,16 @@ evgl_eng_context_create(void *data, void *share_ctx) // Share context already assumes that it's sharing with evas' context if (share_ctx) { - context = glXCreateContext(re->info->info.display, - re->win->visualinfo, + context = glXCreateContext(re->generic.ob->info->info.display, + re->generic.ob->visualinfo, (GLXContext)share_ctx, 1); } else { - context = glXCreateContext(re->info->info.display, - re->win->visualinfo, - re->win->context, // Evas' GL Context + context = glXCreateContext(re->generic.ob->info->info.display, + re->generic.ob->visualinfo, + re->generic.ob->context, // Evas' GL Context 1); } @@ -539,9 +513,9 @@ evgl_eng_context_destroy(void *data, void *context) } #ifdef GL_GLES - eglDestroyContext(re->win->egl_disp, (EGLContext)context); + eglDestroyContext(re->generic.ob->egl_disp, (EGLContext)context); #else - glXDestroyContext(re->info->info.display, (GLXContext)context); + glXDestroyContext(re->generic.ob->info->info.display, (GLXContext)context); #endif return 1; @@ -560,10 +534,10 @@ evgl_eng_string_get(void *data) } #ifdef GL_GLES - return eglQueryString(re->win->egl_disp, EGL_EXTENSIONS); + return eglQueryString(re->generic.ob->egl_disp, EGL_EXTENSIONS); #else - return glXQueryExtensionsString(re->info->info.display, - re->info->info.screen); + return glXQueryExtensionsString(re->generic.ob->info->info.display, + re->generic.ob->info->info.screen); #endif } @@ -591,8 +565,8 @@ evgl_eng_rotation_angle_get(void *data) return 0; } - if ((re->win) && (re->win->gl_context)) - return re->win->gl_context->rot; + if ((re->generic.ob) && (re->generic.ob->gl_context)) + return re->generic.ob->gl_context->rot; else { ERR("Unable to retrieve rotation angle."); @@ -712,7 +686,7 @@ gl_extn_veto(Render_Engine *re) { const char *str = NULL; #ifdef GL_GLES - str = eglQueryString(re->win->egl_disp, EGL_EXTENSIONS); + str = eglQueryString(re->generic.ob->egl_disp, EGL_EXTENSIONS); if (str) { if (getenv("EVAS_GL_INFO")) @@ -756,8 +730,8 @@ gl_extn_veto(Render_Engine *re) extn_have_buffer_age = 0; } #else - str = glXQueryExtensionsString(re->info->info.display, - re->info->info.screen); + str = glXQueryExtensionsString(re->generic.ob->info->info.display, + re->generic.ob->info->info.screen); if (str) { if (getenv("EVAS_GL_INFO")) @@ -833,25 +807,12 @@ eng_info_free(Evas *eo_e EINA_UNUSED, void *info) free(in); } -static int -_re_wincheck(Render_Engine *re) -{ - if (re->win->surf) return 1; - eng_window_resurf(re->win); - re->lost_back = 1; - if (!re->win->surf) - { - ERR("GL engine can't re-create window surface!"); - } - return 0; -} - static void _re_winfree(Render_Engine *re) { - if (!re->win->surf) return; - evas_gl_preload_render_relax(eng_preload_make_current, re); - eng_window_unsurf(re->win); + if (!re->generic.ob->surf) return; + evas_gl_preload_render_relax(eng_preload_make_current, re->generic.ob); + eng_window_unsurf(re->generic.ob); } static int @@ -869,11 +830,113 @@ eng_setup(Evas *eo_e, void *in) Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS); Render_Engine *re; Evas_Engine_Info_GL_X11 *info; + Render_Engine_Swap_Mode swap_mode = MODE_FULL; const char *s; info = (Evas_Engine_Info_GL_X11 *)in; + + if ((s = getenv("EVAS_GL_SWAP_MODE"))) + { + if ((!strcasecmp(s, "full")) || + (!strcasecmp(s, "f"))) + swap_mode = MODE_FULL; + else if ((!strcasecmp(s, "copy")) || + (!strcasecmp(s, "c"))) + swap_mode = MODE_COPY; + else if ((!strcasecmp(s, "double")) || + (!strcasecmp(s, "d")) || + (!strcasecmp(s, "2"))) + swap_mode = MODE_DOUBLE; + else if ((!strcasecmp(s, "triple")) || + (!strcasecmp(s, "t")) || + (!strcasecmp(s, "3"))) + swap_mode = MODE_TRIPLE; + else if ((!strcasecmp(s, "quadruple")) || + (!strcasecmp(s, "q")) || + (!strcasecmp(s, "4"))) + swap_mode = MODE_QUADRUPLE; + } + else + { +// in most gl implementations - egl and glx here that we care about the TEND +// to either swap or copy backbuffer and front buffer, but strictly that is +// not true. technically backbuffer content is totally undefined after a swap +// and thus you MUST re-render all of it, thus MODE_FULL + swap_mode = MODE_FULL; +// BUT... reality is that lmost every implementation copies or swaps so +// triple buffer mode can be used as it is a superset of double buffer and +// copy (though using those explicitly is more efficient). so let's play with +// triple buffer mdoe as a default and see. +// re->mode = MODE_TRIPLE; +// XXX: note - the above seems to break on some older intel chipsets and +// drivers. it seems we CANT depend on backbuffer staying around. bugger! + switch (info->swap_mode) + { + case EVAS_ENGINE_GL_X11_SWAP_MODE_FULL: + swap_mode = MODE_FULL; + break; + case EVAS_ENGINE_GL_X11_SWAP_MODE_COPY: + swap_mode = MODE_COPY; + break; + case EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE: + swap_mode = MODE_DOUBLE; + break; + case EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE: + swap_mode = MODE_TRIPLE; + break; + case EVAS_ENGINE_GL_X11_SWAP_MODE_QUADRUPLE: + swap_mode = MODE_QUADRUPLE; + break; + default: + swap_mode = MODE_AUTO; + break; + } + } + + if (safe_native == -1) + { + s = getenv("EVAS_GL_SAFE_NATIVE"); + safe_native = 0; + if (s) safe_native = atoi(s); + else + { + s = (const char *)glGetString(GL_RENDERER); + if (s) + { + if (strstr(s, "PowerVR SGX 540") || + strstr(s, "Mali-400 MP")) + safe_native = 1; + } + } + } + + // Set this env var to dump files every frame + // Or set the global var in gdb to 1|0 to turn it on and off + if (getenv("EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS")) + swap_buffer_debug = 1; + + if (swap_buffer_debug_mode == -1) + { + if ( +#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) + (getuid() == geteuid()) && +#endif + ((debug_dir = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR")))) + { + int stat; + // Create a directory with 0775 permission + stat = mkdir(debug_dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); + if ((!stat) || errno == EEXIST) swap_buffer_debug_mode = 1; + } + else + swap_buffer_debug_mode = 0; + } + + if (!e->engine.data.output) { + Outbuf *ob; + Render_Engine_Merge_Mode merge_mode = MERGE_BOUNDING; #ifdef GL_GLES #else int eb, evb; @@ -882,29 +945,56 @@ eng_setup(Evas *eo_e, void *in) #endif re = calloc(1, sizeof(Render_Engine)); if (!re) return 0; - re->info = info; - re->evas = (Evas *)e; - re->w = e->output.w; - re->h = e->output.h; - re->win = eng_window_new(re->info->info.display, - re->info->info.drawable, - re->info->info.screen, - re->info->info.visual, - re->info->info.colormap, - re->info->info.depth, - re->w, - re->h, - re->info->indirect, - re->info->info.destination_alpha, - re->info->info.rotation); - if (!re->win) + ob = eng_window_new(info, eo_e, + info->info.display, + info->info.drawable, + info->info.screen, + info->info.visual, + info->info.colormap, + info->info.depth, + e->output.w, e->output.h, + info->indirect, + info->info.destination_alpha, + info->info.rotation, + swap_mode); + if (!ob) { free(re); return 0; } + + if (!evas_render_engine_software_generic_init(&re->generic, ob, + eng_outbuf_swap_mode, + eng_outbuf_get_rot, + eng_outbuf_reconfigure, + eng_outbuf_region_first_rect, + eng_outbuf_new_region_for_update, + eng_outbuf_push_updated_region, + eng_outbuf_push_free_region_for_update, + NULL, + eng_outbuf_flush, + eng_window_free, + e->output.w, e->output.h)) + { + free(re); + return 0; + } + e->engine.data.output = re; gl_wins++; + if ((s = getenv("EVAS_GL_PARTIAL_MERGE"))) + { + if ((!strcmp(s, "bounding")) || + (!strcmp(s, "b"))) + merge_mode = MERGE_BOUNDING; + else if ((!strcmp(s, "full")) || + (!strcmp(s, "f"))) + merge_mode = MERGE_FULL; + } + + evas_render_engine_software_generic_merge_mode_set(&re->generic, merge_mode); + if (!initted) { gl_symbols(); @@ -929,111 +1019,60 @@ eng_setup(Evas *eo_e, void *in) else { re = e->engine.data.output; - if (re->win && _re_wincheck(re)) + if (re->generic.ob && _re_wincheck(re->generic.ob)) { - if ((re->info->info.display != re->win->disp) || - (re->info->info.drawable != re->win->win) || - (re->info->info.screen != re->win->screen) || - (re->info->info.visual != re->win->visual) || - (re->info->info.colormap != re->win->colormap) || - (re->info->info.depth != re->win->depth) || - (re->info->info.destination_alpha != re->win->alpha)) + if ((re->generic.ob->info->info.display != re->generic.ob->disp) || + (re->generic.ob->info->info.drawable != re->generic.ob->win) || + (re->generic.ob->info->info.screen != re->generic.ob->screen) || + (re->generic.ob->info->info.visual != re->generic.ob->visual) || + (re->generic.ob->info->info.colormap != re->generic.ob->colormap) || + (re->generic.ob->info->info.depth != re->generic.ob->depth) || + (re->generic.ob->info->info.destination_alpha != re->generic.ob->alpha)) { - re->win->gl_context->references++; - eng_window_free(re->win); + Outbuf *ob; + + re->generic.ob->gl_context->references++; + eng_window_free(re->generic.ob); + re->generic.ob = NULL; gl_wins--; - re->w = e->output.w; - re->h = e->output.h; - re->win = eng_window_new(re->info->info.display, - re->info->info.drawable, - re->info->info.screen, - re->info->info.visual, - re->info->info.colormap, - re->info->info.depth, - re->w, - re->h, - re->info->indirect, - re->info->info.destination_alpha, - re->info->info.rotation); - eng_window_use(re->win); - if (re->win) + ob = eng_window_new(info, eo_e, + re->generic.ob->info->info.display, + re->generic.ob->info->info.drawable, + re->generic.ob->info->info.screen, + re->generic.ob->info->info.visual, + re->generic.ob->info->info.colormap, + re->generic.ob->info->info.depth, + e->output.w, e->output.h, + re->generic.ob->info->indirect, + re->generic.ob->info->info.destination_alpha, + re->generic.ob->info->info.rotation, + swap_mode); + eng_window_use(ob); + if (ob) { + evas_render_engine_software_generic_update(&re->generic, ob, + e->output.w, e->output.h); + gl_wins++; - re->win->gl_context->references--; + re->generic.ob->gl_context->references--; } } - else if ((re->win->w != e->output.w) || - (re->win->h != e->output.h) || - (re->info->info.rotation != re->win->rot)) + else if ((re->generic.ob->w != e->output.w) || + (re->generic.ob->h != e->output.h) || + (re->generic.ob->info->info.rotation != re->generic.ob->rot)) { - re->w = e->output.w; - re->h = e->output.h; - re->win->w = e->output.w; - re->win->h = e->output.h; - re->win->rot = re->info->info.rotation; - eng_window_use(re->win); - evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot); + eng_outbuf_reconfigure(re->generic.ob, e->output.w, e->output.h, re->generic.ob->info->info.rotation, 0); + if (re->generic.tb) + evas_common_tilebuf_free(re->generic.tb); + re->generic.tb = evas_common_tilebuf_new(e->output.w, e->output.h); + if (re->generic.tb) + evas_common_tilebuf_set_tile_size(re->generic.tb, + TILESIZE, TILESIZE); } } } - if ((s = getenv("EVAS_GL_SWAP_MODE"))) - { - if ((!strcasecmp(s, "full")) || - (!strcasecmp(s, "f"))) - re->mode = MODE_FULL; - else if ((!strcasecmp(s, "copy")) || - (!strcasecmp(s, "c"))) - re->mode = MODE_COPY; - else if ((!strcasecmp(s, "double")) || - (!strcasecmp(s, "d")) || - (!strcasecmp(s, "2"))) - re->mode = MODE_DOUBLE; - else if ((!strcasecmp(s, "triple")) || - (!strcasecmp(s, "t")) || - (!strcasecmp(s, "3"))) - re->mode = MODE_TRIPLE; - else if ((!strcasecmp(s, "quadruple")) || - (!strcasecmp(s, "q")) || - (!strcasecmp(s, "4"))) - re->mode = MODE_QUADRUPLE; - } - else - { -// in most gl implementations - egl and glx here that we care about the TEND -// to either swap or copy backbuffer and front buffer, but strictly that is -// not true. technically backbuffer content is totally undefined after a swap -// and thus you MUST re-render all of it, thus MODE_FULL - re->mode = MODE_FULL; -// BUT... reality is that lmost every implementation copies or swaps so -// triple buffer mode can be used as it is a superset of double buffer and -// copy (though using those explicitly is more efficient). so let's play with -// triple buffer mdoe as a default and see. -// re->mode = MODE_TRIPLE; -// XXX: note - the above seems to break on some older intel chipsets and -// drivers. it seems we CANT depend on backbuffer staying around. bugger! - switch (info->swap_mode) - { - case EVAS_ENGINE_GL_X11_SWAP_MODE_FULL: - re->mode = MODE_FULL; - break; - case EVAS_ENGINE_GL_X11_SWAP_MODE_COPY: - re->mode = MODE_COPY; - break; - case EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE: - re->mode = MODE_DOUBLE; - break; - case EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE: - re->mode = MODE_TRIPLE; - break; - case EVAS_ENGINE_GL_X11_SWAP_MODE_QUADRUPLE: - re->mode = MODE_QUADRUPLE; - break; - default: - break; - } - } - if (!re->win) + if (!re->generic.ob) { free(re); return 0; @@ -1041,35 +1080,21 @@ eng_setup(Evas *eo_e, void *in) if (!e->engine.data.output) { - if (re->win) + if (re->generic.ob) { - eng_window_free(re->win); + eng_window_free(re->generic.ob); gl_wins--; } free(re); return 0; } - if (re->tb) evas_common_tilebuf_free(re->tb); - re->tb = evas_common_tilebuf_new(re->win->w, re->win->h); - if (!re->tb) - { - if (re->win) - { - eng_window_free(re->win); - gl_wins--; - } - free(re); - return 0; - } - evas_common_tilebuf_set_tile_size(re->tb, EVAS_GL_UPDATE_TILE_SIZE, EVAS_GL_UPDATE_TILE_SIZE); - evas_common_tilebuf_tile_strict_set(re->tb, EINA_TRUE); + + evas_render_engine_software_generic_tile_strict_set(&re->generic, EINA_TRUE); if (!e->engine.data.context) e->engine.data.context = e->engine.func->context_new(e->engine.data.output); - eng_window_use(re->win); - - re->vsync = 0; + eng_window_use(re->generic.ob); return 1; } @@ -1083,43 +1108,35 @@ eng_output_free(void *data) if (re) { - evas_gl_preload_render_relax(eng_preload_make_current, re); +#ifndef GL_GLES + Display *disp = re->generic.ob->disp; + Window win = re->generic.ob->win; +#endif + + evas_gl_preload_render_relax(eng_preload_make_current, re->generic.ob); #if 0 #ifdef GL_GLES // Destroy the resource surface // Only required for EGL case if (re->surface) - eglDestroySurface(re->win->egl_disp, re->surface); + eglDestroySurface(re->generic.ob->egl_disp, re->surface); #endif // Destroy the resource context _destroy_internal_context(re, context); #endif - if (re->win) - { - if (gl_wins == 1) evgl_engine_shutdown(re); -#ifdef GL_GLES - eng_window_free(re->win); -#else - Display *disp = re->win->disp; - Window win = re->win->win; - eng_window_free(re->win); - if (glsym_glXReleaseBuffersMESA) - glsym_glXReleaseBuffersMESA(disp, win); + if (gl_wins == 1) evgl_engine_shutdown(re); + + evas_render_engine_software_generic_clean(&re->generic); + +#ifndef GL_GLES + if (glsym_glXReleaseBuffersMESA) + glsym_glXReleaseBuffersMESA(disp, win); #endif - gl_wins--; - } - - evas_common_tilebuf_free(re->tb); - if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); - if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]); - if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]); - if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]); - if (re->rects_prev[3]) evas_common_tilebuf_free_render_rects(re->rects_prev[3]); + gl_wins--; - free(re); } if ((initted == 1) && (gl_wins == 0)) @@ -1131,164 +1148,23 @@ eng_output_free(void *data) } } -static void -eng_output_resize(void *data, int w, int h) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - re->win->w = w; - re->win->h = h; - eng_window_use(re->win); - evas_gl_common_context_resize(re->win->gl_context, w, h, re->win->rot); - 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, EVAS_GL_UPDATE_TILE_SIZE, EVAS_GL_UPDATE_TILE_SIZE); - evas_common_tilebuf_tile_strict_set(re->tb, EINA_TRUE); - } -} - -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; - eng_window_use(re->win); - evas_gl_common_context_resize(re->win->gl_context, re->win->w, re->win->h, re->win->rot); - 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); -// INF("GL: finish update cycle!"); -} - -static Tilebuf_Rect * -_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, Tilebuf_Rect *r4) -{ - Tilebuf_Rect *r, *rects; - Evas_Point p1, p2; - - 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); - } - } - if (r4) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(r4), r) - { - evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h); - } - } - rects = evas_common_tilebuf_get_render_rects(tb); - - if (partial_rect_union_mode == -1) - { - const char *s = getenv("EVAS_GL_PARTIAL_MERGE"); - if (s) - { - if ((!strcmp(s, "bounding")) || - (!strcmp(s, "b"))) - partial_rect_union_mode = MERGE_BOUNDING; - else if ((!strcmp(s, "full")) || - (!strcmp(s, "f"))) - partial_rect_union_mode = MERGE_FULL; - } - else - partial_rect_union_mode = MERGE_BOUNDING; - } - if (partial_rect_union_mode == MERGE_BOUNDING) - { -// 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) - { - p1.x = rects->x; p1.y = rects->y; - p2.x = rects->x + rects->w; p2.y = rects->y + rects->h; - EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) - { - if (r->x < p1.x) p1.x = r->x; - if (r->y < p1.y) p1.y = r->y; - if ((r->x + r->w) > p2.x) p2.x = r->x + r->w; - if ((r->y + r->h) > p2.y) p2.y = r->y + r->h; - } - evas_common_tilebuf_free_render_rects(rects); - rects = calloc(1, sizeof(Tilebuf_Rect)); - if (rects) - { - rects->x = p1.x; - rects->y = p1.y; - rects->w = p2.x - p1.x; - rects->h = p2.y - p1.y; - } - } - } - evas_common_tilebuf_clear(tb); - return rects; -} - /* vsync games - not for now though */ #define VSYNC_TO_SCREEN 1 -static Eina_Bool +Eina_Bool eng_preload_make_current(void *data, void *doit) { - Render_Engine *re = data; + Outbuf *ob = data; if (doit) { #ifdef GL_GLES - if (!eglMakeCurrent(re->win->egl_disp, re->win->egl_surface[0], re->win->egl_surface[0], re->win->egl_context[0])) + if (!eglMakeCurrent(ob->egl_disp, ob->egl_surface[0], ob->egl_surface[0], ob->egl_context[0])) return EINA_FALSE; #else - if (!glXMakeCurrent(re->info->info.display, re->win->win, re->win->context)) + if (!glXMakeCurrent(ob->info->info.display, ob->win, ob->context)) { - ERR("glXMakeCurrent(%p, 0x%x, %p) failed", re->info->info.display, (unsigned int)re->win->win, (void *)re->win->context); + ERR("glXMakeCurrent(%p, 0x%x, %p) failed", ob->info->info.display, (unsigned int)ob->win, (void *)ob->context); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); return EINA_FALSE; } @@ -1297,12 +1173,12 @@ eng_preload_make_current(void *data, void *doit) else { #ifdef GL_GLES - if (!eglMakeCurrent(re->win->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) + if (!eglMakeCurrent(ob->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) return EINA_FALSE; #else - if (!glXMakeCurrent(re->info->info.display, None, NULL)) + if (!glXMakeCurrent(ob->info->info.display, None, NULL)) { - ERR("glXMakeCurrent(%p, None, NULL) failed", re->info->info.display); + ERR("glXMakeCurrent(%p, None, NULL) failed", ob->info->info.display); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); return EINA_FALSE; } @@ -1311,435 +1187,6 @@ eng_preload_make_current(void *data, void *doit) return EINA_TRUE; } -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; - Tilebuf_Rect *rect; - Eina_Bool first_rect = EINA_FALSE; - -#define CLEAR_PREV_RECTS(x) \ - do { \ - if (re->rects_prev[x]) \ - evas_common_tilebuf_free_render_rects(re->rects_prev[x]); \ - re->rects_prev[x] = NULL; \ - } while (0) - - re = (Render_Engine *)data; - /* get the upate rect surface - return engine data as dummy */ - if (re->end) - { - re->end = 0; - return NULL; - } - if (!re->rects) - { - re->rects = evas_common_tilebuf_get_render_rects(re->tb); - if (re->rects) - { - if (re->info->swap_mode == EVAS_ENGINE_GL_X11_SWAP_MODE_AUTO) - { - if (extn_have_buffer_age) - { -#ifdef GL_GLES - EGLint age = 0; - - if (!eglQuerySurface(re->win->egl_disp, - re->win->egl_surface[0], - EGL_BUFFER_AGE_EXT, &age)) - age = 0; -#else - unsigned int age = 0; - - if (glsym_glXQueryDrawable) - { - if (re->win->glxwin) - glsym_glXQueryDrawable(re->win->disp, - re->win->glxwin, - GLX_BACK_BUFFER_AGE_EXT, - &age); - else - glsym_glXQueryDrawable(re->win->disp, - re->win->win, - GLX_BACK_BUFFER_AGE_EXT, - &age); - } -#endif - if (age == 1) re->mode = MODE_COPY; - else if (age == 2) re->mode = MODE_DOUBLE; - else if (age == 3) re->mode = MODE_TRIPLE; - else if (age == 4) re->mode = MODE_QUADRUPLE; - else re->mode = MODE_FULL; - if ((int)age != re->prev_age) re->mode = MODE_FULL; - re->prev_age = age; - } - } - if ((re->lost_back) || (re->mode == MODE_FULL)) - { - /* if we lost our backbuffer since the last frame redraw all */ - re->lost_back = 0; - evas_common_tilebuf_add_redraw(re->tb, 0, 0, re->win->w, re->win->h); - evas_common_tilebuf_free_render_rects(re->rects); - re->rects = evas_common_tilebuf_get_render_rects(re->tb); - } - /* ensure we get rid of previous rect lists we dont need if mode - * changed/is appropriate */ - evas_common_tilebuf_clear(re->tb); - CLEAR_PREV_RECTS(3); - re->rects_prev[3] = re->rects_prev[2]; - re->rects_prev[2] = re->rects_prev[1]; - re->rects_prev[1] = re->rects_prev[0]; - re->rects_prev[0] = re->rects; - re->rects = NULL; - switch (re->mode) - { - case MODE_FULL: - case MODE_COPY: // no prev rects needed - re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL, NULL); - break; - case MODE_DOUBLE: // double mode - only 1 level of prev rect - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL); - break; - case MODE_TRIPLE: // triple mode - 2 levels of prev rect - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], NULL); - break; - case MODE_QUADRUPLE: // keep all - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], re->rects_prev[3]); - break; - default: - break; - } - first_rect = EINA_TRUE; - } - 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) - { - re->win->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; - - switch (re->mode) - { - case MODE_COPY: - case MODE_DOUBLE: - case MODE_TRIPLE: - case MODE_QUADRUPLE: - 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; - re->win->gl_context->master_clip.enabled = EINA_TRUE; - re->win->gl_context->master_clip.x = rect->x; - re->win->gl_context->master_clip.y = rect->y; - re->win->gl_context->master_clip.w = rect->w; - re->win->gl_context->master_clip.h = rect->h; - break; - case MODE_FULL: - re->cur_rect = NULL; - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = re->win->w; - if (h) *h = re->win->h; - if (cx) *cx = 0; - if (cy) *cy = 0; - if (cw) *cw = re->win->w; - if (ch) *ch = re->win->h; - re->win->gl_context->master_clip.enabled = EINA_FALSE; - break; - default: - break; - } - if (first_rect) - { - evas_gl_preload_render_lock(eng_preload_make_current, re); -#ifdef GL_GLES - // dont need to for egl - eng_window_use() can check for other ctxt's -#else - eng_window_use(NULL); -#endif - eng_window_use(re->win); - if (!_re_wincheck(re)) return NULL; - - evas_gl_common_context_flush(re->win->gl_context); - evas_gl_common_context_newframe(re->win->gl_context); - if (partial_render_debug == -1) - { - if (getenv("EVAS_GL_PARTIAL_DEBUG")) partial_render_debug = 1; - else partial_render_debug = 0; - } - if (partial_render_debug == 1) - { - glClearColor(0.2, 0.5, 1.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - } - } - if (!re->cur_rect) - { - re->end = 1; - } - return re->win->gl_context->def_surface; - } - return NULL; -} - -static int safe_native = -1; - -static void -eng_output_redraws_next_update_push(void *data, void *surface EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - re = (Render_Engine *)data; - /* put back update surface.. in this case just unflag redraw */ - if (!_re_wincheck(re)) return; - re->win->draw.drew = 1; - evas_gl_common_context_flush(re->win->gl_context); - if (safe_native == -1) - { - const char *s = getenv("EVAS_GL_SAFE_NATIVE"); - safe_native = 0; - if (s) safe_native = atoi(s); - else - { - s = (const char *)glGetString(GL_RENDERER); - if (s) - { - if (strstr(s, "PowerVR SGX 540") || - strstr(s, "Mali-400 MP")) - safe_native = 1; - } - } - } -#ifdef GL_GLES - // this is needed to make sure all previous rendering is flushed to - // buffers/surfaces - // previous rendering should be done and swapped -//xx if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE); -// if (eglGetError() != EGL_SUCCESS) -// { -// printf("Error: eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n"); -// } -#else - // previous rendering should be done and swapped -//xx if (!safe_native) glXWaitX(); -#endif -} - -static void -eng_output_flush(void *data, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - static char *dname = NULL; - - re = (Render_Engine *)data; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end; - - if (!_re_wincheck(re)) goto end; - if (!re->win->draw.drew) goto end; - - re->win->draw.drew = 0; - eng_window_use(re->win); - evas_gl_common_context_done(re->win->gl_context); - - // Save contents of the framebuffer to a file - if (swap_buffer_debug_mode == -1) - { - if ( -#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) - (getuid() == geteuid()) && -#endif - ((dname = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR")))) - { - int stat; - // Create a directory with 0775 permission - stat = mkdir(dname, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); - if ((!stat) || errno == EEXIST) swap_buffer_debug_mode = 1; - } - else - swap_buffer_debug_mode = 0; - } - - if (swap_buffer_debug_mode == 1) - { - // Set this env var to dump files every frame - // Or set the global var in gdb to 1|0 to turn it on and off - if (getenv("EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS")) - swap_buffer_debug = 1; - - if (swap_buffer_debug) - { - char fname[100]; - int ret = 0; - snprintf(fname, sizeof(fname), "%p", (void*)re->win); - - ret = evas_gl_common_buffer_dump(re->win->gl_context, - (const char*)dname, - (const char*)fname, - re->frame_cnt, - NULL); - if (!ret) swap_buffer_debug_mode = 0; - } - } - -#ifdef GL_GLES - if (!re->vsync) - { - if (re->info->vsync) eglSwapInterval(re->win->egl_disp, 1); - else eglSwapInterval(re->win->egl_disp, 0); - re->vsync = 1; - } - if (re->info->callback.pre_swap) - { - re->info->callback.pre_swap(re->info->callback.data, re->evas); - } - if ((glsym_eglSwapBuffersWithDamage) && (re->mode != MODE_FULL)) - { - EGLint num = 0, *rects = NULL, i = 0; - Tilebuf_Rect *r; - - // if partial swaps can be done use re->rects - num = eina_inlist_count(EINA_INLIST_GET(re->rects)); - if (num > 0) - { - rects = alloca(sizeof(EGLint) * 4 * num); - EINA_INLIST_FOREACH(EINA_INLIST_GET(re->rects), r) - { - int gw, gh; - - gw = re->win->gl_context->w; - gh = re->win->gl_context->h; - switch (re->win->rot) - { - case 0: - rects[i + 0] = r->x; - rects[i + 1] = gh - (r->y + r->h); - rects[i + 2] = r->w; - rects[i + 3] = r->h; - break; - case 90: - rects[i + 0] = r->y; - rects[i + 1] = r->x; - rects[i + 2] = r->h; - rects[i + 3] = r->w; - break; - case 180: - rects[i + 0] = gw - (r->x + r->w); - rects[i + 1] = r->y; - rects[i + 2] = r->w; - rects[i + 3] = r->h; - break; - case 270: - rects[i + 0] = gh - (r->y + r->h); - rects[i + 1] = gw - (r->x + r->w); - rects[i + 2] = r->h; - rects[i + 3] = r->w; - break; - default: - rects[i + 0] = r->x; - rects[i + 1] = gh - (r->y + r->h); - rects[i + 2] = r->w; - rects[i + 3] = r->h; - break; - } - i += 4; - } - glsym_eglSwapBuffersWithDamage(re->win->egl_disp, - re->win->egl_surface[0], - rects, num); - } - } - else - eglSwapBuffers(re->win->egl_disp, re->win->egl_surface[0]); - -//xx if (!safe_native) eglWaitGL(); - if (re->info->callback.post_swap) - { - re->info->callback.post_swap(re->info->callback.data, re->evas); - } -// if (eglGetError() != EGL_SUCCESS) -// { -// printf("Error: eglSwapBuffers() fail.\n"); -// } -#else -#ifdef VSYNC_TO_SCREEN - if (re->info->vsync) - { - if (glsym_glXSwapIntervalEXT) - { - if (!re->vsync) - { - if (re->info->vsync) glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 1); - else glsym_glXSwapIntervalEXT(re->win->disp, re->win->win, 0); - re->vsync = 1; - } - } - else if (glsym_glXSwapIntervalSGI) - { - if (!re->vsync) - { - if (re->info->vsync) glsym_glXSwapIntervalSGI(1); - else glsym_glXSwapIntervalSGI(0); - re->vsync = 1; - } - } - else - { - if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync)) - { - unsigned int rc; - - glsym_glXGetVideoSync(&rc); - glsym_glXWaitVideoSync(1, 0, &rc); - } - } - } -#endif - if (re->info->callback.pre_swap) - { - re->info->callback.pre_swap(re->info->callback.data, re->evas); - } - // XXX: if partial swaps can be done use re->rects -// measure(0, "swap"); - glXSwapBuffers(re->win->disp, re->win->win); -// measure(1, "swap"); - if (re->info->callback.post_swap) - { - re->info->callback.post_swap(re->info->callback.data, re->evas); - } -#endif - // clear out rects after swap as we may use them during swap - if (re->rects) - { - evas_common_tilebuf_free_render_rects(re->rects); - re->rects = NULL; - } - - re->frame_cnt++; - - end: - evas_gl_preload_render_unlock(eng_preload_make_current, re); -} - -static void -eng_output_idle_flush(void *data) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - (void) re; -} - static void eng_output_dump(void *data) { @@ -1748,40 +1195,20 @@ eng_output_dump(void *data) re = (Render_Engine *)data; evas_common_image_image_all_unload(); evas_common_font_font_all_unload(); - evas_gl_common_image_all_unload(re->win->gl_context); + evas_gl_common_image_all_unload(re->generic.ob->gl_context); _re_winfree(re); } -static void -eng_context_cutout_add(void *data EINA_UNUSED, void *context, int x, int y, int w, int h) -{ -// Render_Engine *re; -// -// re = (Render_Engine *)data; -// re->win->gl_context->dc = context; - evas_common_draw_context_add_cutout(context, x, y, w, h); -} - -static void -eng_context_cutout_clear(void *data EINA_UNUSED, void *context) -{ -// Render_Engine *re; -// -// re = (Render_Engine *)data; -// re->win->gl_context->dc = context; - evas_common_draw_context_clear_cutouts(context); -} - static void eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h); + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; + evas_gl_common_rect_draw(re->generic.ob->gl_context, x, y, w, h); } static void @@ -1790,10 +1217,10 @@ eng_line_draw(void *data, void *context, void *surface, int p1x, int p1y, int p2 Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_line_draw(re->win->gl_context, p1x, p1y, p2x, p2y); + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; + evas_gl_common_line_draw(re->generic.ob->gl_context, p1x, p1y, p2x, p2y); } static void * @@ -1822,10 +1249,10 @@ eng_polygon_draw(void *data, void *context, void *surface EINA_UNUSED, void *pol Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y); + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; + evas_gl_common_poly_draw(re->generic.ob->gl_context, polygon, x, y); } static int @@ -1867,7 +1294,7 @@ eng_image_alpha_set(void *data, void *image, int has_alpha) im->alpha = has_alpha; return image; } - eng_window_use(re->win); + eng_window_use(re->generic.ob); if ((im->tex) && (im->tex->pt->dyn.img)) { im->alpha = has_alpha; @@ -1962,7 +1389,7 @@ eng_image_colorspace_set(void *data, void *image, Evas_Colorspace cspace) if (im->native.data) return; /* FIXME: can move to gl_common */ if (im->cs.space == cspace) return; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_alloc_ensure(im); evas_cache_image_colorspace(&im->im->cache_entry, cspace); switch (cspace) @@ -2054,7 +1481,7 @@ _native_bind_cb(void *data, void *image) if (glsym_glXBindTexImage) { - glsym_glXBindTexImage(re->win->disp, n->glx_pixmap, + glsym_glXBindTexImage(re->generic.ob->disp, n->glx_pixmap, GLX_FRONT_LEFT_EXT, NULL); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); } @@ -2088,7 +1515,7 @@ _native_unbind_cb(void *data, void *image) if (glsym_glXReleaseTexImage) { - glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap, + glsym_glXReleaseTexImage(re->generic.ob->disp, n->glx_pixmap, GLX_FRONT_LEFT_EXT); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); } @@ -2117,13 +1544,13 @@ _native_free_cb(void *data, void *image) if (n->ns.type == EVAS_NATIVE_SURFACE_X11) { pmid = n->pixmap; - eina_hash_del(re->win->gl_context->shared->native_pm_hash, &pmid, im); + eina_hash_del(re->generic.ob->gl_context->shared->native_pm_hash, &pmid, im); #ifdef GL_GLES if (n->egl_surface) { if (glsym_eglDestroyImage) { - glsym_eglDestroyImage(re->win->egl_disp, + glsym_eglDestroyImage(re->generic.ob->egl_disp, n->egl_surface); if (eglGetError() != EGL_SUCCESS) ERR("eglDestroyImage() failed."); @@ -2139,7 +1566,7 @@ _native_free_cb(void *data, void *image) { if (glsym_glXReleaseTexImage) { - glsym_glXReleaseTexImage(re->win->disp, n->glx_pixmap, + glsym_glXReleaseTexImage(re->generic.ob->disp, n->glx_pixmap, GLX_FRONT_LEFT_EXT); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); } @@ -2148,7 +1575,7 @@ _native_free_cb(void *data, void *image) } if (glsym_glXDestroyPixmap) { - glsym_glXDestroyPixmap(re->win->disp, n->glx_pixmap); + glsym_glXDestroyPixmap(re->generic.ob->disp, n->glx_pixmap); GLERR(__FUNCTION__, __FILE__, __LINE__, ""); } else @@ -2161,7 +1588,7 @@ _native_free_cb(void *data, void *image) else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) { texid = n->ns.data.opengl.texture_id; - eina_hash_del(re->win->gl_context->shared->native_tex_hash, &texid, im); + eina_hash_del(re->generic.ob->gl_context->shared->native_tex_hash, &texid, im); } im->native.data = NULL; im->native.func.data = NULL; @@ -2188,7 +1615,7 @@ eng_image_native_set(void *data, void *image, void *native) { if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL)) { - im = evas_gl_common_image_new_from_data(re->win->gl_context, + im = evas_gl_common_image_new_from_data(re->generic.ob->gl_context, ns->data.opengl.w, ns->data.opengl.h, NULL, 1, @@ -2227,7 +1654,7 @@ eng_image_native_set(void *data, void *image, void *native) } if ((!ns) && (!im->native.data)) return im; - eng_window_use(re->win); + eng_window_use(re->generic.ob); if (im->native.data) { @@ -2241,7 +1668,7 @@ eng_image_native_set(void *data, void *image, void *native) if (ns->type == EVAS_NATIVE_SURFACE_X11) { pmid = pm; - im2 = eina_hash_find(re->win->gl_context->shared->native_pm_hash, &pmid); + im2 = eina_hash_find(re->generic.ob->gl_context->shared->native_pm_hash, &pmid); if (im2 == im) return im; if (im2) { @@ -2257,7 +1684,7 @@ eng_image_native_set(void *data, void *image, void *native) else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL) { texid = tex; - im2 = eina_hash_find(re->win->gl_context->shared->native_tex_hash, &texid); + im2 = eina_hash_find(re->generic.ob->gl_context->shared->native_tex_hash, &texid); if (im2 == im) return im; if (im2) { @@ -2271,7 +1698,7 @@ eng_image_native_set(void *data, void *image, void *native) } } - im2 = evas_gl_common_image_new_from_data(re->win->gl_context, + im2 = evas_gl_common_image_new_from_data(re->generic.ob->gl_context, im->w, im->h, NULL, im->alpha, EVAS_COLORSPACE_ARGB8888); evas_gl_common_image_free(im); @@ -2290,7 +1717,7 @@ eng_image_native_set(void *data, void *image, void *native) int num_config, i = 0; int yinvert = 1; - eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im); + eina_hash_add(re->generic.ob->gl_context->shared->native_pm_hash, &pmid, im); // assume 32bit pixmap! :) config_attrs[i++] = EGL_RED_SIZE; @@ -2311,14 +1738,14 @@ eng_image_native_set(void *data, void *image, void *native) config_attrs[i++] = EGL_PIXMAP_BIT; config_attrs[i++] = EGL_NONE; - if (!eglChooseConfig(re->win->egl_disp, config_attrs, + if (!eglChooseConfig(re->generic.ob->egl_disp, config_attrs, &egl_config, 1, &num_config)) ERR("eglChooseConfig() failed for pixmap 0x%x, num_config = %i", (unsigned int)pm, num_config); else { int val; if (extn_have_y_inverted && - eglGetConfigAttrib(re->win->egl_disp, egl_config, + eglGetConfigAttrib(re->generic.ob->egl_disp, egl_config, EGL_Y_INVERTED_NOK, &val)) yinvert = val; } @@ -2327,7 +1754,7 @@ eng_image_native_set(void *data, void *image, void *native) n->pixmap = pm; n->visual = vis; if (glsym_eglCreateImage) - n->egl_surface = glsym_eglCreateImage(re->win->egl_disp, + n->egl_surface = glsym_eglCreateImage(re->generic.ob->egl_disp, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (void *)pm, @@ -2357,7 +1784,7 @@ eng_image_native_set(void *data, void *image, void *native) Window wdummy; // fixme: round trip :( - XGetGeometry(re->win->disp, pm, &wdummy, &dummy, &dummy, + XGetGeometry(re->generic.ob->disp, pm, &wdummy, &dummy, &dummy, &w, &h, &border, &depth); if (depth <= 32) { @@ -2405,8 +1832,8 @@ eng_image_native_set(void *data, void *image, void *native) config_attrs[i++] = 0; - configs = glXChooseFBConfig(re->win->disp, - re->win->screen, + configs = glXChooseFBConfig(re->generic.ob->disp, + re->generic.ob->screen, config_attrs, &num); if (configs) @@ -2420,42 +1847,42 @@ eng_image_native_set(void *data, void *image, void *native) { XVisualInfo *vi; - vi = glXGetVisualFromFBConfig(re->win->disp, configs[j]); + vi = glXGetVisualFromFBConfig(re->generic.ob->disp, configs[j]); if (!vi) continue; if (vi->depth != (int)depth) continue; XFree(vi); - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BUFFER_SIZE, &val); if (val != (int) depth) continue; } - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_DRAWABLE_TYPE, &val); if (!(val & GLX_PIXMAP_BIT)) continue; tex_format = GLX_TEXTURE_FORMAT_RGB_EXT; - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_ALPHA_SIZE, &val); if ((depth == 32) && (!val)) continue; if (val > 0) { - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BIND_TO_TEXTURE_RGBA_EXT, &val); if (val) tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT; } else { - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BIND_TO_TEXTURE_RGB_EXT, &val); if (val) tex_format = GLX_TEXTURE_FORMAT_RGB_EXT; } - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_Y_INVERTED_EXT, &val); yinvert = val; - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &val); tex_target = val; - glXGetFBConfigAttrib(re->win->disp, configs[j], + glXGetFBConfigAttrib(re->generic.ob->disp, configs[j], GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val); mipmap = val; n->fbc = configs[j]; @@ -2470,7 +1897,7 @@ eng_image_native_set(void *data, void *image, void *native) XFree(configs); } - eina_hash_add(re->win->gl_context->shared->native_pm_hash, &pmid, im); + eina_hash_add(re->generic.ob->gl_context->shared->native_pm_hash, &pmid, im); if ((tex_target & GLX_TEXTURE_2D_BIT_EXT)) target = GLX_TEXTURE_2D_EXT; else if ((tex_target & GLX_TEXTURE_RECTANGLE_BIT_EXT)) @@ -2503,7 +1930,7 @@ eng_image_native_set(void *data, void *image, void *native) n->pixmap = pm; n->visual = vis; if (glsym_glXCreatePixmap) - n->glx_pixmap = glsym_glXCreatePixmap(re->win->disp, + n->glx_pixmap = glsym_glXCreatePixmap(re->generic.ob->disp, n->fbc, n->pixmap, pixmap_att); @@ -2517,7 +1944,7 @@ eng_image_native_set(void *data, void *image, void *native) { ERR("no target :("); if (glsym_glXQueryDrawable) - glsym_glXQueryDrawable(re->win->disp, + glsym_glXQueryDrawable(re->generic.ob->disp, n->pixmap, GLX_TEXTURE_TARGET_EXT, &target); @@ -2544,7 +1971,7 @@ eng_image_native_set(void *data, void *image, void *native) else ERR("GLX Pixmap create fail"); im->native.yinvert = yinvert; - im->native.loose = re->win->detected.loose_binding; + im->native.loose = re->generic.ob->detected.loose_binding; im->native.data = n; im->native.func.data = re; im->native.func.bind = _native_bind_cb; @@ -2567,7 +1994,7 @@ eng_image_native_set(void *data, void *image, void *native) { memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface)); - eina_hash_add(re->win->gl_context->shared->native_tex_hash, &texid, im); + eina_hash_add(re->generic.ob->gl_context->shared->native_tex_hash, &texid, im); n->pixmap = 0; n->visual = 0; @@ -2622,8 +2049,8 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I re = (Render_Engine *)data; *error = EVAS_LOAD_ERROR_NONE; - eng_window_use(re->win); - return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error); + eng_window_use(re->generic.ob); + return evas_gl_common_image_load(re->generic.ob->gl_context, file, key, lo, error); } static void * @@ -2633,8 +2060,8 @@ eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image re = (Render_Engine *)data; *error = EVAS_LOAD_ERROR_NONE; - eng_window_use(re->win); - return evas_gl_common_image_mmap(re->win->gl_context, f, key, lo, error); + eng_window_use(re->generic.ob); + return evas_gl_common_image_mmap(re->generic.ob->gl_context, f, key, lo, error); } static void * @@ -2643,8 +2070,8 @@ eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace); + eng_window_use(re->generic.ob); + return evas_gl_common_image_new_from_data(re->generic.ob->gl_context, w, h, image_data, alpha, cspace); } static void * @@ -2653,8 +2080,8 @@ eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace); + eng_window_use(re->generic.ob); + return evas_gl_common_image_new_from_copied_data(re->generic.ob->gl_context, w, h, image_data, alpha, cspace); } static void @@ -2664,7 +2091,7 @@ eng_image_free(void *data, void *image) re = (Render_Engine *)data; if (!image) return; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_free(image); } @@ -2696,7 +2123,7 @@ eng_image_size_set(void *data, void *image, int w, int h) im->h = h; return image; } - eng_window_use(re->win); + eng_window_use(re->generic.ob); if ((im->tex) && (im->tex->pt->dyn.img)) { evas_gl_common_texture_free(im->tex, EINA_TRUE); @@ -2727,13 +2154,13 @@ eng_image_size_set(void *data, void *image, int w, int h) return image; if (im_old) { - im = evas_gl_common_image_new(re->win->gl_context, w, h, + im = evas_gl_common_image_new(re->generic.ob->gl_context, w, h, eng_image_alpha_get(data, image), eng_image_colorspace_get(data, image)); evas_gl_common_image_free(im_old); } else - im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888); + im = evas_gl_common_image_new(re->generic.ob->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888); return im; } @@ -2746,7 +2173,7 @@ eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h) re = (Render_Engine *)data; if (!image) return NULL; if (im->native.data) return image; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_dirty(image, x, y, w, h); return image; } @@ -2774,7 +2201,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i } #ifdef GL_GLES - eng_window_use(re->win); + eng_window_use(re->generic.ob); if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) && (im->cs.space == EVAS_COLORSPACE_ARGB8888)) { @@ -2785,7 +2212,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i if (err) *err = EVAS_LOAD_ERROR_NONE; return im; } - *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->win->egl_disp, + *image_data = im->tex->pt->dyn.data = glsym_eglMapImageSEC(re->generic.ob->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC, EGL_MAP_GL_TEXTURE_OPTION_WRITE_SEC); @@ -2809,7 +2236,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i return im; } - eng_window_use(re->win); + eng_window_use(re->generic.ob); #endif /* Engine can be fail to create texture after cache drop like eng_image_content_hint_set function, @@ -2891,7 +2318,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) if (!image) return NULL; im = image; if (im->native.data) return image; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_alloc_ensure(im); if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data) @@ -2904,7 +2331,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) im->tex->pt->dyn.checked_out--; #ifdef GL_GLES if (im->tex->pt->dyn.checked_out == 0) - glsym_eglUnmapImageSEC(re->win->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC); + glsym_eglUnmapImageSEC(re->generic.ob->egl_disp, im->tex->pt->dyn.img, EGL_MAP_GL_TEXTURE_DEVICE_CPU_SEC); #endif } @@ -2973,7 +2400,7 @@ eng_image_data_preload_request(void *data, void *image, const Eo *target) #endif evas_cache_image_preload_data(&im->cache_entry, target, NULL, NULL, NULL); if (!gim->tex) - gim->tex = evas_gl_common_texture_new(re->win->gl_context, gim->im); + gim->tex = evas_gl_common_texture_new(re->generic.ob->gl_context, gim->im); evas_gl_preload_target_register(gim->tex, (Eo*) target); } @@ -3014,39 +2441,39 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, { DBG("Rendering Directly to the window: %p", data); - re->win->gl_context->dc = context; + re->generic.ob->gl_context->dc = context; if (re->func.get_pixels) { - if ((re->win->gl_context->master_clip.enabled) && - (re->win->gl_context->master_clip.w > 0) && - (re->win->gl_context->master_clip.h > 0)) + if ((re->generic.ob->gl_context->master_clip.enabled) && + (re->generic.ob->gl_context->master_clip.w > 0) && + (re->generic.ob->gl_context->master_clip.h > 0)) { // Pass the preserve flag info the evas_gl - evgl_direct_partial_info_set(re->win->gl_context->preserve_bit); + evgl_direct_partial_info_set(re->generic.ob->gl_context->preserve_bit); } // Set necessary info for direct rendering - evgl_direct_info_set(re->win->gl_context->w, - re->win->gl_context->h, - re->win->gl_context->rot, + evgl_direct_info_set(re->generic.ob->gl_context->w, + re->generic.ob->gl_context->h, + re->generic.ob->gl_context->rot, dst_x, dst_y, dst_w, dst_h, - re->win->gl_context->dc->clip.x, - re->win->gl_context->dc->clip.y, - re->win->gl_context->dc->clip.w, - re->win->gl_context->dc->clip.h); + re->generic.ob->gl_context->dc->clip.x, + re->generic.ob->gl_context->dc->clip.y, + re->generic.ob->gl_context->dc->clip.w, + re->generic.ob->gl_context->dc->clip.h); // Call pixel get function re->func.get_pixels(re->func.get_pixels_data, re->func.obj); // Call end tile if it's being used - if ((re->win->gl_context->master_clip.enabled) && - (re->win->gl_context->master_clip.w > 0) && - (re->win->gl_context->master_clip.h > 0)) + if ((re->generic.ob->gl_context->master_clip.enabled) && + (re->generic.ob->gl_context->master_clip.w > 0) && + (re->generic.ob->gl_context->master_clip.h > 0)) { evgl_direct_partial_render_end(); evgl_direct_partial_info_clear(); - re->win->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; + re->generic.ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; } // Reset direct rendering info @@ -3055,10 +2482,10 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, } else { - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; - evas_gl_common_image_draw(re->win->gl_context, image, + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; + evas_gl_common_image_draw(re->generic.ob->gl_context, image, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h, smooth); @@ -3089,9 +2516,9 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_M re = (Render_Engine *)data; if (!image) return EINA_FALSE; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; if (m->count != 4) { // FIXME: nash - you didn't fix this @@ -3127,7 +2554,7 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_M } else { - evas_gl_common_image_map_draw(re->win->gl_context, image, m->count, &m->pts[0], + evas_gl_common_image_map_draw(re->generic.ob->gl_context, image, m->count, &m->pts[0], smooth, level); } @@ -3145,8 +2572,8 @@ eng_image_map_surface_new(void *data, int w, int h, int alpha) Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha); + eng_window_use(re->generic.ob); + return evas_gl_common_image_surface_new(re->generic.ob->gl_context, w, h, alpha); } static void @@ -3155,7 +2582,7 @@ eng_image_map_surface_free(void *data, void *surface) Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_gl_common_image_free(surface); } @@ -3165,7 +2592,7 @@ eng_image_content_hint_set(void *data, void *image, int hint) Render_Engine *re; re = (Render_Engine *)data; - if (re) eng_window_use(re->win); + if (re) eng_window_use(re->generic.ob); if (image) evas_gl_common_image_content_hint_set(image, hint); } @@ -3185,12 +2612,12 @@ eng_image_cache_flush(void *data) re = (Render_Engine *)data; - eng_window_use(re->win); + eng_window_use(re->generic.ob); tmp_size = evas_common_image_get_cache(); evas_common_image_set_cache(0); evas_common_rgba_image_scalecache_flush(); - evas_gl_common_image_cache_flush(re->win->gl_context); + evas_gl_common_image_cache_flush(re->generic.ob->gl_context); evas_common_image_set_cache(tmp_size); } @@ -3201,11 +2628,11 @@ eng_image_cache_set(void *data, int bytes) re = (Render_Engine *)data; - eng_window_use(re->win); + eng_window_use(re->generic.ob); evas_common_image_set_cache(bytes); evas_common_rgba_image_scalecache_size_set(bytes); - evas_gl_common_image_cache_flush(re->win->gl_context); + evas_gl_common_image_cache_flush(re->generic.ob->gl_context); } static int @@ -3255,20 +2682,20 @@ eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font EINA Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_target_surface_set(re->win->gl_context, surface); - re->win->gl_context->dc = context; + eng_window_use(re->generic.ob); + evas_gl_common_context_target_surface_set(re->generic.ob->gl_context, surface); + re->generic.ob->gl_context->dc = context; { // FIXME: put im into context so we can free it static RGBA_Image *im = NULL; if (!im) im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); - im->cache_entry.w = re->win->gl_context->shared->w; - im->cache_entry.h = re->win->gl_context->shared->h; + im->cache_entry.w = re->generic.ob->gl_context->shared->w; + im->cache_entry.h = re->generic.ob->gl_context->shared->h; evas_common_draw_context_font_ext_set(context, - re->win->gl_context, + re->generic.ob->gl_context, evas_gl_font_texture_new, evas_gl_font_texture_free, evas_gl_font_texture_draw); @@ -3288,7 +2715,7 @@ static Eina_Bool eng_canvas_alpha_get(void *data, void *info EINA_UNUSED) { Render_Engine *re = (Render_Engine *)data; - return re->win->alpha; + return re->generic.ob->alpha; } //--------------------------------// @@ -3339,13 +2766,13 @@ eng_gl_make_current(void *data, void *surface, void *context) EVGLINIT(data, 0); if ((sfc) && (ctx)) { - if ((re->win->gl_context->havestuff) || - (re->win->gl_context->master_clip.used)) + if ((re->generic.ob->gl_context->havestuff) || + (re->generic.ob->gl_context->master_clip.used)) { - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); - if (re->win->gl_context->master_clip.used) - evas_gl_common_context_done(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); + if (re->generic.ob->gl_context->master_clip.used) + evas_gl_common_context_done(re->generic.ob->gl_context); } } @@ -3603,8 +3030,8 @@ static void eng_image_max_size_get(void *data, int *maxw, int *maxh) { Render_Engine *re = (Render_Engine *)data; - if (maxw) *maxw = re->win->gl_context->shared->info.max_texture_size; - if (maxh) *maxh = re->win->gl_context->shared->info.max_texture_size; + if (maxw) *maxw = re->generic.ob->gl_context->shared->info.max_texture_size; + if (maxh) *maxh = re->generic.ob->gl_context->shared->info.max_texture_size; } static Eina_Bool @@ -3700,13 +3127,13 @@ eng_context_flush(void *data) Render_Engine *re; re = (Render_Engine *)data; - if ((re->win->gl_context->havestuff) || - (re->win->gl_context->master_clip.used)) + if ((re->generic.ob->gl_context->havestuff) || + (re->generic.ob->gl_context->master_clip.used)) { - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); - if (re->win->gl_context->master_clip.used) - evas_gl_common_context_done(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); + if (re->generic.ob->gl_context->master_clip.used) + evas_gl_common_context_done(re->generic.ob->gl_context); } } @@ -3716,7 +3143,7 @@ eng_context_3d_use(void *data) Render_Engine *re = (Render_Engine *)data; if (!re->context_3d) - re->context_3d = eng_gl_context_new(re->win); + re->context_3d = eng_gl_context_new(re->generic.ob); if (re->context_3d) eng_gl_context_use(re->context_3d); } @@ -3781,8 +3208,8 @@ eng_drawable_scene_render(void *data, void *drawable, void *scene_data) Render_Engine *re = (Render_Engine *)data; E3D_Renderer *renderer = NULL; - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); eng_context_3d_use(data); renderer = eng_renderer_3d_get(data); @@ -3806,8 +3233,8 @@ eng_texture_data_set(void *data, void *texture, Evas_3D_Color_Format color_forma Evas_3D_Pixel_Format pixel_format, int w, int h, const void *pixels) { Render_Engine *re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); eng_context_3d_use(data); e3d_texture_data_set((E3D_Texture *)texture, color_format, pixel_format, w, h, pixels); @@ -3817,8 +3244,8 @@ static void eng_texture_file_set(void *data, void *texture, const char *file, const char *key) { Render_Engine *re = (Render_Engine *)data; - eng_window_use(re->win); - evas_gl_common_context_flush(re->win->gl_context); + eng_window_use(re->generic.ob); + evas_gl_common_context_flush(re->generic.ob->gl_context); eng_context_3d_use(data); e3d_texture_file_set((E3D_Texture *)texture, file, key); @@ -3894,6 +3321,12 @@ module_open(Evas_Module *em) return 0; } + if (partial_render_debug == -1) + { + if (getenv("EVAS_GL_PARTIAL_DEBUG")) partial_render_debug = 1; + else partial_render_debug = 0; + } + /* store it for later use */ func = pfunc; /* now to override methods */ @@ -3903,17 +3336,6 @@ module_open(Evas_Module *em) 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(context_cutout_add); - ORD(context_cutout_clear); - ORD(output_flush); - ORD(output_idle_flush); ORD(output_dump); ORD(rectangle_draw); ORD(line_draw); diff --git a/src/modules/evas/engines/gl_x11/evas_engine.h b/src/modules/evas/engines/gl_x11/evas_engine.h index 2ae3757f44..603c715866 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.h +++ b/src/modules/evas/engines/gl_x11/evas_engine.h @@ -31,6 +31,8 @@ # include #endif +#include "../software_generic/Evas_Engine_Software_Generic.h" + extern int _evas_engine_GL_X11_log_dom ; #ifdef ERR # undef ERR @@ -57,25 +59,11 @@ extern int _evas_engine_GL_X11_log_dom ; #endif #define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_GL_X11_log_dom, __VA_ARGS__) -typedef struct _Evas_GL_X11_Window Evas_GL_X11_Window; +typedef struct _Outbuf Outbuf; typedef struct _Evas_GL_X11_Context Evas_GL_X11_Context; -struct _Evas_GL_X11_Window +struct _Outbuf { - Display *disp; - Window win; - int w, h; - int screen; - XVisualInfo *visualinfo; - Visual *visual; - Colormap colormap; - int depth; - int alpha; - int rot; - Evas_Engine_GL_Context *gl_context; - struct { - int drew : 1; - } draw; #ifdef GL_GLES EGLContext egl_context[1]; EGLSurface egl_surface[1]; @@ -89,7 +77,32 @@ struct _Evas_GL_X11_Window unsigned int loose_binding : 1; } detected; #endif - int surf : 1; + + Evas *evas; + Display *disp; + XVisualInfo *visualinfo; + Visual *visual; + Evas_Engine_GL_Context *gl_context; + Evas_Engine_Info_GL_X11 *info; + + Render_Engine_Swap_Mode swap_mode; + Colormap colormap; + Window win; + int w, h; + int screen; + int depth; + int alpha; + int rot; + int prev_age; + int frame_cnt; + int vsync; + + unsigned char lost_back : 1; + unsigned char surf : 1; + + struct { + unsigned char drew : 1; + } draw; }; struct _Evas_GL_X11_Context @@ -106,21 +119,62 @@ struct _Evas_GL_X11_Context #endif }; -Evas_GL_X11_Window *eng_window_new(Display *disp, Window win, int screen, - Visual *vis, Colormap cmap, - int depth, int w, int h, int indirect, - int alpha, int rot); -void eng_window_free(Evas_GL_X11_Window *gw); -void eng_window_use(Evas_GL_X11_Window *gw); -void eng_window_unsurf(Evas_GL_X11_Window *gw); -void eng_window_resurf(Evas_GL_X11_Window *gw); +extern int extn_have_buffer_age; +extern int partial_render_debug; +extern int swap_buffer_debug_mode; +extern int swap_buffer_debug; +extern const char *debug_dir; + +extern void (*glsym_glXQueryDrawable) (Display *a, XID b, int c, unsigned int *d); +extern void (*glsym_glXSwapIntervalEXT) (Display *s, GLXDrawable b, int c); +extern int (*glsym_glXSwapIntervalSGI) (int a); +extern int (*glsym_glXGetVideoSync) (unsigned int *a); +extern int (*glsym_glXWaitVideoSync) (int a, int b, unsigned int *c); + +Outbuf *eng_window_new(Evas_Engine_Info_GL_X11 *info, Evas *e, + Display *disp, Window win, int screen, + Visual *vis, Colormap cmap, + int depth, int w, int h, int indirect, + int alpha, int rot, + Render_Engine_Swap_Mode swap_mode); +void eng_window_free(Outbuf *gw); +void eng_window_use(Outbuf *gw); +void eng_window_unsurf(Outbuf *gw); +void eng_window_resurf(Outbuf *gw); void *eng_best_visual_get(Evas_Engine_Info_GL_X11 *einfo); Colormap eng_best_colormap_get(Evas_Engine_Info_GL_X11 *einfo); int eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo); -Evas_GL_X11_Context *eng_gl_context_new(Evas_GL_X11_Window *win); +Evas_GL_X11_Context *eng_gl_context_new(Outbuf *win); void eng_gl_context_free(Evas_GL_X11_Context *context); void eng_gl_context_use(Evas_GL_X11_Context *context); +void eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); +int eng_outbuf_get_rot(Outbuf *ob); +Render_Engine_Swap_Mode eng_outbuf_swap_mode(Outbuf *ob); +Eina_Bool eng_outbuf_region_first_rect(Outbuf *ob); +void *eng_outbuf_new_region_for_update(Outbuf *ob, + int x, int y, int w, int h, + int *cx, int *cy, int *cw, int *ch); +void eng_outbuf_push_free_region_for_update(Outbuf *ob, RGBA_Image *update); +void eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update, + int x, int y, int w, int h); +void eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); + +Eina_Bool eng_preload_make_current(void *data, void *doit); + +static inline int +_re_wincheck(Outbuf *ob) +{ + if (ob->surf) return 1; + eng_window_resurf(ob); + ob->lost_back = 1; + if (!ob->surf) + { + ERR("GL engine can't re-create window surface!"); + } + return 0; +} + #endif diff --git a/src/modules/evas/engines/gl_x11/evas_x_main.c b/src/modules/evas/engines/gl_x11/evas_x_main.c index 92fe2d0286..f4ba440b89 100644 --- a/src/modules/evas/engines/gl_x11/evas_x_main.c +++ b/src/modules/evas/engines/gl_x11/evas_x_main.c @@ -1,6 +1,6 @@ #include "evas_engine.h" -static Evas_GL_X11_Window *_evas_gl_x11_window = NULL; +static Outbuf *_evas_gl_x11_window = NULL; #ifdef GL_GLES static EGLContext context = EGL_NO_CONTEXT; @@ -22,8 +22,10 @@ static Colormap _evas_gl_x11_rgba_cmap = 0; static int win_count = 0; -Evas_GL_X11_Window * -eng_window_new(Display *disp, +Outbuf * +eng_window_new(Evas_Engine_Info_GL_X11 *info, + Evas *e, + Display *disp, Window win, int screen, Visual *vis, @@ -33,9 +35,10 @@ eng_window_new(Display *disp, int h, int indirect, int alpha, - int rot) + int rot, + Render_Engine_Swap_Mode swap_mode) { - Evas_GL_X11_Window *gw; + Outbuf *gw; #ifdef GL_GLES int context_attrs[3]; int config_attrs[40]; @@ -48,7 +51,7 @@ eng_window_new(Display *disp, if (!_evas_gl_x11_vi) return NULL; - gw = calloc(1, sizeof(Evas_GL_X11_Window)); + gw = calloc(1, sizeof(Outbuf)); if (!gw) return NULL; win_count++; @@ -62,6 +65,9 @@ eng_window_new(Display *disp, gw->w = w; gw->h = h; gw->rot = rot; + gw->swap_mode = swap_mode; + gw->info = info; + gw->evas = e; vi_use = _evas_gl_x11_vi; if (gw->alpha) @@ -416,7 +422,7 @@ eng_window_new(Display *disp, } void -eng_window_free(Evas_GL_X11_Window *gw) +eng_window_free(Outbuf *gw) { int ref = 0; win_count--; @@ -458,7 +464,7 @@ eng_window_free(Evas_GL_X11_Window *gw) static Eina_Bool eng_window_make_current(void *data, void *doit) { - Evas_GL_X11_Window *gw = data; + Outbuf *gw = data; #ifdef GL_GLES if (doit) @@ -501,7 +507,7 @@ eng_window_make_current(void *data, void *doit) } void -eng_window_use(Evas_GL_X11_Window *gw) +eng_window_use(Outbuf *gw) { Eina_Bool force_use = EINA_FALSE; @@ -565,7 +571,7 @@ eng_window_use(Evas_GL_X11_Window *gw) } void -eng_window_unsurf(Evas_GL_X11_Window *gw) +eng_window_unsurf(Outbuf *gw) { if (!gw->surf) return; if (!getenv("EVAS_GL_WIN_RESURF")) return; @@ -596,7 +602,7 @@ eng_window_unsurf(Evas_GL_X11_Window *gw) } void -eng_window_resurf(Evas_GL_X11_Window *gw) +eng_window_resurf(Outbuf *gw) { if (gw->surf) return; if (getenv("EVAS_GL_INFO")) @@ -851,7 +857,7 @@ eng_best_depth_get(Evas_Engine_Info_GL_X11 *einfo) } Evas_GL_X11_Context * -eng_gl_context_new(Evas_GL_X11_Window *win) +eng_gl_context_new(Outbuf *win) { Evas_GL_X11_Context *ctx; #if GL_GLES @@ -939,3 +945,305 @@ eng_gl_context_use(Evas_GL_X11_Context *ctx) } #endif } + +void +eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth EINA_UNUSED) +{ + ob->w = w; + ob->h = h; + ob->rot = rot; + eng_window_use(ob); + evas_gl_common_context_resize(ob->gl_context, w, h, rot); +} + +int +eng_outbuf_get_rot(Outbuf *ob) +{ + return ob->rot; +} + +Render_Engine_Swap_Mode +eng_outbuf_swap_mode(Outbuf *ob) +{ + if (ob->swap_mode == MODE_AUTO && extn_have_buffer_age) + { + Render_Engine_Swap_Mode swap_mode; +#ifdef GL_GLES + EGLint age = 0; + + if (!eglQuerySurface(ob->egl_disp, + ob->egl_surface[0], + EGL_BUFFER_AGE_EXT, &age)) + age = 0; +#else + unsigned int age = 0; + + if (glsym_glXQueryDrawable) + { + if (ob->glxwin) + glsym_glXQueryDrawable(ob->disp, + ob->glxwin, + GLX_BACK_BUFFER_AGE_EXT, + &age); + else + glsym_glXQueryDrawable(ob->disp, + ob->win, + GLX_BACK_BUFFER_AGE_EXT, + &age); + } +#endif + if (age == 1) swap_mode = MODE_COPY; + else if (age == 2) swap_mode = MODE_DOUBLE; + else if (age == 3) swap_mode = MODE_TRIPLE; + else if (age == 4) swap_mode = MODE_QUADRUPLE; + else swap_mode = MODE_FULL; + if ((int)age != ob->prev_age) swap_mode = MODE_FULL; + ob->prev_age = age; + + return swap_mode; + } + + return ob->swap_mode; +} + +Eina_Bool +eng_outbuf_region_first_rect(Outbuf *ob) +{ + ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; + + evas_gl_preload_render_lock(eng_preload_make_current, ob); +#ifdef GL_GLES + // dont need to for egl - eng_window_use() can check for other ctxt's +#else + eng_window_use(NULL); +#endif + eng_window_use(ob); + if (!_re_wincheck(ob)) return EINA_TRUE; + + evas_gl_common_context_flush(ob->gl_context); + evas_gl_common_context_newframe(ob->gl_context); + if (partial_render_debug == 1) + { + glClearColor(0.2, 0.5, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + } + + return EINA_FALSE; +} + +void* +eng_outbuf_new_region_for_update(Outbuf *ob, + int x, int y, int w, int h, + int *cx EINA_UNUSED, int *cy EINA_UNUSED, + int *cw EINA_UNUSED, int *ch EINA_UNUSED) +{ + if (w == ob->w && h == ob->h) + { + ob->gl_context->master_clip.enabled = EINA_FALSE; + } + else + { + ob->gl_context->master_clip.enabled = EINA_TRUE; + ob->gl_context->master_clip.x = x; + ob->gl_context->master_clip.y = y; + ob->gl_context->master_clip.w = w; + ob->gl_context->master_clip.h = h; + } + return ob->gl_context->def_surface; +} + +void +eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update EINA_UNUSED, + int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) +{ + /* Is it really necessary to flush per region ? Shouldn't we be able to + still do that for the full canvas when doing partial update */ + if (!_re_wincheck(ob)) return; + ob->draw.drew = 1; + evas_gl_common_context_flush(ob->gl_context); +#ifdef GL_GLES + // this is needed to make sure all previous rendering is flushed to + // buffers/surfaces + // previous rendering should be done and swapped +//xx if (!safe_native) eglWaitNative(EGL_CORE_NATIVE_ENGINE); +// if (eglGetError() != EGL_SUCCESS) +// { +// printf("Error: eglWaitNative(EGL_CORE_NATIVE_ENGINE) fail.\n"); +// } +#else + // previous rendering should be done and swapped +//xx if (!safe_native) glXWaitX(); +#endif +} + +void +eng_outbuf_push_free_region_for_update(Outbuf *ob EINA_UNUSED, + RGBA_Image *update EINA_UNUSED) +{ + /* Nothing to do here as we don't really create an image per area */ +} + +void +eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode) +{ + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end; + + if (!_re_wincheck(ob)) goto end; + if (!ob->draw.drew) goto end; + + ob->draw.drew = 0; + eng_window_use(ob); + evas_gl_common_context_done(ob->gl_context); + + // Save contents of the framebuffer to a file + if (swap_buffer_debug_mode == 1) + { + if (swap_buffer_debug) + { + char fname[100]; + int ret = 0; + snprintf(fname, sizeof(fname), "%p", (void*)ob); + + ret = evas_gl_common_buffer_dump(ob->gl_context, + (const char*)debug_dir, + (const char*)fname, + ob->frame_cnt, + NULL); + if (!ret) swap_buffer_debug_mode = 0; + } + } + +#ifdef GL_GLES + if (!ob->vsync) + { + if (ob->info->vsync) eglSwapInterval(ob->egl_disp, 1); + else eglSwapInterval(ob->egl_disp, 0); + ob->vsync = 1; + } + if (ob->info->callback.pre_swap) + { + ob->info->callback.pre_swap(ob->info->callback.data, re->evas); + } + if ((glsym_eglSwapBuffersWithDamage) && (re->swap_mode != MODE_FULL)) + { + EGLint num = 0, *result = NULL, i = 0; + Tilebuf_Rect *r; + + // if partial swaps can be done use re->rects + num = eina_inlist_count(EINA_INLIST_GET(rects)); + if (num > 0) + { + result = alloca(sizeof(EGLint) * 4 * num); + EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) + { + int gw, gh; + + gw = ob->gl_context->w; + gh = ob->gl_context->h; + switch (ob->rot) + { + case 0: + result[i + 0] = r->x; + result[i + 1] = gh - (r->y + r->h); + result[i + 2] = r->w; + result[i + 3] = r->h; + break; + case 90: + result[i + 0] = r->y; + result[i + 1] = r->x; + result[i + 2] = r->h; + result[i + 3] = r->w; + break; + case 180: + result[i + 0] = gw - (r->x + r->w); + result[i + 1] = r->y; + result[i + 2] = r->w; + result[i + 3] = r->h; + break; + case 270: + result[i + 0] = gh - (r->y + r->h); + result[i + 1] = gw - (r->x + r->w); + result[i + 2] = r->h; + result[i + 3] = r->w; + break; + default: + result[i + 0] = r->x; + result[i + 1] = gh - (r->y + r->h); + result[i + 2] = r->w; + result[i + 3] = r->h; + break; + } + i += 4; + } + glsym_eglSwapBuffersWithDamage(ob->egl_disp, + ob->egl_surface[0], + rects, num); + } + } + else + eglSwapBuffers(ob->egl_disp, ob->egl_surface[0]); + +//xx if (!safe_native) eglWaitGL(); + if (ob->info->callback.post_swap) + { + ob->info->callback.post_swap(ob->info->callback.data, ob->evas); + } +// if (eglGetError() != EGL_SUCCESS) +// { +// printf("Error: eglSwapBuffers() fail.\n"); +// } +#else + (void)rects; +#ifdef VSYNC_TO_SCREEN + if (ob->info->vsync) + { + if (glsym_glXSwapIntervalEXT) + { + if (!ob->vsync) + { + if (ob->info->vsync) glsym_glXSwapIntervalEXT(ob->disp, ob->win, 1); + else glsym_glXSwapIntervalEXT(ob->disp, ob->win, 0); + ob->vsync = 1; + } + } + else if (glsym_glXSwapIntervalSGI) + { + if (!ob->vsync) + { + if (ob->info->vsync) glsym_glXSwapIntervalSGI(1); + else glsym_glXSwapIntervalSGI(0); + ob->vsync = 1; + } + } + else + { + if ((glsym_glXGetVideoSync) && (glsym_glXWaitVideoSync)) + { + unsigned int rc; + + glsym_glXGetVideoSync(&rc); + glsym_glXWaitVideoSync(1, 0, &rc); + } + } + } +#endif + if (ob->info->callback.pre_swap) + { + ob->info->callback.pre_swap(ob->info->callback.data, ob->evas); + } + // XXX: if partial swaps can be done use re->rects +// measure(0, "swap"); + glXSwapBuffers(ob->disp, ob->win); +// measure(1, "swap"); + if (ob->info->callback.post_swap) + { + ob->info->callback.post_swap(ob->info->callback.data, ob->evas); + } +#endif + // clear out rects after swap as we may use them during swap + + ob->frame_cnt++; + + end: + evas_gl_preload_render_unlock(eng_preload_make_current, ob); +} diff --git a/src/modules/evas/engines/software_ddraw/evas_engine.c b/src/modules/evas/engines/software_ddraw/evas_engine.c index 0e6d96b49e..31934e6dde 100644 --- a/src/modules/evas/engines/software_ddraw/evas_engine.c +++ b/src/modules/evas/engines/software_ddraw/evas_engine.c @@ -12,18 +12,12 @@ typedef struct _Render_Engine Render_Engine; struct _Render_Engine { - Tilebuf *tb; - Outbuf *ob; - Tilebuf_Rect *rects; - Eina_Inlist *cur_rect; - int end : 1; + Render_Engine_Software_Generic generic; }; - /* log domain variable */ int _evas_log_dom_module = -1; - static void * _output_setup(int width, int height, @@ -33,6 +27,7 @@ _output_setup(int width, int fullscreen) { Render_Engine *re; + Outbuf *ob; re = calloc(1, sizeof(Render_Engine)); if (!re) @@ -54,35 +49,29 @@ _output_setup(int width, evas_software_ddraw_outbuf_init(); - re->ob = evas_software_ddraw_outbuf_setup(width, height, rot, - OUTBUF_DEPTH_INHERIT, - window, depth, fullscreen); - if (!re->ob) - { - free(re); - return NULL; - } + ob = evas_software_ddraw_outbuf_setup(width, height, rot, + OUTBUF_DEPTH_INHERIT, + window, depth, fullscreen); + if (!ob) goto on_error; - /* for updates return 1 big buffer, but only use portions of it, also cache - it and keep it around until an idle_flush */ - /* disable for now - i am hunting down why some expedite tests are slower, - * as well as shaped stuff is broken and probable non-32bpp is broken as - * convert funcs dont do the right thing - * - re->ob->onebuf = 1; - */ - - re->tb = evas_common_tilebuf_new(width, height); - if (!re->tb) - { - evas_software_ddraw_outbuf_free(re->ob); - free(re); - return NULL; - } - /* in preliminary tests 16x16 gave highest framerates */ - evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + if (!evas_render_engine_software_generic_init(&re->generic, ob, NULL, + evas_software_ddraw_outbuf_rot_get, + evas_software_ddraw_outbuf_reconfigure, + evas_software_ddraw_outbuf_new_region_for_update, + evas_software_ddraw_outbuf_push_updated_region, + evas_software_ddraw_outbuf_free_region_for_update, + evas_software_ddraw_outbuf_idle_flush, + evas_software_ddraw_outbuf_flush, + evas_software_ddraw_outbuf_free, + width, height)) + goto on_error; return re; + + on_error: + if (ob) evas_software_ddraw_outbuf_free(ob); + free(re); + return NULL; } @@ -101,9 +90,10 @@ eng_info(Evas *e EINA_UNUSED) } static void -eng_info_free(Evas *e, void *info) +eng_info_free(Evas *e EINA_UNUSED, void *info) { Evas_Engine_Info_Software_DDraw *in; + in = (Evas_Engine_Info_Software_DDraw *)info; free(in); } @@ -112,7 +102,7 @@ static int eng_setup(Evas *eo_e, void *in) { Evas_Public_Data *e = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS); - Render_Engine *re; + Render_Engine *re; Evas_Engine_Info_Software_DDraw *info; info = (Evas_Engine_Info_Software_DDraw *)in; @@ -125,19 +115,23 @@ eng_setup(Evas *eo_e, void *in) info->info.fullscreen); else { - int ponebuf = 0; + Outbuf *ob; + int ponebuf = 0; - re = e->engine.data.output; - ponebuf = re->ob->onebuf; - evas_software_ddraw_outbuf_free(re->ob); - re->ob = evas_software_ddraw_outbuf_setup(e->output.w, - e->output.h, - info->info.rotation, - OUTBUF_DEPTH_INHERIT, - info->info.window, - info->info.depth, - info->info.fullscreen); - re->ob->onebuf = ponebuf; + re = e->engine.data.output; + ponebuf = re->generic.ob->onebuf; + + ob = evas_software_ddraw_outbuf_setup(e->output.w, + e->output.h, + info->info.rotation, + OUTBUF_DEPTH_INHERIT, + info->info.window, + info->info.depth, + info->info.fullscreen); + if (!ob) return 0; + evas_render_engine_software_generic_update(&re->generic, ob); + + re->generic.ob->onebuf = ponebuf; } if (!e->engine.data.output) return 0; if (!e->engine.data.context) @@ -156,166 +150,13 @@ eng_output_free(void *data) if (!data) return; re = (Render_Engine *)data; - evas_software_ddraw_outbuf_free(re->ob); - evas_common_tilebuf_free(re->tb); - if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); + 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 width, int height) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_software_ddraw_outbuf_reconfigure(re->ob, - width, - height, - evas_software_ddraw_outbuf_rot_get(re->ob), - OUTBUF_DEPTH_INHERIT); - evas_common_tilebuf_free(re->tb); - re->tb = evas_common_tilebuf_new(width, height); - 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; - int uy; - int uw; - int 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_software_ddraw_outbuf_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, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - re = (Render_Engine *)data; -#ifdef BUILD_PIPE_RENDER - evas_common_pipe_map_begin(surface); -#endif - evas_software_ddraw_outbuf_push_updated_region(re->ob, surface, x, y, w, h); - evas_software_ddraw_outbuf_free_region_for_update(re->ob, surface); - 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; - - re = (Render_Engine *)data; - evas_software_ddraw_outbuf_flush(re->ob); -} - -static void -eng_output_idle_flush(void *data) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_software_ddraw_outbuf_idle_flush(re->ob); -} - static Eina_Bool eng_canvas_alpha_get(void *data EINA_UNUSED, void *context EINA_UNUSED) { @@ -346,15 +187,6 @@ module_open(Evas_Module *em) 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; diff --git a/src/modules/evas/engines/software_ddraw/evas_engine.h b/src/modules/evas/engines/software_ddraw/evas_engine.h index 2f5917037c..9217cdcfa5 100644 --- a/src/modules/evas/engines/software_ddraw/evas_engine.h +++ b/src/modules/evas/engines/software_ddraw/evas_engine.h @@ -7,24 +7,12 @@ #undef WIN32_LEAN_AND_MEAN #include +#include "../software_generic/Evas_Engine_Software_Generic.h" + typedef struct _Outbuf Outbuf; typedef struct _Outbuf_Region Outbuf_Region; typedef struct _DD_Output_Buffer DD_Output_Buffer; -enum _Outbuf_Depth -{ - OUTBUF_DEPTH_NONE, - OUTBUF_DEPTH_INHERIT, - OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED, - OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED, - OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED, - OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED, - OUTBUF_DEPTH_RGB_32BPP_888_8888, - OUTBUF_DEPTH_LAST -}; - -typedef enum _Outbuf_Depth Outbuf_Depth; - struct _Outbuf { Outbuf_Depth depth; @@ -152,7 +140,7 @@ void evas_software_ddraw_outbuf_push_updated_region(Outbuf *buf, void evas_software_ddraw_outbuf_free_region_for_update(Outbuf *buf, RGBA_Image *update); -void evas_software_ddraw_outbuf_flush(Outbuf *buf); +void evas_software_ddraw_outbuf_flush(Outbuf *buf, Evas_Render_Mode render_mode); void evas_software_ddraw_outbuf_idle_flush(Outbuf *buf); diff --git a/src/modules/evas/engines/software_ddraw/evas_outbuf.c b/src/modules/evas/engines/software_ddraw/evas_outbuf.c index 0e121ac981..4d6a515c64 100644 --- a/src/modules/evas/engines/software_ddraw/evas_outbuf.c +++ b/src/modules/evas/engines/software_ddraw/evas_outbuf.c @@ -356,7 +356,7 @@ evas_software_ddraw_outbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, } void -evas_software_ddraw_outbuf_flush(Outbuf *buf) +evas_software_ddraw_outbuf_flush(Outbuf *buf, Evas_Render_Mode render_mode) { Eina_List *l; RGBA_Image *im; @@ -367,6 +367,8 @@ evas_software_ddraw_outbuf_flush(Outbuf *buf) int ddraw_pitch; int ddraw_depth; + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; + /* lock the back surface */ if (!(ddraw_data = evas_software_ddraw_lock(buf, &ddraw_width, diff --git a/src/modules/evas/engines/software_gdi/evas_engine.c b/src/modules/evas/engines/software_gdi/evas_engine.c index a1cc27f6e4..10a88b1194 100644 --- a/src/modules/evas/engines/software_gdi/evas_engine.c +++ b/src/modules/evas/engines/software_gdi/evas_engine.c @@ -12,11 +12,7 @@ typedef struct _Render_Engine Render_Engine; struct _Render_Engine { - Tilebuf *tb; - Outbuf *ob; - Tilebuf_Rect *rects; - Eina_Inlist *cur_rect; - int end : 1; + Render_Engine_Software_Generic generic; }; @@ -31,6 +27,7 @@ _output_setup(int width, unsigned int region) { Render_Engine *re; + Outbuf *ob; re = calloc(1, sizeof(Render_Engine)); if (!re) @@ -57,36 +54,30 @@ _output_setup(int width, if (height <= 0) height = 1; - re->ob = evas_software_gdi_outbuf_setup(width, height, rot, - OUTBUF_DEPTH_INHERIT, - window, depth, borderless, fullscreen, region, - 0, 0); - if (!re->ob) - { - free(re); - return NULL; - } + ob = evas_software_gdi_outbuf_setup(width, height, rot, + OUTBUF_DEPTH_INHERIT, + window, depth, borderless, fullscreen, region, + 0, 0); + if (!ob) goto on_error; - /* for updates return 1 big buffer, but only use portions of it, also cache - it and keep it around until an idle_flush */ - /* disable for now - i am hunting down why some expedite tests are slower, - * as well as shaped stuff is broken and probable non-32bpp is broken as - * convert funcs dont do the right thing - * - re->ob->onebuf = 1; - */ - - re->tb = evas_common_tilebuf_new(width, height); - if (!re->tb) - { - evas_software_gdi_outbuf_free(re->ob); - free(re); - return NULL; - } - /* in preliminary tests 16x16 gave highest framerates */ - evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + if (!evas_render_engine_software_generic_init(&re->generic, ob, NULL, + evas_software_gdi_outbuf_rot_get, + evas_software_gdi_outbuf_reconfigure, + evas_software_gdi_outbuf_new_region_for_update, + evas_software_gdi_outbuf_push_updated_region, + evas_software_gdi_outbuf_free_region_for_update, + evas_software_gdi_outbuf_idle_flush, + evas_software_gdi_outbuf_flush, + evas_software_gdi_outbuf_free, + width, height)) + goto on_error; return re; + + on_error: + if (ob) evas_software_gdi_outbuf_free(ob); + free(re); + return NULL; } @@ -129,22 +120,26 @@ eng_setup(Evas *eo_e, void *in) info->info.region); else { - int ponebuf = 0; + Outbuf *ob; + int ponebuf = 0; - re = e->engine.data.output; - ponebuf = re->ob->onebuf; - evas_software_gdi_outbuf_free(re->ob); - re->ob = evas_software_gdi_outbuf_setup(e->output.w, - e->output.h, - info->info.rotation, - OUTBUF_DEPTH_INHERIT, - info->info.window, - info->info.depth, - info->info.borderless, - info->info.fullscreen, - info->info.region, - 0, 0); - re->ob->onebuf = ponebuf; + re = e->engine.data.output; + ponebuf = re->generic.ob->onebuf; + + ob = evas_software_gdi_outbuf_setup(e->output.w, + e->output.h, + info->info.rotation, + OUTBUF_DEPTH_INHERIT, + info->info.window, + info->info.depth, + info->info.borderless, + info->info.fullscreen, + info->info.region, + 0, 0); + if (!ob) return 0; + + evas_render_engine_software_generic_update(&re->generic, ob); + re->generic.ob->onebuf = ponebuf; } if (!e->engine.data.output) return 0; if (!e->engine.data.context) @@ -163,166 +158,13 @@ eng_output_free(void *data) if (!data) return; re = (Render_Engine *)data; - evas_software_gdi_outbuf_free(re->ob); - evas_common_tilebuf_free(re->tb); - if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); + 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 width, int height) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_software_gdi_outbuf_reconfigure(re->ob, - width, - height, - evas_software_gdi_outbuf_rot_get(re->ob), - OUTBUF_DEPTH_INHERIT); - evas_common_tilebuf_free(re->tb); - re->tb = evas_common_tilebuf_new(width, height); - 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; - int uy; - int uw; - int 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_software_gdi_outbuf_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, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - re = (Render_Engine *)data; -#ifdef BUILD_PIPE_RENDER - evas_common_pipe_map_begin(surface); -#endif - evas_software_gdi_outbuf_push_updated_region(re->ob, surface, x, y, w, h); - evas_software_gdi_outbuf_free_region_for_update(re->ob, surface); - 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; - - re = (Render_Engine *)data; - evas_software_gdi_outbuf_flush(re->ob); -} - -static void -eng_output_idle_flush(void *data) -{ - Render_Engine *re; - - re = (Render_Engine *)data; - evas_software_gdi_outbuf_idle_flush(re->ob); -} - static Eina_Bool eng_canvas_alpha_get(void *data EINA_UNUSED, void *context EINA_UNUSED) { @@ -354,15 +196,6 @@ module_open(Evas_Module *em) 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; diff --git a/src/modules/evas/engines/software_gdi/evas_engine.h b/src/modules/evas/engines/software_gdi/evas_engine.h index 2f8a6ebb72..a69032c15f 100644 --- a/src/modules/evas/engines/software_gdi/evas_engine.h +++ b/src/modules/evas/engines/software_gdi/evas_engine.h @@ -6,6 +6,8 @@ #include #undef WIN32_LEAN_AND_MEAN +#include "../software_generic/Evas_Engine_Software_Generic.h" + extern int _evas_engine_soft_gdi_log_dom; #ifdef ERR @@ -33,17 +35,6 @@ extern int _evas_engine_soft_gdi_log_dom; #endif #define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_soft_gdi_log_dom, __VA_ARGS__) -typedef enum _Outbuf_Depth Outbuf_Depth; - -enum _Outbuf_Depth -{ - OUTBUF_DEPTH_NONE, - OUTBUF_DEPTH_INHERIT, - OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED, - OUTBUF_DEPTH_RGB_32BPP_888_8888, - OUTBUF_DEPTH_LAST -}; - typedef struct BITMAPINFO_GDI BITMAPINFO_GDI; typedef struct _Outbuf Outbuf; typedef struct _Outbuf_Region Outbuf_Region; @@ -193,7 +184,7 @@ void evas_software_gdi_outbuf_push_updated_region(Outbuf *buf, void evas_software_gdi_outbuf_free_region_for_update(Outbuf *buf, RGBA_Image *update); -void evas_software_gdi_outbuf_flush(Outbuf *buf); +void evas_software_gdi_outbuf_flush(Outbuf *buf, Evas_Render_Mode render_mode); void evas_software_gdi_outbuf_idle_flush(Outbuf *buf); diff --git a/src/modules/evas/engines/software_gdi/evas_outbuf.c b/src/modules/evas/engines/software_gdi/evas_outbuf.c index 28a64a37d8..705c56961f 100644 --- a/src/modules/evas/engines/software_gdi/evas_outbuf.c +++ b/src/modules/evas/engines/software_gdi/evas_outbuf.c @@ -563,12 +563,14 @@ evas_software_gdi_outbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, } void -evas_software_gdi_outbuf_flush(Outbuf *buf) +evas_software_gdi_outbuf_flush(Outbuf *buf, Evas_Render_Mode render_mode) { Eina_List *l; RGBA_Image *im; Outbuf_Region *obr; + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; + /* copy safely the images that need to be drawn onto the back surface */ EINA_LIST_FOREACH(buf->priv.pending_writes, l, im) { diff --git a/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h b/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h index 483cb46b20..dc9b971d49 100644 --- a/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h +++ b/src/modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h @@ -1,8 +1,6 @@ #ifndef EVAS_ENGINE_SOFTWARE_GENERIC_H_ # define EVAS_ENGINE_SOFTWARE_GENERIC_H_ -#include "evas_private.h" - typedef enum _Outbuf_Depth { OUTBUF_DEPTH_NONE, @@ -30,21 +28,28 @@ typedef enum { MODE_COPY, MODE_DOUBLE, MODE_TRIPLE, - MODE_QUADRUPLE + MODE_QUADRUPLE, + MODE_AUTO } Render_Engine_Swap_Mode; +typedef enum { + MERGE_BOUNDING, + MERGE_FULL +} Render_Engine_Merge_Mode; + typedef struct _Render_Engine_Software_Generic Render_Engine_Software_Generic; typedef struct _Outbuf Outbuf; typedef Render_Engine_Swap_Mode (*Outbuf_Swap_Mode_Get)(Outbuf *ob); typedef void (*Outbuf_Reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); -typedef RGBA_Image *(*Outbuf_New_Region_For_Update)(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); +typedef Eina_Bool (*Outbuf_Region_First_Rect)(Outbuf *ob); +typedef void *(*Outbuf_New_Region_For_Update)(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); typedef void (*Outbuf_Push_Updated_Region)(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); typedef void (*Outbuf_Idle_Flush)(Outbuf *ob); typedef void (*Outbuf_Free_Region_For_Update)(Outbuf *ob, RGBA_Image *update); typedef void (*Outbuf_Free)(Outbuf *ob); typedef int (*Outbuf_Get_Rot)(Outbuf *ob); -typedef void (*Outbuf_Flush)(Outbuf *ob); +typedef void (*Outbuf_Flush)(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); struct _Render_Engine_Software_Generic { @@ -57,6 +62,7 @@ struct _Render_Engine_Software_Generic Outbuf_Swap_Mode_Get outbuf_swap_mode_get; Outbuf_Get_Rot outbuf_get_rot; Outbuf_Reconfigure outbuf_reconfigure; + Outbuf_Region_First_Rect outbuf_region_first_rect; Outbuf_New_Region_For_Update outbuf_new_region_for_update; Outbuf_Push_Updated_Region outbuf_push_updated_region; Outbuf_Idle_Flush outbuf_idle_flush; @@ -66,10 +72,12 @@ struct _Render_Engine_Software_Generic unsigned int w, h; - Render_Engine_Swap_Mode mode; + Render_Engine_Swap_Mode swap_mode; + Render_Engine_Merge_Mode merge_mode; unsigned char end : 1; unsigned char lost_back : 1; + unsigned char tile_strict : 1; }; static inline Eina_Bool @@ -78,6 +86,7 @@ evas_render_engine_software_generic_init(Render_Engine_Software_Generic *re, Outbuf_Swap_Mode_Get outbuf_swap_mode_get, Outbuf_Get_Rot outbuf_get_rot, Outbuf_Reconfigure outbuf_reconfigure, + Outbuf_Region_First_Rect outbuf_region_first_rect, Outbuf_New_Region_For_Update outbuf_new_region_for_update, Outbuf_Push_Updated_Region outbuf_push_updated_region, Outbuf_Free_Region_For_Update outbuf_free_region_for_update, @@ -92,6 +101,7 @@ evas_render_engine_software_generic_init(Render_Engine_Software_Generic *re, re->outbuf_swap_mode_get = outbuf_swap_mode_get; re->outbuf_get_rot = outbuf_get_rot; re->outbuf_reconfigure = outbuf_reconfigure; + re->outbuf_region_first_rect = outbuf_region_first_rect; re->outbuf_new_region_for_update = outbuf_new_region_for_update; re->outbuf_push_updated_region = outbuf_push_updated_region; re->outbuf_idle_flush = outbuf_idle_flush; @@ -106,9 +116,11 @@ evas_render_engine_software_generic_init(Render_Engine_Software_Generic *re, re->w = w; re->h = h; - re->mode = MODE_FULL; + re->swap_mode = MODE_FULL; + re->merge_mode = MERGE_FULL; re->end = 0; re->lost_back = 0; + re->tile_strict = 0; re->tb = evas_common_tilebuf_new(w, h); if (!re->tb) return EINA_FALSE; @@ -135,11 +147,34 @@ evas_render_engine_software_generic_clean(Render_Engine_Software_Generic *re) } static inline void +evas_render_engine_software_generic_merge_mode_set(Render_Engine_Software_Generic *re, + Render_Engine_Merge_Mode merge_mode) +{ + re->merge_mode = merge_mode; +} + +static inline void +evas_render_engine_software_generic_tile_strict_set(Render_Engine_Software_Generic *re, + Eina_Bool tile_strict) +{ + re->tile_strict = !!tile_strict; + evas_common_tilebuf_tile_strict_set(re->tb, re->tile_strict); +} + +static inline Eina_Bool evas_render_engine_software_generic_update(Render_Engine_Software_Generic *re, - Outbuf *ob) + Outbuf *ob, + int w, int h) { if (re->ob) re->outbuf_free(re->ob); re->ob = ob; + + evas_common_tilebuf_free(re->tb); + re->tb = evas_common_tilebuf_new(w, h); + if (!re->tb) return EINA_FALSE; + evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + evas_render_engine_software_generic_tile_strict_set(re, re->tile_strict); + return EINA_TRUE; } #endif diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 6342e20261..7c57fcfdd0 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -2586,6 +2586,7 @@ eng_output_resize(void *data, int w, int h) re->tb = evas_common_tilebuf_new(w, h); if (re->tb) evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + evas_common_tilebuf_tile_strict_set(re->tb, re->tile_strict); re->w = w; re->h = h; } @@ -2627,7 +2628,12 @@ eng_output_redraws_clear(void *data) } static Tilebuf_Rect * -_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, Tilebuf_Rect *r4) +_merge_rects(Render_Engine_Merge_Mode merge_mode, + Tilebuf *tb, + Tilebuf_Rect *r1, + Tilebuf_Rect *r2, + Tilebuf_Rect *r3, + Tilebuf_Rect *r4) { Tilebuf_Rect *r, *rects; @@ -2662,12 +2668,11 @@ _merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, } 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) + if (merge_mode == MERGE_BOUNDING && rects) { int px1, py1, px2, py2; @@ -2690,7 +2695,6 @@ _merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, rects->h = py2 - py1; } } - */ evas_common_tilebuf_clear(tb); return rects; } @@ -2700,9 +2704,8 @@ 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_Software_Generic *re; - RGBA_Image *surface; + void *surface; Tilebuf_Rect *rect; - Eina_Bool first_rect = EINA_FALSE; #define CLEAR_PREV_RECTS(x) \ do { \ @@ -2725,9 +2728,13 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i re->rects = evas_common_tilebuf_get_render_rects(re->tb); if (re->rects) { + // do anything needed for the first rect and update lost backbuffer if needed + if (re->outbuf_region_first_rect) + re->lost_back |= re->outbuf_region_first_rect(re->ob); + if (re->outbuf_swap_mode_get) mode = re->outbuf_swap_mode_get(re->ob); - re->mode = mode; - if ((re->lost_back) || (re->mode == MODE_FULL)) + re->swap_mode = mode; + if ((re->lost_back) || (re->swap_mode == MODE_FULL) || (re->swap_mode == MODE_AUTO)) { /* if we lost our backbuffer since the last frame redraw all */ re->lost_back = 0; @@ -2744,25 +2751,25 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i re->rects_prev[1] = re->rects_prev[0]; re->rects_prev[0] = re->rects; re->rects = NULL; - switch (re->mode) + switch (re->swap_mode) { + case MODE_AUTO: case MODE_FULL: case MODE_COPY: // no prev rects needed - re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL, NULL); + re->rects = _merge_rects(re->merge_mode, re->tb, re->rects_prev[0], NULL, NULL, NULL); break; case MODE_DOUBLE: // double mode - only 1 level of prev rect - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL); + re->rects = _merge_rects(re->merge_mode, re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL); break; case MODE_TRIPLE: // triple mode - 2 levels of prev rect - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], NULL); + re->rects = _merge_rects(re->merge_mode, re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], NULL); break; case MODE_QUADRUPLE: // keep all - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], re->rects_prev[3]); + re->rects = _merge_rects(re->merge_mode, re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2], re->rects_prev[3]); break; default: break; } - first_rect = EINA_TRUE; } evas_common_tilebuf_clear(re->tb); re->cur_rect = EINA_INLIST_GET(re->rects); @@ -2771,7 +2778,7 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i rect = (Tilebuf_Rect *)re->cur_rect; if (re->rects) { - switch (re->mode) + switch (re->swap_mode) { case MODE_COPY: case MODE_DOUBLE: @@ -2788,6 +2795,7 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i *ch = rect->h; re->cur_rect = re->cur_rect->next; break; + case MODE_AUTO: case MODE_FULL: re->cur_rect = NULL; if (x) *x = 0; @@ -2802,10 +2810,6 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i default: break; } - if (first_rect) - { - // do anything needed fir the first frame - } surface = re->outbuf_new_region_for_update(re->ob, *x, *y, *w, *h, cx, cy, cw, ch); @@ -2842,8 +2846,8 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode) if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; re = (Render_Engine_Software_Generic *)data; - if (re->outbuf_flush) re->outbuf_flush(re->ob); - if (re->rects) + if (re->outbuf_flush) re->outbuf_flush(re->ob, re->rects, render_mode); + if (re->rects && render_mode != EVAS_RENDER_MODE_ASYNC_INIT) { evas_common_tilebuf_free_render_rects(re->rects); re->rects = NULL; diff --git a/src/modules/evas/engines/software_x11/evas_engine.c b/src/modules/evas/engines/software_x11/evas_engine.c index 80036d8e9f..2d7e9bfb61 100644 --- a/src/modules/evas/engines/software_x11/evas_engine.c +++ b/src/modules/evas/engines/software_x11/evas_engine.c @@ -163,6 +163,7 @@ _output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw, if (!evas_render_engine_software_generic_init(&re->generic, ob, NULL, evas_software_xlib_outbuf_get_rot, evas_software_xlib_outbuf_reconfigure, + NULL, evas_software_xlib_outbuf_new_region_for_update, evas_software_xlib_outbuf_push_updated_region, evas_software_xlib_outbuf_free_region_for_update, @@ -207,6 +208,7 @@ _output_swapbuf_setup(int w, int h, int rot, Display *disp, Drawable draw, evas_software_xlib_swapbuf_buffer_state_get, evas_software_xlib_swapbuf_get_rot, evas_software_xlib_swapbuf_reconfigure, + NULL, evas_software_xlib_swapbuf_new_region_for_update, evas_software_xlib_swapbuf_push_updated_region, evas_software_xlib_swapbuf_free_region_for_update, @@ -262,6 +264,7 @@ _output_xcb_setup(int w, int h, int rot, xcb_connection_t *conn, if (!evas_render_engine_software_generic_init(re, ob, NULL, evas_software_xcb_outbuf_rotation_get, evas_software_xcb_outbuf_reconfigure, + NULL, evas_software_xcb_outbuf_new_region_for_update, evas_software_xcb_outbuf_push_updated_region, evas_software_xcb_outbuf_free_region_for_update, @@ -568,7 +571,7 @@ eng_setup(Evas *eo_e, void *in) if (ob) { - evas_render_engine_software_generic_update(&re->generic, ob); + evas_render_engine_software_generic_update(&re->generic, ob, e->output.w, e->output.h); } /* if ((re) && (re->ob)) re->ob->onebuf = ponebuf; */ diff --git a/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c b/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c index ba544efcb4..048e7edd8e 100644 --- a/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c +++ b/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c @@ -259,7 +259,7 @@ evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_co return buf; } -RGBA_Image * +void * evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) { RGBA_Image *im = NULL; @@ -581,12 +581,14 @@ evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_Im } void -evas_software_xcb_outbuf_flush(Outbuf *buf) +evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects, Evas_Render_Mode render_mode) { Eina_List *l = NULL; RGBA_Image *im = NULL; Outbuf_Region *obr = NULL; + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; + if ((buf->priv.onebuf) && (eina_array_count(&buf->priv.onebuf_regions))) { Eina_Array_Iterator it; diff --git a/src/modules/evas/engines/software_x11/evas_xcb_outbuf.h b/src/modules/evas/engines/software_x11/evas_xcb_outbuf.h index e9f300180b..39ac6dcd84 100644 --- a/src/modules/evas/engines/software_x11/evas_xcb_outbuf.h +++ b/src/modules/evas/engines/software_x11/evas_xcb_outbuf.h @@ -6,9 +6,9 @@ void evas_software_xcb_outbuf_init(void); void evas_software_xcb_outbuf_free(Outbuf *buf); Outbuf *evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha); -RGBA_Image *evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); +void *evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); void evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf, RGBA_Image *update); -void evas_software_xcb_outbuf_flush(Outbuf *buf); +void evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); void evas_software_xcb_outbuf_idle_flush(Outbuf *buf); void evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h); void evas_software_xcb_outbuf_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth); diff --git a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c index a189accc27..8fd2f1079c 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c +++ b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c @@ -172,7 +172,7 @@ evas_software_xlib_outbuf_free(Outbuf *buf) free(obr); } evas_software_xlib_outbuf_idle_flush(buf); - evas_software_xlib_outbuf_flush(buf); + evas_software_xlib_outbuf_flush(buf, NULL, MODE_FULL); if (buf->priv.x11.xlib.gc) XFreeGC(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc); if (buf->priv.x11.xlib.gcm) @@ -361,7 +361,7 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth, return buf; } -RGBA_Image * +void * evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) { RGBA_Image *im; @@ -710,12 +710,14 @@ evas_software_xlib_outbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_I } void -evas_software_xlib_outbuf_flush(Outbuf *buf) +evas_software_xlib_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode) { Eina_List *l; RGBA_Image *im; Outbuf_Region *obr; + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; + if ((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions)) { Eina_Rectangle *rect; diff --git a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.h b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.h index 8745a1abfd..16f0cf1b53 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.h +++ b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.h @@ -25,20 +25,20 @@ Outbuf *evas_software_xlib_outbuf_setup_x (int w, int destination_alpha); -RGBA_Image *evas_software_xlib_outbuf_new_region_for_update (Outbuf *buf, - int x, - int y, - int w, - int h, - int *cx, - int *cy, - int *cw, - int *ch); +void *evas_software_xlib_outbuf_new_region_for_update (Outbuf *buf, + int x, + int y, + int w, + int h, + int *cx, + int *cy, + int *cw, + int *ch); void evas_software_xlib_outbuf_free_region_for_update (Outbuf *buf, RGBA_Image *update); -void evas_software_xlib_outbuf_flush (Outbuf *buf); +void evas_software_xlib_outbuf_flush (Outbuf *buf, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); void evas_software_xlib_outbuf_idle_flush (Outbuf *buf); diff --git a/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.c b/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.c index ddd128b9ca..59a83d81ec 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.c +++ b/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.c @@ -34,7 +34,7 @@ evas_software_xlib_swapbuf_init(void) void evas_software_xlib_swapbuf_free(Outbuf *buf) { - evas_software_xlib_swapbuf_flush(buf); + evas_software_xlib_swapbuf_flush(buf, NULL, MODE_FULL); evas_software_xlib_swapbuf_idle_flush(buf); if (buf->priv.pal) evas_software_xlib_x_color_deallocate @@ -207,7 +207,7 @@ evas_software_xlib_swapbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth, return buf; } -RGBA_Image * +void * evas_software_xlib_swapbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) { RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h); @@ -315,25 +315,27 @@ evas_software_xlib_swapbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_ } void -evas_software_xlib_swapbuf_flush(Outbuf *buf) +evas_software_xlib_swapbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode EINA_UNUSED) { + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; + if (!buf->priv.pending_writes) { - Eina_Rectangle *rects, *rect; + Eina_Rectangle *result, *rect; Eina_Array_Iterator it; unsigned int n, i; RGBA_Image *im; n = eina_array_count_get(&buf->priv.onebuf_regions); if (n == 0) return; - rects = alloca(n * sizeof(Eina_Rectangle)); + result = alloca(n * sizeof(Eina_Rectangle)); EINA_ARRAY_ITER_NEXT(&buf->priv.onebuf_regions, i, rect, it) { - rects[i] = *rect; + result[i] = *rect; eina_rectangle_free(rect); } evas_xlib_swapper_buffer_unmap(buf->priv.swapper); - evas_xlib_swapper_swap(buf->priv.swapper, rects, n); + evas_xlib_swapper_swap(buf->priv.swapper, result, n); eina_array_clean(&buf->priv.onebuf_regions); im = buf->priv.onebuf; buf->priv.onebuf = NULL; @@ -350,12 +352,12 @@ evas_software_xlib_swapbuf_flush(Outbuf *buf) else { RGBA_Image *im; - Eina_Rectangle *rects; + Eina_Rectangle *result; unsigned int n, i = 0; n = eina_list_count(buf->priv.pending_writes); if (n == 0) return; - rects = alloca(n * sizeof(Eina_Rectangle)); + result = alloca(n * sizeof(Eina_Rectangle)); EINA_LIST_FREE(buf->priv.pending_writes, im) { Eina_Rectangle *rect = im->extended_info; @@ -364,33 +366,33 @@ evas_software_xlib_swapbuf_flush(Outbuf *buf) x = rect->x; y = rect->y; w = rect->w; h = rect->h; if (buf->rot == 0) { - rects[i].x = x; - rects[i].y = y; + result[i].x = x; + result[i].y = y; } else if (buf->rot == 90) { - rects[i].x = y; - rects[i].y = buf->w - x - w; + result[i].x = y; + result[i].y = buf->w - x - w; } else if (buf->rot == 180) { - rects[i].x = buf->w - x - w; - rects[i].y = buf->h - y - h; + result[i].x = buf->w - x - w; + result[i].y = buf->h - y - h; } else if (buf->rot == 270) { - rects[i].x = buf->h - y - h; - rects[i].y = x; + result[i].x = buf->h - y - h; + result[i].y = x; } if ((buf->rot == 0) || (buf->rot == 180)) { - rects[i].w = w; - rects[i].h = h; + result[i].w = w; + result[i].h = h; } else if ((buf->rot == 90) || (buf->rot == 270)) { - rects[i].w = h; - rects[i].h = w; + result[i].w = h; + result[i].h = w; } eina_rectangle_free(rect); #ifdef EVAS_CSERVE2 @@ -402,7 +404,7 @@ evas_software_xlib_swapbuf_flush(Outbuf *buf) i++; } evas_xlib_swapper_buffer_unmap(buf->priv.swapper); - evas_xlib_swapper_swap(buf->priv.swapper, rects, n); + evas_xlib_swapper_swap(buf->priv.swapper, result, n); // evas_xlib_swapper_swap(buf->priv.swapper, NULL, 0); } } diff --git a/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.h b/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.h index ac8011697a..031c29de1f 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.h +++ b/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.h @@ -21,18 +21,18 @@ Outbuf *evas_software_xlib_swapbuf_setup_x(int w, Pixmap mask, int shape_dither, int destination_alpha); -RGBA_Image *evas_software_xlib_swapbuf_new_region_for_update(Outbuf *buf, - int x, - int y, - int w, - int h, - int *cx, - int *cy, - int *cw, - int *ch); +void *evas_software_xlib_swapbuf_new_region_for_update(Outbuf *buf, + int x, + int y, + int w, + int h, + int *cx, + int *cy, + int *cw, + int *ch); void evas_software_xlib_swapbuf_free_region_for_update(Outbuf *buf, RGBA_Image *update); -void evas_software_xlib_swapbuf_flush(Outbuf *buf); +void evas_software_xlib_swapbuf_flush(Outbuf *buf, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); void evas_software_xlib_swapbuf_idle_flush(Outbuf *buf); void evas_software_xlib_swapbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.c b/src/modules/evas/engines/wayland_shm/evas_engine.c index 415b40eb13..c8a612e188 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.c +++ b/src/modules/evas/engines/wayland_shm/evas_engine.c @@ -9,48 +9,16 @@ typedef struct _Render_Engine Render_Engine; struct _Render_Engine { - Evas_Engine_Info_Wayland_Shm *info; - Outbuf *ob; - Tilebuf *tb; + Render_Engine_Software_Generic generic; - Tilebuf_Rect *rects; - Tilebuf_Rect *prev_rects[3]; - Eina_Inlist *cur_rect; - - short mode; - - Eina_Bool end : 1; - Eina_Bool lost_back : 1; - - /* function pointers for output buffer functions that we can - * override based on if we are swapping or not */ - void (*outbuf_free)(Outbuf *ob); - void (*outbuf_reconfigure)(Outbuf *ob, int x, int y, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha); - RGBA_Image *(*outbuf_update_region_new)(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); - void (*outbuf_update_region_push)(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); - void (*outbuf_update_region_free)(Outbuf *ob, RGBA_Image *update); - void (*outbuf_flush)(Outbuf *ob); - void (*outbuf_idle_flush)(Outbuf *ob); + void (*outbuf_reconfigure)(Outbuf *ob, int x, int y, int w, int h, int rot, Outbuf_Depth depth, Eina_Bool alpha); }; -/* local function prototypes */ -static void *_output_engine_setup(int w, int h, unsigned int rotation, unsigned int depth, Eina_Bool destination_alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface, int try_swap); -static Tilebuf_Rect *_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3); - /* engine function prototypes */ static void *eng_info(Evas *eo_evas EINA_UNUSED); static void eng_info_free(Evas *eo_evas EINA_UNUSED, void *einfo); static int eng_setup(Evas *eo_evas, void *einfo); 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, Evas_Render_Mode render_mode); -static void eng_output_flush(void *data, Evas_Render_Mode render_mode); -static void eng_output_idle_flush(void *data); /* local variables */ static Evas_Func func, pfunc; @@ -60,107 +28,51 @@ int _evas_engine_way_shm_log_dom = -1; /* local functions */ static void * -_output_engine_setup(int w, int h, unsigned int rotation, unsigned int depth, Eina_Bool destination_alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface, int try_swap) +_output_engine_setup(Evas_Engine_Info_Wayland_Shm *info, + int w, int h, + unsigned int rotation, unsigned int depth, + Eina_Bool destination_alpha, + struct wl_shm *wl_shm, + struct wl_surface *wl_surface) { Render_Engine *re = NULL; + Outbuf *ob; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* try to allocate a new render engine */ - if (!(re = calloc(1, sizeof(Render_Engine)))) + if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL; - /* try to create a new tilebuf first */ - if (!(re->tb = evas_common_tilebuf_new(w, h))) - { - free(re); - return NULL; - } - /* set tile size for the tile buffer */ - evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); + ob = evas_swapbuf_setup(info, w, h, rotation, depth, + destination_alpha, wl_shm, + wl_surface); + if (!ob) goto on_error; - if (try_swap) - { - if ((re->ob = evas_swapbuf_setup(w, h, rotation, depth, - destination_alpha, wl_shm, - wl_surface))) - { - re->outbuf_free = evas_swapbuf_free; - re->outbuf_reconfigure = evas_swapbuf_reconfigure; - re->outbuf_update_region_new = evas_swapbuf_update_region_new; - re->outbuf_update_region_push = evas_swapbuf_update_region_push; - re->outbuf_update_region_free = evas_swapbuf_update_region_free; - re->outbuf_flush = evas_swapbuf_flush; - re->outbuf_idle_flush = evas_swapbuf_idle_flush; - } - } + if (!evas_render_engine_software_generic_init(&re->generic, ob, + evas_swapbuf_state_get, + evas_swapbuf_rotation_get, + NULL, + NULL, + evas_swapbuf_update_region_new, + evas_swapbuf_update_region_push, + evas_swapbuf_update_region_free, + evas_swapbuf_idle_flush, + evas_swapbuf_flush, + evas_swapbuf_free, + w, h)) + goto on_error; - /* if creating an output buffer failed, then return NULL */ - if (!re->ob) - { - if (re->tb) evas_common_tilebuf_free(re->tb); - free(re); - return NULL; - } + re->outbuf_reconfigure = evas_swapbuf_reconfigure; /* return allocated render engine */ return re; -} -static Tilebuf_Rect * -_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3) -{ - Tilebuf_Rect *r, *rects; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - 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; + on_error: + if (ob) evas_swapbuf_free(ob); + free(re); + return NULL; } /* engine functions */ @@ -234,49 +146,31 @@ eng_setup(Evas *eo_evas, void *einfo) else try_swap = 1; } - if (!(re = - _output_engine_setup(epd->output.w, epd->output.h, + if (!(re = + _output_engine_setup(info, epd->output.w, epd->output.h, info->info.rotation, info->info.depth, info->info.destination_alpha, - info->info.wl_shm, info->info.wl_surface, - try_swap))) + info->info.wl_shm, info->info.wl_surface))) return 0; - re->info = info; - } + } else { + Outbuf *ob; int ponebuf = 0; - if ((re) && (re->ob)) ponebuf = re->ob->onebuf; + if ((re) && (re->generic.ob)) ponebuf = re->generic.ob->onebuf; - /* free any existing tile buffer */ - if (re->tb) evas_common_tilebuf_free(re->tb); + ob = evas_swapbuf_setup(info, epd->output.w, epd->output.h, + info->info.rotation, + info->info.depth, + info->info.destination_alpha, + info->info.wl_shm, + info->info.wl_surface); + if (!ob) return 0; - /* we have an existing output buffer, free it */ - if (re->ob) re->outbuf_free(re->ob); + evas_render_engine_software_generic_update(&re->generic, ob, epd->output.w, epd->output.h); - /* create new tile buffer */ - if ((re->tb = evas_common_tilebuf_new(epd->output.w, epd->output.h))) - evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); - - if ((re->ob = evas_swapbuf_setup(epd->output.w, epd->output.h, - info->info.rotation, - info->info.depth, - info->info.destination_alpha, - info->info.wl_shm, - info->info.wl_surface))) - { - re->outbuf_free = evas_swapbuf_free; - re->outbuf_reconfigure = evas_swapbuf_reconfigure; - re->outbuf_update_region_new = evas_swapbuf_update_region_new; - re->outbuf_update_region_push = evas_swapbuf_update_region_push; - re->outbuf_update_region_free = evas_swapbuf_update_region_free; - re->outbuf_flush = evas_swapbuf_flush; - re->outbuf_idle_flush = evas_swapbuf_idle_flush; - } - - re->info = info; - if ((re) && (re->ob)) re->ob->onebuf = ponebuf; + if ((re) && (re->generic.ob)) re->generic.ob->onebuf = ponebuf; } /* reassign render engine to output */ @@ -293,33 +187,20 @@ eng_setup(Evas *eo_evas, void *einfo) return 1; } -static void +static void eng_output_free(void *data) { - Render_Engine *re; + Render_Engine *re = data; LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if ((re = data)) - { - re->outbuf_free(re->ob); - 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]); - free(re); - } + evas_render_engine_software_generic_clean(&re->generic); + free(re); evas_common_font_shutdown(); evas_common_image_shutdown(); } -static void +static void eng_output_resize(void *data, int w, int h) { Render_Engine *re; @@ -327,235 +208,33 @@ eng_output_resize(void *data, int w, int h) int dx = 0, dy = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); - if (!(re = (Render_Engine *)data)) return; - if (!(info = re->info)) return; + if (!(info = re->generic.ob->info)) return; if (info->info.edges & 4) { if ((info->info.rotation == 90) || (info->info.rotation == 270)) - dx = re->ob->h - h; + dx = re->generic.ob->h - h; else - dx = re->ob->w - w; + dx = re->generic.ob->w - w; } if (info->info.edges & 1) { if ((info->info.rotation == 90) || (info->info.rotation == 270)) - dy = re->ob->w - w; + dy = re->generic.ob->w - w; else - dy = re->ob->h - h; + dy = re->generic.ob->h - h; } - re->outbuf_reconfigure(re->ob, dx, dy, w, h, + re->outbuf_reconfigure(re->generic.ob, dx, dy, w, h, info->info.rotation, info->info.depth, info->info.destination_alpha); - 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; - - 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; - - if (!(re = (Render_Engine *)data)) return; - 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; - - 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; - - if (!(re = (Render_Engine *)data)) return; - if (re->tb) 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; - Eina_Bool first_rect = EINA_FALSE; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - -#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) - - re = (Render_Engine *)data; - if (re->end) - { - re->end = 0; - return NULL; - } - - if (!re->rects) - { - re->mode = evas_swapbuf_state_get(re->ob); - re->rects = evas_common_tilebuf_get_render_rects(re->tb); - if (re->rects) - { - if ((re->lost_back) || (re->mode == MODE_FULL)) - { - /* if we lost our backbuffer since the last frame redraw all */ - re->lost_back = 0; - 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); - } - /* ensure we get rid of previous rect lists we dont need if mode - * changed/is appropriate */ - 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: // no prev rects needed - re->rects = - _merge_rects(re->tb, re->prev_rects[0], NULL, NULL); - break; - case MODE_DOUBLE: // double mode - only 1 level of prev rect - re->rects = - _merge_rects(re->tb, re->prev_rects[0], re->prev_rects[1], NULL); - break; - case MODE_TRIPLE: // keep all - re->rects = - _merge_rects(re->tb, re->prev_rects[0], re->prev_rects[1], re->prev_rects[2]); - break; - default: - break; - } - first_rect = EINA_TRUE; - } - 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; - } - if (first_rect) - { - // do anything needed for the first frame - } - surface = - re->outbuf_update_region_new(re->ob, - *x, *y, *w, *h, - cx, cy, cw, ch); - if (!re->cur_rect) re->end = EINA_TRUE; - return surface; - } - - return NULL; -} - -static void -eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - 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(surface); -#endif - re->outbuf_update_region_push(re->ob, surface, x, y, w, h); - re->outbuf_update_region_free(re->ob, surface); - evas_common_cpu_end_opt(); -} - -static void -eng_output_flush(void *data, Evas_Render_Mode render_mode) -{ - Render_Engine *re; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; - - if (!(re = (Render_Engine *)data)) return; - re->outbuf_flush(re->ob); - if (re->rects) - { - evas_common_tilebuf_free_render_rects(re->rects); - re->rects = NULL; - } -} - -static void -eng_output_idle_flush(void *data) -{ - Render_Engine *re; - - LOGFN(__FILE__, __LINE__, __FUNCTION__); - - if (!(re = (Render_Engine *)data)) return; - re->outbuf_idle_flush(re->ob); + evas_common_tilebuf_free(re->generic.tb); + if ((re->generic.tb = evas_common_tilebuf_new(w, h))) + evas_common_tilebuf_set_tile_size(re->generic.tb, TILESIZE, TILESIZE); } /* module functions */ @@ -591,14 +270,6 @@ module_open(Evas_Module *em) ORD(setup); 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); /* advertise out our own api */ em->functions = (void *)(&func); diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.h b/src/modules/evas/engines/wayland_shm/evas_engine.h index 1abae01523..73095968a6 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.h +++ b/src/modules/evas/engines/wayland_shm/evas_engine.h @@ -39,31 +39,20 @@ extern int _evas_engine_way_shm_log_dom; # include -typedef enum _Outbuf_Depth Outbuf_Depth; +#include "Evas_Engine_Wayland_Shm.h" + +#include "../software_generic/Evas_Engine_Software_Generic.h" + typedef struct _Outbuf Outbuf; -enum _Outbuf_Depth -{ - OUTBUF_DEPTH_NONE, - OUTBUF_DEPTH_ARGB_32BPP_8888_8888, - OUTBUF_DEPTH_RGB_32BPP_8888_8888, - OUTBUF_DEPTH_LAST -}; - -enum -{ - MODE_FULL, - MODE_COPY, - MODE_DOUBLE, - MODE_TRIPLE -}; - struct _Outbuf { + Evas_Engine_Info_Wayland_Shm *info; + int w, h; - unsigned int rotation; - Outbuf_Depth depth; + int rotation; int onebuf; + Outbuf_Depth depth; struct { diff --git a/src/modules/evas/engines/wayland_shm/evas_swapbuf.c b/src/modules/evas/engines/wayland_shm/evas_swapbuf.c index 56ff4a3c4e..835ec52f9f 100644 --- a/src/modules/evas/engines/wayland_shm/evas_swapbuf.c +++ b/src/modules/evas/engines/wayland_shm/evas_swapbuf.c @@ -21,7 +21,7 @@ /* local function prototypes */ Outbuf * -evas_swapbuf_setup(int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface) +evas_swapbuf_setup(Evas_Engine_Info_Wayland_Shm *info, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface) { Outbuf *ob = NULL; @@ -39,6 +39,7 @@ evas_swapbuf_setup(int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina ob->priv.destination_alpha = alpha; ob->priv.wl.shm = wl_shm; ob->priv.wl.surface = wl_surface; + ob->info = info; if ((ob->rotation == 0) || (ob->rotation == 180)) { @@ -78,7 +79,7 @@ evas_swapbuf_free(Outbuf *ob) if (!ob) return; /* flush the output buffer */ - evas_swapbuf_flush(ob); + evas_swapbuf_flush(ob, NULL, MODE_FULL); evas_swapbuf_idle_flush(ob); evas_swapper_free(ob->priv.swapper); eina_array_flush(&ob->priv.onebuf_regions); @@ -88,7 +89,7 @@ evas_swapbuf_free(Outbuf *ob) } void -evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha) +evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rotation, Outbuf_Depth depth, Eina_Bool alpha) { LOGFN(__FILE__, __LINE__, __FUNCTION__); @@ -136,7 +137,7 @@ evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, unsigned int ro } } -RGBA_Image * +void * evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) { RGBA_Image *img; @@ -374,14 +375,16 @@ evas_swapbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_ } void -evas_swapbuf_flush(Outbuf *ob) +evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode) { - Eina_Rectangle *rects; + Eina_Rectangle *result; RGBA_Image *img; unsigned int n = 0, i = 0; LOGFN(__FILE__, __LINE__, __FUNCTION__); + if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; + /* check for valid output buffer */ if (!ob) return; @@ -396,17 +399,17 @@ evas_swapbuf_flush(Outbuf *ob) if (n == 0) return; /* allocate rectangles */ - if (!(rects = alloca(n * sizeof(Eina_Rectangle)))) return; + if (!(result = alloca(n * sizeof(Eina_Rectangle)))) return; - /* loop the buffer regions and assign to rects */ + /* loop the buffer regions and assign to result */ EINA_ARRAY_ITER_NEXT(&ob->priv.onebuf_regions, i, rect, it) - rects[i] = *rect; + result[i] = *rect; /* unmap the buffer */ evas_swapper_buffer_unmap(ob->priv.swapper); /* force a buffer swap */ - evas_swapper_swap(ob->priv.swapper, rects, n); + evas_swapper_swap(ob->priv.swapper, result, n); /* clean array */ eina_array_clean(&ob->priv.onebuf_regions); @@ -430,7 +433,7 @@ evas_swapbuf_flush(Outbuf *ob) if (n == 0) return; /* allocate rectangles */ - if (!(rects = alloca(n * sizeof(Eina_Rectangle)))) return; + if (!(result = alloca(n * sizeof(Eina_Rectangle)))) return; /* loop the pending writes */ EINA_LIST_FREE(ob->priv.pending_writes, img) @@ -445,35 +448,35 @@ evas_swapbuf_flush(Outbuf *ob) /* based on rotation, set rectangle position */ if (ob->rotation == 0) { - rects[i].x = x; - rects[i].y = y; + result[i].x = x; + result[i].y = y; } else if (ob->rotation == 90) { - rects[i].x = y; - rects[i].y = (ob->w - x - w); + result[i].x = y; + result[i].y = (ob->w - x - w); } else if (ob->rotation == 180) { - rects[i].x = (ob->w - x - w); - rects[i].y = (ob->h - y - h); + result[i].x = (ob->w - x - w); + result[i].y = (ob->h - y - h); } else if (ob->rotation == 270) { - rects[i].x = (ob->h - y - h); - rects[i].y = x; + result[i].x = (ob->h - y - h); + result[i].y = x; } /* based on rotation, set rectangle size */ if ((ob->rotation == 0) || (ob->rotation == 180)) { - rects[i].w = w; - rects[i].h = h; + result[i].w = w; + result[i].h = h; } else if ((ob->rotation == 90) || (ob->rotation == 270)) { - rects[i].w = h; - rects[i].h = w; + result[i].w = h; + result[i].h = w; } eina_rectangle_free(rect); @@ -492,7 +495,7 @@ evas_swapbuf_flush(Outbuf *ob) evas_swapper_buffer_unmap(ob->priv.swapper); /* force a buffer swap */ - evas_swapper_swap(ob->priv.swapper, rects, n); + evas_swapper_swap(ob->priv.swapper, result, n); } } @@ -511,7 +514,7 @@ evas_swapbuf_idle_flush(Outbuf *ob EINA_UNUSED) /* evas_swapper_buffer_idle_flush(ob->priv.swapper); */ } -int +Render_Engine_Swap_Mode evas_swapbuf_state_get(Outbuf *ob) { int mode = 0; @@ -523,4 +526,10 @@ evas_swapbuf_state_get(Outbuf *ob) return mode; } +int +evas_swapbuf_rotation_get(Outbuf *ob) +{ + return ob->rotation; +} + /* local functions */ diff --git a/src/modules/evas/engines/wayland_shm/evas_swapbuf.h b/src/modules/evas/engines/wayland_shm/evas_swapbuf.h index cc895f6056..8716a37c29 100644 --- a/src/modules/evas/engines/wayland_shm/evas_swapbuf.h +++ b/src/modules/evas/engines/wayland_shm/evas_swapbuf.h @@ -3,14 +3,15 @@ # include "evas_engine.h" -Outbuf *evas_swapbuf_setup(int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface); +Outbuf *evas_swapbuf_setup(Evas_Engine_Info_Wayland_Shm *info, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface); void evas_swapbuf_free(Outbuf *ob); -void evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha); -RGBA_Image *evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); +void evas_swapbuf_reconfigure(Outbuf *ob, int x, int y, int w, int h, int rotation, Outbuf_Depth depth, Eina_Bool alpha); +void *evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); void evas_swapbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); void evas_swapbuf_update_region_free(Outbuf *ob, RGBA_Image *update); -void evas_swapbuf_flush(Outbuf *ob); +void evas_swapbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); void evas_swapbuf_idle_flush(Outbuf *ob EINA_UNUSED); -int evas_swapbuf_state_get(Outbuf *ob); +Render_Engine_Swap_Mode evas_swapbuf_state_get(Outbuf *ob); +int evas_swapbuf_rotation_get(Outbuf *ob); #endif