[mutter] clutter: Pass redraw clip via paint context



commit fe1ccea1e1cb90e2110fe9c7d2f856154adc903f
Author: Jonas Ådahl <jadahl gmail com>
Date:   Thu Feb 6 10:04:49 2020 +0100

    clutter: Pass redraw clip via paint context
    
    Instead of users fetching it via `clutter_stage_get_redraw_clip()`, pass
    it via the paint context. This is helpful as it is only valid during a
    paint, making it more obvious that it needs to be handled differently
    when there is no redraw clip (i.e. we're painting off-screen).
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042

 clutter/clutter/clutter-paint-context-private.h |  3 ++-
 clutter/clutter/clutter-paint-context.c         | 13 +++++++++-
 clutter/clutter/clutter-paint-context.h         |  3 +++
 clutter/clutter/clutter-stage.c                 | 22 +----------------
 clutter/clutter/clutter-stage.h                 |  2 --
 src/compositor/meta-window-group.c              | 32 +++++++++++++++----------
 6 files changed, 37 insertions(+), 38 deletions(-)
---
diff --git a/clutter/clutter/clutter-paint-context-private.h b/clutter/clutter/clutter-paint-context-private.h
index 6d2f0e92c..a825c8ffd 100644
--- a/clutter/clutter/clutter-paint-context-private.h
+++ b/clutter/clutter/clutter-paint-context-private.h
@@ -20,7 +20,8 @@
 
 #include "clutter-paint-context.h"
 
-ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view);
+ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView     *view,
+                                                          const cairo_region_t *redraw_clip);
 
 gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context);
 
diff --git a/clutter/clutter/clutter-paint-context.c b/clutter/clutter/clutter-paint-context.c
index 1787435de..d0d334951 100644
--- a/clutter/clutter/clutter-paint-context.c
+++ b/clutter/clutter/clutter-paint-context.c
@@ -26,6 +26,8 @@ struct _ClutterPaintContext
   GList *framebuffers;
 
   ClutterStageView *view;
+
+  cairo_region_t *redraw_clip;
 };
 
 G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
@@ -33,7 +35,8 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
                      clutter_paint_context_unref)
 
 ClutterPaintContext *
-clutter_paint_context_new_for_view (ClutterStageView *view)
+clutter_paint_context_new_for_view (ClutterStageView     *view,
+                                    const cairo_region_t *redraw_clip)
 {
   ClutterPaintContext *paint_context;
   CoglFramebuffer *framebuffer;
@@ -41,6 +44,7 @@ clutter_paint_context_new_for_view (ClutterStageView *view)
   paint_context = g_new0 (ClutterPaintContext, 1);
   g_ref_count_init (&paint_context->ref_count);
   paint_context->view = view;
+  paint_context->redraw_clip = cairo_region_copy (redraw_clip);
 
   framebuffer = clutter_stage_view_get_framebuffer (view);
   clutter_paint_context_push_framebuffer (paint_context, framebuffer);
@@ -77,6 +81,7 @@ clutter_paint_context_dispose (ClutterPaintContext *paint_context)
   g_list_free_full (paint_context->framebuffers,
                     cogl_object_unref);
   paint_context->framebuffers = NULL;
+  g_clear_pointer (&paint_context->redraw_clip, cairo_region_destroy);
 }
 
 void
@@ -115,6 +120,12 @@ clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context)
                         paint_context->framebuffers);
 }
 
+const cairo_region_t *
+clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context)
+{
+  return paint_context->redraw_clip;
+}
+
 /**
  * clutter_paint_context_get_framebuffer:
  * @paint_context: The #ClutterPaintContext
diff --git a/clutter/clutter/clutter-paint-context.h b/clutter/clutter/clutter-paint-context.h
index 59ce0fa45..c54f95c03 100644
--- a/clutter/clutter/clutter-paint-context.h
+++ b/clutter/clutter/clutter-paint-context.h
@@ -59,4 +59,7 @@ void clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context,
 CLUTTER_EXPORT
 void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context);
 
+CLUTTER_EXPORT
+const cairo_region_t * clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context);
+
 #endif /* CLUTTER_PAINT_CONTEXT_H */
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 24930df70..ff7fed3bc 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -908,7 +908,7 @@ clutter_stage_do_paint_view (ClutterStage         *stage,
   ClutterPaintContext *paint_context;
   cairo_rectangle_int_t clip_rect;
 
-  paint_context = clutter_paint_context_new_for_view (view);
+  paint_context = clutter_paint_context_new_for_view (view, redraw_clip);
 
   cairo_region_get_extents (redraw_clip, &clip_rect);
   setup_view_for_pick_or_paint (stage, view, &clip_rect);
@@ -1631,26 +1631,6 @@ _clutter_stage_has_full_redraw_queued (ClutterStage *stage)
     return FALSE;
 }
 
-cairo_region_t *
-clutter_stage_get_redraw_clip (ClutterStage *stage)
-{
-  ClutterStagePrivate *priv;
-  cairo_rectangle_int_t clip;
-  cairo_region_t *region;
-
-  g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
-
-  priv = stage->priv;
-
-  region = _clutter_stage_window_get_redraw_clip (priv->impl);
-  if (region)
-    return region;
-
-  /* Set clip to the full extents of the stage */
-  _clutter_stage_window_get_geometry (priv->impl, &clip);
-  return cairo_region_create_rectangle (&clip);
-}
-
 static ClutterActor *
 _clutter_stage_do_pick_on_view (ClutterStage     *stage,
                                 float             x,
diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h
index 11f2e8716..f60bb3a8c 100644
--- a/clutter/clutter/clutter-stage.h
+++ b/clutter/clutter/clutter-stage.h
@@ -206,8 +206,6 @@ guchar *        clutter_stage_read_pixels                       (ClutterStage
                                                                  gint                   width,
                                                                  gint                   height);
 
-CLUTTER_EXPORT
-cairo_region_t * clutter_stage_get_redraw_clip                  (ClutterStage          *stage);
 CLUTTER_EXPORT
 void            clutter_stage_ensure_viewport                   (ClutterStage          *stage);
 CLUTTER_EXPORT
diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c
index cca22b87d..49eb72b85 100644
--- a/src/compositor/meta-window-group.c
+++ b/src/compositor/meta-window-group.c
@@ -55,14 +55,23 @@ static void
 meta_window_group_paint (ClutterActor        *actor,
                          ClutterPaintContext *paint_context)
 {
+  MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
+  ClutterActorClass *parent_actor_class =
+    CLUTTER_ACTOR_CLASS (meta_window_group_parent_class);
+  ClutterActor *stage = clutter_actor_get_stage (actor);
+  const cairo_region_t *redraw_clip;
   cairo_region_t *clip_region;
   cairo_region_t *unobscured_region;
   cairo_rectangle_int_t visible_rect;
   int paint_x_origin, paint_y_origin;
   int screen_width, screen_height;
 
-  MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
-  ClutterActor *stage = clutter_actor_get_stage (actor);
+  redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
+  if (!redraw_clip)
+    {
+      parent_actor_class->paint (actor, paint_context);
+      return;
+    }
 
   meta_display_get_size (window_group->display, &screen_width, &screen_height);
 
@@ -91,8 +100,7 @@ meta_window_group_paint (ClutterActor        *actor,
                                               &paint_y_origin) ||
           !meta_cullable_is_untransformed (META_CULLABLE (actor)))
         {
-          CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor,
-                                                                       paint_context);
+          parent_actor_class->paint (actor, paint_context);
           return;
         }
     }
@@ -108,13 +116,12 @@ meta_window_group_paint (ClutterActor        *actor,
 
   unobscured_region = cairo_region_create_rectangle (&visible_rect);
 
-  /* Get the clipped redraw bounds from Clutter so that we can avoid
-   * painting shadows on windows that don't need to be painted in this
-   * frame. In the case of a multihead setup with mismatched monitor
-   * sizes, we could intersect this with an accurate union of the
-   * monitors to avoid painting shadows that are visible only in the
-   * holes. */
-  clip_region = clutter_stage_get_redraw_clip (CLUTTER_STAGE (stage));
+  /* Get the clipped redraw bounds so that we can avoid painting shadows on
+   * windows that don't need to be painted in this frame. In the case of a
+   * multihead setup with mismatched monitor sizes, we could intersect this
+   * with an accurate union of the monitors to avoid painting shadows that are
+   * visible only in the holes. */
+  clip_region = cairo_region_copy (redraw_clip);
 
   cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin);
 
@@ -123,8 +130,7 @@ meta_window_group_paint (ClutterActor        *actor,
   cairo_region_destroy (unobscured_region);
   cairo_region_destroy (clip_region);
 
-  CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor,
-                                                               paint_context);
+  parent_actor_class->paint (actor, paint_context);
 
   meta_cullable_reset_culling (META_CULLABLE (window_group));
 }


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