[mutter] window-actor: Add paint_to_content() function



commit b1c8510a95dfe7c4bdf7835cdccd25ac2c11b491
Author: Robert Mader <robert mader posteo de>
Date:   Sun Aug 22 13:21:56 2021 +0200

    window-actor: Add paint_to_content() function
    
    Analogous to `get_image()` this returns a `ClutterContent` for a
    given `MetaWindowActor`. This can be used to implement window
    effects without a roundtrip from GPU to CPU memory.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1893>

 src/compositor/meta-window-actor.c | 68 ++++++++++++++++++++++++++++++++++++++
 src/meta/meta-window-actor.h       |  5 +++
 2 files changed, 73 insertions(+)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index c284a6cd57..cbc0c96a84 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1575,3 +1575,71 @@ out:
   clutter_actor_uninhibit_culling (actor);
   return surface;
 }
+
+/**
+ * meta_window_actor_paint_to_content:
+ * @self: A #MetaWindowActor
+ * @clip: (nullable): A clipping rectangle, in actor coordinates, to help
+ * prevent extra processing.
+ * In the case that the clipping rectangle is partially or fully
+ * outside the bounds of the actor, the rectangle will be clipped.
+ * @error: A #GError to catch exceptional errors or %NULL.
+ *
+ * Returns: (nullable) (transfer full): a new #ClutterContent
+ */
+ClutterContent *
+meta_window_actor_paint_to_content (MetaWindowActor  *self,
+                                    MetaRectangle    *clip,
+                                    GError          **error)
+{
+  MetaWindowActorPrivate *priv = meta_window_actor_get_instance_private (self);
+  ClutterActor *actor = CLUTTER_ACTOR (self);
+  ClutterContent *content = NULL;
+  CoglFramebuffer *framebuffer;
+  CoglTexture *texture;
+  MetaRectangle framebuffer_clip;
+  float x, y, width, height;
+
+  if (!priv->surface)
+    return NULL;
+
+  clutter_actor_inhibit_culling (actor);
+
+  clutter_actor_get_position (actor, &x, &y);
+  clutter_actor_get_size (actor, &width, &height);
+
+  if (width == 0 || height == 0)
+    goto out;
+
+  framebuffer_clip = (MetaRectangle) {
+    .x = floorf (x),
+    .y = floorf (y),
+    .width = ceilf (width),
+    .height = ceilf (height),
+  };
+
+  if (clip)
+    {
+      MetaRectangle tmp_clip;
+
+      if (!meta_rectangle_intersect (&framebuffer_clip, clip, &tmp_clip))
+        goto out;
+
+      framebuffer_clip = tmp_clip;
+    }
+
+  framebuffer = create_framebuffer_from_window_actor (self,
+                                                      &framebuffer_clip,
+                                                      error);
+  if (!framebuffer)
+    goto out;
+
+  texture = cogl_offscreen_get_texture (COGL_OFFSCREEN (framebuffer));
+  content = clutter_texture_content_new_from_texture (texture, NULL);
+
+  g_object_unref (framebuffer);
+
+out:
+  clutter_actor_uninhibit_culling (actor);
+  return content;
+}
diff --git a/src/meta/meta-window-actor.h b/src/meta/meta-window-actor.h
index 6e18683a27..342995fb05 100644
--- a/src/meta/meta-window-actor.h
+++ b/src/meta/meta-window-actor.h
@@ -51,6 +51,11 @@ META_EXPORT
 cairo_surface_t * meta_window_actor_get_image (MetaWindowActor       *self,
                                                cairo_rectangle_int_t *clip);
 
+META_EXPORT
+ClutterContent * meta_window_actor_paint_to_content (MetaWindowActor  *self,
+                                                     MetaRectangle    *clip,
+                                                     GError          **error);
+
 META_EXPORT
 void meta_window_actor_freeze (MetaWindowActor *self);
 


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