[mutter] window-actor: Factor out framebuffer creation of get_image()



commit 6bbb216f07f0175f692411786090fcacdbb60ef6
Author: Robert Mader <robert mader posteo de>
Date:   Sun Jun 6 14:28:48 2021 +0200

    window-actor: Factor out framebuffer creation of get_image()
    
    So we can reuse the code in the following commit.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1893>

 src/compositor/meta-window-actor.c | 164 ++++++++++++++++++++-----------------
 1 file changed, 91 insertions(+), 73 deletions(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index d4fc9a43a0..c284a6cd57 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1411,6 +1411,60 @@ meta_window_actor_notify_damaged (MetaWindowActor *window_actor)
   g_signal_emit (window_actor, signals[DAMAGED], 0);
 }
 
+static CoglFramebuffer *
+create_framebuffer_from_window_actor (MetaWindowActor  *self,
+                                      MetaRectangle    *clip,
+                                      GError          **error)
+{
+  ClutterActor *actor = CLUTTER_ACTOR (self);
+  MetaBackend *backend = meta_get_backend ();
+  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
+  CoglContext *cogl_context =
+    clutter_backend_get_cogl_context (clutter_backend);
+  CoglTexture2D *texture;
+  CoglOffscreen *offscreen;
+  CoglFramebuffer *framebuffer;
+  CoglColor clear_color;
+  ClutterPaintContext *paint_context;
+  float resource_scale;
+
+  resource_scale = clutter_actor_get_resource_scale (actor);
+
+  texture = cogl_texture_2d_new_with_size (cogl_context,
+                                           clip->width * resource_scale,
+                                           clip->height * resource_scale);
+  if (!texture)
+    return NULL;
+
+  cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
+                                          FALSE);
+
+  offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
+  framebuffer = COGL_FRAMEBUFFER (offscreen);
+
+  cogl_object_unref (texture);
+
+  if (!cogl_framebuffer_allocate (framebuffer, error))
+    {
+      g_object_unref (framebuffer);
+      return NULL;
+    }
+
+  cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
+  cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
+  cogl_framebuffer_orthographic (framebuffer, 0, 0, clip->width, clip->height,
+                                 0, 1.0);
+  cogl_framebuffer_translate (framebuffer, -clip->x, -clip->y, 0);
+
+  paint_context =
+    clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
+                                               CLUTTER_PAINT_FLAG_NONE);
+  clutter_actor_paint (actor, paint_context);
+  clutter_paint_context_destroy (paint_context);
+
+  return framebuffer;
+}
+
 /**
  * meta_window_actor_get_image:
  * @self: A #MetaWindowActor
@@ -1430,21 +1484,11 @@ meta_window_actor_get_image (MetaWindowActor *self,
 {
   MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self);
   ClutterActor *actor = CLUTTER_ACTOR (self);
-  MetaBackend *backend = meta_get_backend ();
-  ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
-  CoglContext *cogl_context =
-    clutter_backend_get_cogl_context (clutter_backend);
-  float resource_scale;
-  float width, height;
-  CoglTexture2D *texture;
-  g_autoptr (GError) error = NULL;
-  CoglOffscreen *offscreen;
-  CoglFramebuffer *framebuffer;
-  CoglColor clear_color;
-  float x, y;
-  MetaRectangle scaled_clip;
-  ClutterPaintContext *paint_context;
   cairo_surface_t *surface = NULL;
+  CoglFramebuffer *framebuffer;
+  MetaRectangle framebuffer_clip;
+  float resource_scale;
+  float x, y, width, height;
 
   if (!priv->surface)
     return NULL;
@@ -1458,7 +1502,6 @@ meta_window_actor_get_image (MetaWindowActor *self,
 
       if (clip)
         {
-
           int geometry_scale;
 
           geometry_scale =
@@ -1476,76 +1519,51 @@ meta_window_actor_get_image (MetaWindowActor *self,
       goto out;
     }
 
+  clutter_actor_get_position (actor, &x, &y);
   clutter_actor_get_size (actor, &width, &height);
 
   if (width == 0 || height == 0)
     goto out;
 
-  resource_scale = clutter_actor_get_resource_scale (actor);
-
-  width = ceilf (width * resource_scale);
-  height = ceilf (height * resource_scale);
-
-  texture = cogl_texture_2d_new_with_size (cogl_context, width, height);
-  if (!texture)
-    goto out;
-
-  cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
-                                          FALSE);
-
-  offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
-  framebuffer = COGL_FRAMEBUFFER (offscreen);
-
-  cogl_object_unref (texture);
-
-  if (!cogl_framebuffer_allocate (framebuffer, &error))
-    {
-      g_warning ("Failed to allocate framebuffer for screenshot: %s",
-                 error->message);
-      g_object_unref (framebuffer);
-      cogl_object_unref (texture);
-      goto out;
-    }
-
-  cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
-  clutter_actor_get_position (actor, &x, &y);
-
-  cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
-  cogl_framebuffer_orthographic (framebuffer, 0, 0, width, height, 0, 1.0);
-  cogl_framebuffer_scale (framebuffer, resource_scale, resource_scale, 1);
-  cogl_framebuffer_translate (framebuffer, -x, -y, 0);
-
-  paint_context =
-    clutter_paint_context_new_for_framebuffer (framebuffer, NULL,
-                                               CLUTTER_PAINT_FLAG_NONE);
-  clutter_actor_paint (actor, paint_context);
-  clutter_paint_context_destroy (paint_context);
+  framebuffer_clip = (MetaRectangle) {
+    .x = floorf (x),
+    .y = floorf (y),
+    .width = ceilf (width),
+    .height = ceilf (height),
+  };
 
   if (clip)
     {
-      meta_rectangle_scale_double (clip, resource_scale,
-                                   META_ROUNDING_STRATEGY_GROW,
-                                   &scaled_clip);
-      meta_rectangle_intersect (&scaled_clip,
-                                &(MetaRectangle) {
-                                  .width = width,
-                                  .height = height,
-                                },
-                                &scaled_clip);
-    }
-  else
-    {
-      scaled_clip = (MetaRectangle) {
-        .width = width,
-        .height = height,
-      };
+      MetaRectangle tmp_clip;
+      MetaRectangle intersected_clip;
+
+      tmp_clip = *clip;
+      tmp_clip.x += floorf (x);
+      tmp_clip.y += floorf (y);
+      if (!meta_rectangle_intersect (&framebuffer_clip,
+                                     &tmp_clip,
+                                     &intersected_clip))
+        goto out;
+
+      framebuffer_clip = intersected_clip;
     }
 
+  framebuffer = create_framebuffer_from_window_actor (self,
+                                                      &framebuffer_clip,
+                                                      NULL);
+  if (!framebuffer)
+    goto out;
+
+  resource_scale = clutter_actor_get_resource_scale (actor);
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
-                                        scaled_clip.width, scaled_clip.height);
+                                        framebuffer_clip.width *
+                                        resource_scale,
+                                        framebuffer_clip.height *
+                                        resource_scale);
   cogl_framebuffer_read_pixels (framebuffer,
-                                scaled_clip.x, scaled_clip.y,
-                                scaled_clip.width, scaled_clip.height,
+                                0, 0,
+                                framebuffer_clip.width * resource_scale,
+                                framebuffer_clip.height * resource_scale,
                                 CLUTTER_CAIRO_FORMAT_ARGB32,
                                 cairo_image_surface_get_data (surface));
 


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