[mutter] window-actor: Factor out framebuffer creation of get_image()
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] window-actor: Factor out framebuffer creation of get_image()
- Date: Sat, 4 Sep 2021 10:07:17 +0000 (UTC)
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]