evas/software_generic: Round up merged rect to tile size 95/123195/1
authorJoogab Yun <joogab.yun@samsung.com>
Thu, 23 Feb 2017 03:53:33 +0000 (12:53 +0900)
committerJoogab Yun <joogab.yun@samsung.com>
Wed, 5 Apr 2017 01:58:54 +0000 (10:58 +0900)
Summary:
For some drivers, there is a limitation for partial rects that only
multiples of tile size width/height are allowed.
Currently, rects are merged based on the current rotation, so when
the rects are calculated based on 0 rotation it does not meet the above
requirement.
Add a rect rounding up routine after _merge_rects such that the rect
is rounded up to tile size based on 0 rotation.

Change-Id: I0ac0208e383332158dc7c3fa9fa5012e37bcf797

src/modules/evas/engines/software_generic/evas_engine.c

index bee32d6..b23b77e 100644 (file)
@@ -3532,6 +3532,79 @@ _merge_rects(Render_Engine_Merge_Mode merge_mode,
 }
 
 
+static void
+_round_up_rect(Tilebuf *tb, Tilebuf_Rect *rect, int rot)
+{
+   int x1, x2, y1, y2;
+   int x, y, w, h;
+
+   if (rect == NULL)
+      return;
+
+   if (rot == 0 || rot == 180)
+      return;
+
+   // For 90 or 270 rotation, merged rect should be rounded up to tb->tile_size.w and tb->tile_size.h
+   // AFTER rotated to 0 rotation, then rotated back to original rotation
+
+   x = rect->x;
+   y = rect->y;
+   w = rect->w;
+   h = rect->h;
+
+   // STEP 1. rotate the merged rect to rotation 0
+   switch (rot)
+     {
+      case 90:
+        rect->x = y;
+        rect->y = tb->outbuf_w - (x + w);
+        rect->w = h;
+        rect->h = w;
+        break;
+      case 270:
+        rect->x = tb->outbuf_h - (y + h);
+        rect->y = x;
+        rect->w = h;
+        rect->h = w;
+        break;
+      default:
+        break;
+     }
+
+   // STEP 2. round up rects
+   x1 = rect->x;
+   x2 = x1 + rect->w;
+   y1 = rect->y;
+   y2 = y1 + rect->h;
+   x1 = tb->tile_size.w * (x1 / tb->tile_size.w);
+   y1 = tb->tile_size.h * (y1 / tb->tile_size.h);
+   x2 = tb->tile_size.w * ((x2 + tb->tile_size.w - 1) / tb->tile_size.w);
+   y2 = tb->tile_size.h * ((y2 + tb->tile_size.h - 1) / tb->tile_size.h);
+
+   x = x1; y = y1; w = x2 - x1; h = y2 - y1;
+   RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, tb->outbuf_h, tb->outbuf_w);
+
+   // STEP 3. rotate the rect back to original rotation
+   switch (rot)
+     {
+      case 90:
+        rect->x = tb->outbuf_w - (y + h);
+        rect->y = x;
+        rect->w = h;
+        rect->h = w;
+        break;
+      case 270:
+        rect->x = y;
+        rect->y = tb->outbuf_h - (x + w);
+        rect->w = h;
+        rect->h = w;
+        break;
+      default:
+        break;
+     }
+}
+
+
 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)
 {
@@ -3602,6 +3675,9 @@ eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, i
                 default:
                   break;
                }
+             if ((re->outbuf_get_rot(re->ob) == 90) ||
+                 (re->outbuf_get_rot(re->ob) == 270))
+               _round_up_rect(re->tb, re->rects, re->outbuf_get_rot(re->ob));
           }
         evas_common_tilebuf_clear(re->tb);
         re->cur_rect = EINA_INLIST_GET(re->rects);