[mutter/wip/carlosg/clip-regions: 1/7] ClutterStage: Use clutter_region_t for swap_region



commit b20a8f8c6367134e21f1afeb18c8a6fbda415fc2
Author: Robert Mader <robert mader posteo de>
Date:   Sat Jul 27 18:39:04 2019 +0200

    ClutterStage: Use clutter_region_t for swap_region
    
    We use `clutter_region_t` for the clip now, so lets also use it
    for the swap region.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/692

 clutter/clutter/cogl/clutter-stage-cogl.c | 172 +++++++++++++++++-------------
 1 file changed, 100 insertions(+), 72 deletions(-)
---
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 7bf951b9d..399417679 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -393,42 +393,50 @@ valid_buffer_age (ClutterStageViewCogl *view_cogl,
 }
 
 static void
-paint_damage_region (ClutterStageWindow    *stage_window,
-                     ClutterStageView      *view,
-                     cairo_rectangle_int_t *swap_region)
+paint_damage_region (ClutterStageWindow *stage_window,
+                     ClutterStageView   *view,
+                     cairo_region_t     *swap_region)
 {
   CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
   CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   static CoglPipeline *overlay_blue = NULL;
   ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
   ClutterActor *actor = CLUTTER_ACTOR (stage_cogl->wrapper);
-  float x_1 = swap_region->x;
-  float x_2 = swap_region->x + swap_region->width;
-  float y_1 = swap_region->y;
-  float y_2 = swap_region->y + swap_region->height;
   CoglMatrix modelview;
+  int n_rects, i;
 
+  cogl_framebuffer_push_matrix (framebuffer);
+  cogl_matrix_init_identity (&modelview);
+  _clutter_actor_apply_modelview_transform (actor, &modelview);
+  cogl_framebuffer_set_modelview_matrix (framebuffer, &modelview);
+
+  /* Blue for the swap region */
   if (G_UNLIKELY (overlay_blue == NULL))
     {
       overlay_blue = cogl_pipeline_new (ctx);
       cogl_pipeline_set_color4ub (overlay_blue, 0x00, 0x00, 0x33, 0x33);
     }
 
-  cogl_framebuffer_push_matrix (framebuffer);
-  cogl_matrix_init_identity (&modelview);
-  _clutter_actor_apply_modelview_transform (actor, &modelview);
-  cogl_framebuffer_set_modelview_matrix (framebuffer, &modelview);
+  n_rects = cairo_region_num_rectangles (swap_region);
+  for (i = 0; i < n_rects; i++)
+    {
+      cairo_rectangle_int_t rect;
+      float x_1, x_2, y_1, y_2;
 
-  /* Blue for the swap region */
-  cogl_framebuffer_draw_rectangle (framebuffer, overlay_blue, x_1, y_1, x_2, y_2);
+      cairo_region_get_rectangle (swap_region, i, &rect);
+      x_1 = rect.x;
+      x_2 = rect.x + rect.width;
+      y_1 = rect.y;
+      y_2 = rect.y + rect.height;
+
+      cogl_framebuffer_draw_rectangle (framebuffer, overlay_blue, x_1, y_1, x_2, y_2);
+    }
 
   /* Red for the clip */
   if (stage_cogl->initialized_redraw_clip &&
       stage_cogl->redraw_clip)
     {
       static CoglPipeline *overlay_red = NULL;
-      cairo_rectangle_int_t *rects;
-      int n_rects, i;
 
       if (G_UNLIKELY (overlay_red == NULL))
         {
@@ -439,11 +447,14 @@ paint_damage_region (ClutterStageWindow    *stage_window,
       n_rects = cairo_region_num_rectangles (stage_cogl->redraw_clip);
       for (i = 0; i < n_rects; i++)
         {
-          cairo_region_get_rectangle (stage_cogl->redraw_clip, i, &rects[i]);
-          x_1 = rects[i].x;
-          x_2 = rects[i].x + rects[i].width;
-          y_1 = rects[i].y;
-          y_2 = rects[i].y + rects[i].height;
+          cairo_rectangle_int_t rect;
+          float x_1, x_2, y_1, y_2;
+
+          cairo_region_get_rectangle (stage_cogl->redraw_clip, i, &rect);
+          x_1 = rect.x;
+          x_2 = rect.x + rect.width;
+          y_1 = rect.y;
+          y_2 = rect.y + rect.height;
 
           cogl_framebuffer_draw_rectangle (framebuffer, overlay_red, x_1, y_1, x_2, y_2);
         }
@@ -453,43 +464,44 @@ paint_damage_region (ClutterStageWindow    *stage_window,
 }
 
 static gboolean
-swap_framebuffer (ClutterStageWindow    *stage_window,
-                  ClutterStageView      *view,
-                  cairo_rectangle_int_t *swap_region,
-                  gboolean               swap_with_damage)
+swap_framebuffer (ClutterStageWindow *stage_window,
+                  ClutterStageView   *view,
+                  cairo_region_t     *swap_region,
+                  gboolean            swap_with_damage)
 {
   CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
-  int damage[4], ndamage;
-
-  damage[0] = swap_region->x;
-  damage[1] = swap_region->y;
-  damage[2] = swap_region->width;
-  damage[3] = swap_region->height;
-
-  if (swap_region->width != 0)
-    ndamage = 1;
-  else
-    ndamage = 0;
+  int *damage, n_rects, i;
 
   if (G_UNLIKELY ((clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION)))
     paint_damage_region (stage_window, view, swap_region);
 
+  n_rects = cairo_region_num_rectangles (swap_region);
+  damage = g_newa (int, n_rects * 4);
+  for (i = 0; i < n_rects; i++)
+    {
+      cairo_rectangle_int_t rect;
+
+      cairo_region_get_rectangle (swap_region, i, &rect);
+      damage[i * 4] = rect.x;
+      damage[i * 4 + 1] = rect.y;
+      damage[i * 4 + 2] = rect.width;
+      damage[i * 4 + 3] = rect.height;
+    }
+  cairo_region_destroy (swap_region);
+
   if (cogl_is_onscreen (framebuffer))
     {
       CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
 
       /* push on the screen */
-      if (ndamage == 1 && !swap_with_damage)
+      if (n_rects > 0 && !swap_with_damage)
         {
           CLUTTER_NOTE (BACKEND,
-                        "cogl_onscreen_swap_region (onscreen: %p, "
-                        "x: %d, y: %d, "
-                        "width: %d, height: %d)",
-                        onscreen,
-                        damage[0], damage[1], damage[2], damage[3]);
+                        "cogl_onscreen_swap_region (onscreen: %p)",
+                        onscreen);
 
           cogl_onscreen_swap_region (onscreen,
-                                     damage, ndamage);
+                                     damage, n_rects);
 
           return FALSE;
         }
@@ -499,7 +511,7 @@ swap_framebuffer (ClutterStageWindow    *stage_window,
                         onscreen);
 
           cogl_onscreen_swap_buffers_with_damage (onscreen,
-                                                  damage, ndamage);
+                                                  damage, n_rects);
 
           return TRUE;
         }
@@ -562,40 +574,52 @@ fill_current_damage_history_rectangle (ClutterStageView            *view,
   cairo_region_destroy (damage);
 }
 
-static void
-transform_swap_region_to_onscreen (ClutterStageView      *view,
-                                   cairo_rectangle_int_t *swap_region)
+static cairo_region_t *
+transform_swap_region_to_onscreen (ClutterStageView *view,
+                                   cairo_region_t   *swap_region)
 {
   CoglFramebuffer *framebuffer;
   cairo_rectangle_int_t layout;
-  gfloat x1, y1, x2, y2;
   gint width, height;
+  int n_rects, i;
+  cairo_rectangle_int_t *rects;
+  cairo_region_t *transformed_region;
 
   framebuffer = clutter_stage_view_get_onscreen (view);
   clutter_stage_view_get_layout (view, &layout);
 
-  x1 = (float) swap_region->x / layout.width;
-  y1 = (float) swap_region->y / layout.height;
-  x2 = (float) (swap_region->x + swap_region->width) / layout.width;
-  y2 = (float) (swap_region->y + swap_region->height) / layout.height;
-
-  clutter_stage_view_transform_to_onscreen (view, &x1, &y1);
-  clutter_stage_view_transform_to_onscreen (view, &x2, &y2);
-
   width = cogl_framebuffer_get_width (framebuffer);
   height = cogl_framebuffer_get_height (framebuffer);
 
-  x1 = floor (x1 * width);
-  y1 = floor (height - (y1 * height));
-  x2 = ceil (x2 * width);
-  y2 = ceil (height - (y2 * height));
-
-  *swap_region = (cairo_rectangle_int_t) {
-    .x = x1,
-    .y = y1,
-    .width = x2 - x1,
-    .height = y2 - y1
-  };
+  n_rects = cairo_region_num_rectangles (swap_region);
+  rects = g_newa (cairo_rectangle_int_t, n_rects);
+  for (i = 0; i < n_rects; i++)
+    {
+      gfloat x1, y1, x2, y2;
+
+      cairo_region_get_rectangle (swap_region, i, &rects[i]);
+
+      x1 = (float) rects[i].x / layout.width;
+      y1 = (float) rects[i].y / layout.height;
+      x2 = (float) (rects[i].x + rects[i].width) / layout.width;
+      y2 = (float) (rects[i].y + rects[i].height) / layout.height;
+
+      clutter_stage_view_transform_to_onscreen (view, &x1, &y1);
+      clutter_stage_view_transform_to_onscreen (view, &x2, &y2);
+
+      x1 = floor (x1 * width);
+      y1 = floor (height - (y1 * height));
+      x2 = ceil (x2 * width);
+      y2 = ceil (height - (y2 * height));
+
+      rects[i].x = x1;
+      rects[i].y = y1;
+      rects[i].width = x2 - x1;
+      rects[i].height = y2 - y1;
+    }
+  transformed_region = cairo_region_create_rectangles (rects, n_rects);
+
+  return transformed_region;
 }
 
 static void
@@ -661,7 +685,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
   ClutterActor *wrapper;
   cairo_region_t *redraw_clip;
   cairo_region_t *fb_clip_region;
-  cairo_rectangle_int_t swap_region;
+  cairo_region_t *swap_region;
   cairo_rectangle_int_t clip_rect;
   cairo_rectangle_int_t redraw_rect;
   gboolean clip_region_empty;
@@ -983,14 +1007,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
         }
       else
         {
-          cairo_region_get_extents (fb_clip_region, &swap_region);
-          g_assert (swap_region.width > 0);
+          swap_region = cairo_region_copy (fb_clip_region);
           do_swap_buffer = TRUE;
         }
     }
   else
     {
-      swap_region = (cairo_rectangle_int_t) { 0 };
+      swap_region = cairo_region_create ();
       do_swap_buffer = TRUE;
     }
 
@@ -1007,12 +1030,17 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
       if (clutter_stage_view_get_onscreen (view) !=
           clutter_stage_view_get_framebuffer (view))
         {
-          transform_swap_region_to_onscreen (view, &swap_region);
+          cairo_region_t *transformed_swap_region;
+
+          transformed_swap_region =
+            transform_swap_region_to_onscreen (view, swap_region);
+          cairo_region_destroy (swap_region);
+          swap_region = transformed_swap_region;
         }
 
       return swap_framebuffer (stage_window,
                                view,
-                               &swap_region,
+                               swap_region,
                                swap_with_damage);
     }
   else


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]