diff options
author | Robert Mader <robert.mader@posteo.de> | 2021-08-22 13:21:56 +0200 |
---|---|---|
committer | Marge Bot <marge-bot@gnome.org> | 2021-09-04 09:17:44 +0000 |
commit | b1c8510a95dfe7c4bdf7835cdccd25ac2c11b491 (patch) | |
tree | e220d23db7c88d913d8f82703fb1d6151133cff5 | |
parent | 6bbb216f07f0175f692411786090fcacdbb60ef6 (diff) | |
download | mutter-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.c | 68 | ||||
-rw-r--r-- | src/meta/meta-window-actor.h | 5 |
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 |