[mutter/gnome-3-36] clutter/stage: Use new paint API to implement capture()



commit d9d8732096792be0efd495d7373b25ec71386700
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Apr 28 18:13:23 2020 +0200

    clutter/stage: Use new paint API to implement capture()
    
    This changes the semantics a bit, e.g. we will never include the pointer
    cursor sprite, as there is no way to know whether the caller wants to or
    not.
    
    We also change things a bit so that when we render to an offscreen paint
    context, we don't emit the "paint" signal on actors, as doing so would
    end up recursing in gnome-shell's screenshot and screencast code.
    
    Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2567
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1222

 clutter/clutter/clutter-actor.c                 |  4 ++-
 clutter/clutter/clutter-paint-context-private.h |  1 +
 clutter/clutter/clutter-paint-context.c         |  3 +-
 clutter/clutter/clutter-stage.c                 | 45 ++++---------------------
 src/backends/meta-stage.c                       |  4 ++-
 5 files changed, 15 insertions(+), 42 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index b82d847a4..1cf09ac11 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -4194,7 +4194,9 @@ clutter_actor_continue_paint (ClutterActor        *self,
       clutter_paint_node_unref (dummy);
 
       /* XXX:2.0 - Call the paint() virtual directly */
-      if (g_signal_has_handler_pending (self, actor_signals[PAINT],
+      if (!(clutter_paint_context_get_paint_flags (paint_context) &
+            CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL) &&
+          g_signal_has_handler_pending (self, actor_signals[PAINT],
                                         0, TRUE))
         g_signal_emit (self, actor_signals[PAINT], 0, paint_context);
       else
diff --git a/clutter/clutter/clutter-paint-context-private.h b/clutter/clutter/clutter-paint-context-private.h
index 4cc72043e..132238cb9 100644
--- a/clutter/clutter/clutter-paint-context-private.h
+++ b/clutter/clutter/clutter-paint-context-private.h
@@ -24,6 +24,7 @@ typedef enum _ClutterPaintFlag
 {
   CLUTTER_PAINT_FLAG_NONE = 0,
   CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
+  CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 0,
 } ClutterPaintFlag;
 
 ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView     *view,
diff --git a/clutter/clutter/clutter-paint-context.c b/clutter/clutter/clutter-paint-context.c
index fc519c058..6787a5b5c 100644
--- a/clutter/clutter/clutter-paint-context.c
+++ b/clutter/clutter/clutter-paint-context.c
@@ -66,7 +66,8 @@ clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer)
 
   paint_context = g_new0 (ClutterPaintContext, 1);
   g_ref_count_init (&paint_context->ref_count);
-  paint_context->paint_flags = CLUTTER_PAINT_FLAG_NO_CURSORS;
+  paint_context->paint_flags = (CLUTTER_PAINT_FLAG_NO_CURSORS |
+                                CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL);
 
   clutter_paint_context_push_framebuffer (paint_context, framebuffer);
 
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 92f3dd759..82565c6b5 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -4575,50 +4575,17 @@ capture_view_into (ClutterStage          *stage,
                    uint8_t               *data,
                    int                    stride)
 {
-  CoglFramebuffer *framebuffer;
-  ClutterBackend *backend;
-  CoglContext *context;
-  CoglBitmap *bitmap;
-  cairo_rectangle_int_t view_layout;
+  g_autoptr (GError) error = NULL;
   float view_scale;
-  float texture_width;
-  float texture_height;
 
   g_return_if_fail (CLUTTER_IS_STAGE (stage));
 
-  framebuffer = clutter_stage_view_get_framebuffer (view);
-
-  if (paint)
-    {
-      cairo_region_t *region;
-
-      _clutter_stage_maybe_setup_viewport (stage, view);
-      region = cairo_region_create_rectangle (rect);
-      clutter_stage_do_paint_view (stage, view, region);
-      cairo_region_destroy (region);
-    }
-
   view_scale = clutter_stage_view_get_scale (view);
-  texture_width = roundf (rect->width * view_scale);
-  texture_height = roundf (rect->height * view_scale);
-
-  backend = clutter_get_default_backend ();
-  context = clutter_backend_get_cogl_context (backend);
-  bitmap = cogl_bitmap_new_for_data (context,
-                                     texture_width, texture_height,
-                                     CLUTTER_CAIRO_FORMAT_ARGB32,
-                                     stride,
-                                     data);
-
-  clutter_stage_view_get_layout (view, &view_layout);
-
-  cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
-                                            roundf ((rect->x - view_layout.x) * view_scale),
-                                            roundf ((rect->y - view_layout.y) * view_scale),
-                                            COGL_READ_PIXELS_COLOR_BUFFER,
-                                            bitmap);
-
-  cogl_object_unref (bitmap);
+  if (!clutter_stage_paint_to_buffer (stage, rect, view_scale, data, stride,
+                                      CLUTTER_CAIRO_FORMAT_ARGB32,
+                                      CLUTTER_PAINT_FLAG_NO_CURSORS,
+                                      &error))
+    g_warning ("Failed to capture stage: %s", error->message);
 }
 
 void
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
index 43b0ecb2a..3f7dd55ca 100644
--- a/src/backends/meta-stage.c
+++ b/src/backends/meta-stage.c
@@ -204,7 +204,9 @@ meta_stage_paint (ClutterActor        *actor,
                                 META_STAGE_WATCH_AFTER_ACTOR_PAINT);
     }
 
-  g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
+  if (!(clutter_paint_context_get_paint_flags (paint_context) &
+        CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL))
+    g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
 
   if (!(clutter_paint_context_get_paint_flags (paint_context) &
         CLUTTER_PAINT_FLAG_NO_CURSORS))


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