Add quadruple swap mode for partial rendering
authorWonsik Jung <sidein@samsung.com>
Sat, 8 Feb 2014 14:04:04 +0000 (23:04 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Sat, 8 Feb 2014 14:04:04 +0000 (23:04 +0900)
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

src/modules/evas/engines/gl_x11/Evas_Engine_GL_X11.h
src/modules/evas/engines/gl_x11/evas_engine.c
src/modules/evas/engines/software_x11/evas_engine.c
src/modules/evas/engines/software_x11/evas_engine.h
src/modules/evas/engines/software_x11/evas_xlib_swapper.c

index 04e1c4c..e66539e 100644 (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
index fffa16f..1419d16 100644 (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: // 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_TRIPLE: // keep all
-                  re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2]);
+                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;
index 4a1bf4b..8ae0d4d 100644 (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: // 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_TRIPLE: // keep all
-                  re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2]);
+                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;
index 4e91a1c..e15a76e 100644 (file)
@@ -64,7 +64,8 @@ enum {
    MODE_FULL,
    MODE_COPY,
    MODE_DOUBLE,
-   MODE_TRIPLE
+   MODE_TRIPLE,
+   MODE_QUADRUPLE
 };
 
 typedef struct _Outbuf Outbuf;
index fa7a9da..b1d26af 100644 (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;
 }