[mutter] clutter/stage-view: Only blit the damage part of the shadow buffer



commit 8798325489e4eca5a275eccbf06c728eb67a6ab1
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Tue May 5 19:25:23 2020 +0200

    clutter/stage-view: Only blit the damage part of the shadow buffer
    
    This fixes the last "copy everything" paths when clutter doesn't
    directly paint onto the onscreen framebuffer. It adds a new hook into
    the stage view called before the swap buffer, as at this point, we have
    the swap buffer damag regions ready, which corresponds to the regions we
    must blit according to the damage reported to clutter.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1237

 clutter/clutter/clutter-stage-view-private.h |  3 +++
 clutter/clutter/clutter-stage-view.c         | 39 +++++++++++++++++++++++++---
 clutter/clutter/cogl/clutter-stage-cogl.c    |  2 ++
 3 files changed, 40 insertions(+), 4 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage-view-private.h b/clutter/clutter/clutter-stage-view-private.h
index 0dfc4e94ee..36c52e8ad6 100644
--- a/clutter/clutter/clutter-stage-view-private.h
+++ b/clutter/clutter/clutter-stage-view-private.h
@@ -23,6 +23,9 @@
 void clutter_stage_view_after_paint (ClutterStageView *view,
                                      cairo_region_t   *redraw_clip);
 
+void clutter_stage_view_before_swap_buffer (ClutterStageView     *view,
+                                            const cairo_region_t *swap_region);
+
 gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
 
 void clutter_stage_view_invalidate_viewport (ClutterStageView *view);
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index 9a1f0c5c82..ac75e8dcdd 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -370,11 +370,22 @@ clutter_stage_view_after_paint (ClutterStageView *view,
                                          redraw_clip);
         }
     }
+}
+
+void
+clutter_stage_view_before_swap_buffer (ClutterStageView     *view,
+                                       const cairo_region_t *swap_region)
+{
+  ClutterStageViewPrivate *priv =
+    clutter_stage_view_get_instance_private (view);
+  g_autoptr (GError) error = NULL;
 
-  if (priv->shadow.framebuffer)
+  if (!priv->shadow.framebuffer)
+    return;
+
+  if (cairo_region_is_empty (swap_region))
     {
       int width, height;
-      g_autoptr (GError) error = NULL;
 
       width = cogl_framebuffer_get_width (priv->framebuffer);
       height = cogl_framebuffer_get_height (priv->framebuffer);
@@ -384,9 +395,29 @@ clutter_stage_view_after_paint (ClutterStageView *view,
                                   0, 0,
                                   width, height,
                                   &error))
+        g_warning ("Failed to blit shadow buffer: %s", error->message);
+    }
+  else
+    {
+      int n_rects;
+      int i;
+
+      n_rects = cairo_region_num_rectangles (swap_region);
+      for (i = 0; i < n_rects; i++)
         {
-          g_warning ("Failed to blit shadow buffer: %s", error->message);
-          return;
+          cairo_rectangle_int_t rect;
+
+          cairo_region_get_rectangle (swap_region, i, &rect);
+          if (!cogl_blit_framebuffer (priv->shadow.framebuffer,
+                                      priv->framebuffer,
+                                      rect.x, rect.y,
+                                      rect.x, rect.y,
+                                      rect.width, rect.height,
+                                      &error))
+            {
+              g_warning ("Failed to blit shadow buffer: %s", error->message);
+              return;
+            }
         }
     }
 }
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 042621448c..2e2086c813 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -379,6 +379,8 @@ swap_framebuffer (ClutterStageWindow *stage_window,
 {
   CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (view);
 
+  clutter_stage_view_before_swap_buffer (view, swap_region);
+
   if (cogl_is_onscreen (framebuffer))
     {
       CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);


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