diff --git a/src/modules/evas/engines/gl_x11/Evas_Engine_GL_X11.h b/src/modules/evas/engines/gl_x11/Evas_Engine_GL_X11.h index 04e1c4c82d..e66539e021 100644 --- a/src/modules/evas/engines/gl_x11/Evas_Engine_GL_X11.h +++ b/src/modules/evas/engines/gl_x11/Evas_Engine_GL_X11.h @@ -8,11 +8,12 @@ typedef struct _Evas_Engine_Info_GL_X11 Evas_Engine_Info_GL_X11; typedef enum _Evas_Engine_Info_GL_X11_Swap_Mode { - EVAS_ENGINE_GL_X11_SWAP_MODE_AUTO = 0, - EVAS_ENGINE_GL_X11_SWAP_MODE_FULL = 1, - EVAS_ENGINE_GL_X11_SWAP_MODE_COPY = 2, - EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE = 3, - EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE = 4 + EVAS_ENGINE_GL_X11_SWAP_MODE_AUTO = 0, + EVAS_ENGINE_GL_X11_SWAP_MODE_FULL = 1, + EVAS_ENGINE_GL_X11_SWAP_MODE_COPY = 2, + EVAS_ENGINE_GL_X11_SWAP_MODE_DOUBLE = 3, + EVAS_ENGINE_GL_X11_SWAP_MODE_TRIPLE = 4, + EVAS_ENGINE_GL_X11_SWAP_MODE_QUADRUPLE = 5 } Evas_Engine_Info_GL_X11_Swap_Mode; struct _Evas_Engine_Info_GL_X11 diff --git a/src/modules/evas/engines/gl_x11/evas_engine.c b/src/modules/evas/engines/gl_x11/evas_engine.c index fffa16fd11..1419d163cd 100644 --- a/src/modules/evas/engines/gl_x11/evas_engine.c +++ b/src/modules/evas/engines/gl_x11/evas_engine.c @@ -37,7 +37,8 @@ enum { MODE_FULL, MODE_COPY, MODE_DOUBLE, - MODE_TRIPLE + MODE_TRIPLE, + MODE_QUADRUPLE }; typedef struct _Render_Engine Render_Engine; @@ -45,7 +46,7 @@ typedef struct _Render_Engine Render_Engine; struct _Render_Engine { Tilebuf_Rect *rects; - Tilebuf_Rect *rects_prev[3]; + Tilebuf_Rect *rects_prev[4]; Eina_Inlist *cur_rect; Evas_GL_X11_Window *win; @@ -988,6 +989,10 @@ eng_setup(Evas *eo_e, void *in) (!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 { @@ -1017,6 +1022,9 @@ eng_setup(Evas *eo_e, void *in) 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; } @@ -1105,6 +1113,7 @@ eng_output_free(void *data) 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]); free(re); @@ -1177,7 +1186,7 @@ eng_output_redraws_clear(void *data) } static Tilebuf_Rect * -_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3) +_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, Tilebuf_Rect *r4) { Tilebuf_Rect *r, *rects; Evas_Point p1, p2; @@ -1203,6 +1212,13 @@ _merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3) 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) @@ -1348,6 +1364,7 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i 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; @@ -1364,7 +1381,8 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i /* 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); + 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; @@ -1373,13 +1391,16 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i { case MODE_FULL: case MODE_COPY: // no prev rects needed - re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL); + 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); + re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL); break; - case MODE_TRIPLE: // keep all - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2]); + 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; @@ -1398,6 +1419,7 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i case MODE_COPY: case MODE_DOUBLE: case MODE_TRIPLE: + case MODE_QUADRUPLE: rect = (Tilebuf_Rect *)re->cur_rect; *x = rect->x; *y = rect->y; diff --git a/src/modules/evas/engines/software_x11/evas_engine.c b/src/modules/evas/engines/software_x11/evas_engine.c index 4a1bf4b45b..8ae0d4d1c0 100644 --- a/src/modules/evas/engines/software_x11/evas_engine.c +++ b/src/modules/evas/engines/software_x11/evas_engine.c @@ -33,7 +33,7 @@ struct _Render_Engine Tilebuf *tb; Outbuf *ob; Tilebuf_Rect *rects; - Tilebuf_Rect *rects_prev[3]; + Tilebuf_Rect *rects_prev[4]; Eina_Inlist *cur_rect; short mode; unsigned char end : 1; @@ -643,6 +643,7 @@ eng_output_free(void *data) 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]); #ifdef BUILD_ENGINE_SOFTWARE_XLIB _output_egl_shutdown(re); #endif @@ -704,7 +705,7 @@ eng_output_redraws_clear(void *data) } static Tilebuf_Rect * -_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3) +_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3, Tilebuf_Rect *r4) { Tilebuf_Rect *r, *rects; // int px1, py1, px2, py2; @@ -730,6 +731,15 @@ _merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3) 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); /* // bounding box -> make a bounding box single region update of all regions. @@ -807,7 +817,8 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i /* 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); + 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; @@ -816,13 +827,16 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i { case MODE_FULL: case MODE_COPY: // no prev rects needed - re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL); + 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); + re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL, NULL); break; - case MODE_TRIPLE: // keep all - re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2]); + 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; @@ -841,6 +855,7 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i case MODE_COPY: case MODE_DOUBLE: case MODE_TRIPLE: + case MODE_QUADRUPLE: rect = (Tilebuf_Rect *)re->cur_rect; *x = rect->x; *y = rect->y; diff --git a/src/modules/evas/engines/software_x11/evas_engine.h b/src/modules/evas/engines/software_x11/evas_engine.h index 4e91a1c278..e15a76e33a 100644 --- a/src/modules/evas/engines/software_x11/evas_engine.h +++ b/src/modules/evas/engines/software_x11/evas_engine.h @@ -64,7 +64,8 @@ enum { MODE_FULL, MODE_COPY, MODE_DOUBLE, - MODE_TRIPLE + MODE_TRIPLE, + MODE_QUADRUPLE }; typedef struct _Outbuf Outbuf; diff --git a/src/modules/evas/engines/software_x11/evas_xlib_swapper.c b/src/modules/evas/engines/software_x11/evas_xlib_swapper.c index fa7a9daf80..b1d26afaa3 100644 --- a/src/modules/evas/engines/software_x11/evas_xlib_swapper.c +++ b/src/modules/evas/engines/software_x11/evas_xlib_swapper.c @@ -832,11 +832,12 @@ evas_xlib_swapper_buffer_state_get(X_Swapper *swp) if (swap_debug) printf("Reuse changed - force FULL\n"); return MODE_FULL; } - if (swap_debug) printf("Swap state idx_reuse = %i (0=FULL, 1=COPY, 2=DOUBLE, 3=TRIPLE)\n", flags->data.idx_reuse); + if (swap_debug) printf("Swap state idx_reuse = %i (0=FULL, 1=COPY, 2=DOUBLE, 3=TRIPLE, 4=QUAD)\n", flags->data.idx_reuse); if (flags->data.idx_reuse == 0) return MODE_FULL; else if (flags->data.idx_reuse == 1) return MODE_COPY; else if (flags->data.idx_reuse == 2) return MODE_DOUBLE; else if (flags->data.idx_reuse == 3) return MODE_TRIPLE; + else if (flags->data.idx_reuse == 4) return MODE_QUADRUPLE; return MODE_FULL; }