summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mader <robert.mader@posteo.de>2021-08-22 13:21:56 +0200
committerMarge Bot <marge-bot@gnome.org>2021-09-04 09:17:44 +0000
commitb1c8510a95dfe7c4bdf7835cdccd25ac2c11b491 (patch)
treee220d23db7c88d913d8f82703fb1d6151133cff5
parent6bbb216f07f0175f692411786090fcacdbb60ef6 (diff)
downloadmutter-b1c8510a95dfe7c4bdf7835cdccd25ac2c11b491.tar.gz
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>
-rw-r--r--src/compositor/meta-window-actor.c68
-rw-r--r--src/meta/meta-window-actor.h5
2 files changed, 73 insertions, 0 deletions
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index c284a6cd5..cbc0c96a8 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 6e18683a2..342995fb0 100644
--- a/src/meta/meta-window-actor.h
+++ b/src/meta/meta-window-actor.h
@@ -52,6 +52,11 @@ 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);
META_EXPORT