Add quadruple swap mode for partial rendering

Summary: This patch is for QUADRUPLE window buffers.

Test Plan:
When enlightenment uses quadruple buffers or window system can support quadruple buffers,
application can use quadruple buffers with partial rendering

Reviewers: tasn, seoz, raster

Reviewed By: raster

CC: cedric

Differential Revision: https://phab.enlightenment.org/D527
This commit is contained in:
Wonsik Jung 2014-02-08 23:04:04 +09:00 committed by Carsten Haitzler (Rasterman)
parent 229ee74f6c
commit 0e04219758
5 changed files with 62 additions and 22 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -64,7 +64,8 @@ enum {
MODE_FULL,
MODE_COPY,
MODE_DOUBLE,
MODE_TRIPLE
MODE_TRIPLE,
MODE_QUADRUPLE
};
typedef struct _Outbuf Outbuf;

View File

@ -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;
}