pepper: View bounding, opaque and surface damage region processing.
authorTaekyun Kim <tkq.kim@samsung.com>
Tue, 30 Jun 2015 05:37:32 +0000 (14:37 +0900)
committerTaekyun Kim <tkq.kim@samsung.com>
Tue, 7 Jul 2015 06:56:51 +0000 (15:56 +0900)
Change-Id: Ic033ae5babe85f92b8b33649baa63173c6b61d62

pepper/src/view.c

index 0f082ad..80c7ce0 100644 (file)
@@ -412,22 +412,56 @@ pepper_view_get_visible_region(pepper_object_t *v)
     return &view->visible_region;
 }
 
-static void
-view_update_bounding_region(pepper_view_t *view)
+static inline void
+add_bbox_point(double *box, int x, int y, const pepper_mat4_t *matrix)
 {
-    /* TODO: */
+    pepper_vec2_t v = { x, y };
+
+    pepper_mat4_transform_vec2(matrix, &v);
+
+    box[0] = PEPPER_MIN(box[0], v.x);
+    box[1] = PEPPER_MIN(box[1], v.y);
+    box[2] = PEPPER_MAX(box[2], v.x);
+    box[3] = PEPPER_MAX(box[3], v.y);
 }
 
-static void
-view_update_opaque_region(pepper_view_t *view)
+static inline void
+transform_bounding_box(pixman_box32_t *box, const pepper_mat4_t *matrix)
 {
-    /* TODO: */
+    double          b[4] = { HUGE_VAL, HUGE_VAL, -HUGE_VAL, -HUGE_VAL };
+
+    add_bbox_point(b, box->x1, box->y1, matrix);
+    add_bbox_point(b, box->x2, box->y1, matrix);
+    add_bbox_point(b, box->x2, box->y2, matrix);
+    add_bbox_point(b, box->x1, box->y2, matrix);
+
+    box->x1 = floor(b[0]);
+    box->y1 = floor(b[1]);
+    box->x2 = ceil(b[2]);
+    box->y2 = ceil(b[3]);
 }
 
-static void
-damage_region_transform(pixman_region32_t *region, const pepper_mat4_t *matrix)
+static inline void
+transform_region_bounding(pixman_region32_t *region, const pepper_mat4_t *matrix)
 {
-    /* TODO: */
+    pixman_region32_t   result;
+    pixman_box32_t     *rects;
+    int                 i, num_rects;
+
+    pixman_region32_init(&result);
+    rects = pixman_region32_rectangles(region, &num_rects);
+
+    for (i = 0; i < num_rects; i++)
+    {
+        pixman_box32_t box = rects[i];
+
+        transform_bounding_box(&box, matrix);
+        pixman_region32_union_rect(&result, &result,
+                                   box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1);
+    }
+
+    pixman_region32_copy(region, &result);
+    pixman_region32_fini(&result);
 }
 
 void
@@ -468,8 +502,19 @@ view_update_geometry(pepper_view_t *view)
             pepper_mat4_copy(&view->matrix_to_global, &view->matrix_to_parent);
         }
 
-        view_update_bounding_region(view);
-        view_update_opaque_region(view);
+        /* Bounding region. */
+        pixman_region32_init_rect(&view->bounding_region, 0, 0, view->w, view->h);
+        transform_region_bounding(&view->bounding_region, &view->matrix_to_global);
+
+        /* Opaque region. */
+        pixman_region32_init(&view->opaque_region);
+
+        if (view->surface && pepper_mat4_is_translation(&view->matrix_to_global))
+        {
+            pixman_region32_copy(&view->opaque_region, &view->surface->opaque_region);
+            pixman_region32_translate(&view->opaque_region,
+                                      view->matrix_to_global.m[3], view->matrix_to_global.m[7]);
+        }
 
         view->geometry_dirty = PEPPER_FALSE;
     }
@@ -514,7 +559,7 @@ pepper_compositor_update_views(pepper_compositor_t *compositor)
             pixman_region32_copy(&surface_damage, &view->surface->damage_region);
 
             /* Transform surface damage into global coordinate space. */
-            damage_region_transform(&surface_damage, &view->matrix_to_global);
+            transform_region_bounding(&surface_damage, &view->matrix_to_global);
 
             /* Clip surface damage with view's bounding region. */
             pixman_region32_intersect(&surface_damage, &surface_damage, &view->bounding_region);