mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
clutter/stage: Use new paint API to implement capture()
This changes the semantics a bit, e.g. we will never include the pointer cursor sprite, as there is no way to know whether the caller wants to or not. We also change things a bit so that when we render to an offscreen paint context, we don't emit the "paint" signal on actors, as doing so would end up recursing in gnome-shell's screenshot and screencast code. Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2567 https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1222
This commit is contained in:
parent
797c349245
commit
d9d8732096
@ -4194,7 +4194,9 @@ clutter_actor_continue_paint (ClutterActor *self,
|
|||||||
clutter_paint_node_unref (dummy);
|
clutter_paint_node_unref (dummy);
|
||||||
|
|
||||||
/* XXX:2.0 - Call the paint() virtual directly */
|
/* XXX:2.0 - Call the paint() virtual directly */
|
||||||
if (g_signal_has_handler_pending (self, actor_signals[PAINT],
|
if (!(clutter_paint_context_get_paint_flags (paint_context) &
|
||||||
|
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL) &&
|
||||||
|
g_signal_has_handler_pending (self, actor_signals[PAINT],
|
||||||
0, TRUE))
|
0, TRUE))
|
||||||
g_signal_emit (self, actor_signals[PAINT], 0, paint_context);
|
g_signal_emit (self, actor_signals[PAINT], 0, paint_context);
|
||||||
else
|
else
|
||||||
|
@ -24,6 +24,7 @@ typedef enum _ClutterPaintFlag
|
|||||||
{
|
{
|
||||||
CLUTTER_PAINT_FLAG_NONE = 0,
|
CLUTTER_PAINT_FLAG_NONE = 0,
|
||||||
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
|
CLUTTER_PAINT_FLAG_NO_CURSORS = 1 << 0,
|
||||||
|
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL = 1 << 0,
|
||||||
} ClutterPaintFlag;
|
} ClutterPaintFlag;
|
||||||
|
|
||||||
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
|
ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||||
|
@ -66,7 +66,8 @@ clutter_paint_context_new_for_framebuffer (CoglFramebuffer *framebuffer)
|
|||||||
|
|
||||||
paint_context = g_new0 (ClutterPaintContext, 1);
|
paint_context = g_new0 (ClutterPaintContext, 1);
|
||||||
g_ref_count_init (&paint_context->ref_count);
|
g_ref_count_init (&paint_context->ref_count);
|
||||||
paint_context->paint_flags = CLUTTER_PAINT_FLAG_NO_CURSORS;
|
paint_context->paint_flags = (CLUTTER_PAINT_FLAG_NO_CURSORS |
|
||||||
|
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL);
|
||||||
|
|
||||||
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
|
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
|
||||||
|
|
||||||
|
@ -4575,50 +4575,17 @@ capture_view_into (ClutterStage *stage,
|
|||||||
uint8_t *data,
|
uint8_t *data,
|
||||||
int stride)
|
int stride)
|
||||||
{
|
{
|
||||||
CoglFramebuffer *framebuffer;
|
g_autoptr (GError) error = NULL;
|
||||||
ClutterBackend *backend;
|
|
||||||
CoglContext *context;
|
|
||||||
CoglBitmap *bitmap;
|
|
||||||
cairo_rectangle_int_t view_layout;
|
|
||||||
float view_scale;
|
float view_scale;
|
||||||
float texture_width;
|
|
||||||
float texture_height;
|
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||||
|
|
||||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
|
||||||
|
|
||||||
if (paint)
|
|
||||||
{
|
|
||||||
cairo_region_t *region;
|
|
||||||
|
|
||||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
|
||||||
region = cairo_region_create_rectangle (rect);
|
|
||||||
clutter_stage_do_paint_view (stage, view, region);
|
|
||||||
cairo_region_destroy (region);
|
|
||||||
}
|
|
||||||
|
|
||||||
view_scale = clutter_stage_view_get_scale (view);
|
view_scale = clutter_stage_view_get_scale (view);
|
||||||
texture_width = roundf (rect->width * view_scale);
|
if (!clutter_stage_paint_to_buffer (stage, rect, view_scale, data, stride,
|
||||||
texture_height = roundf (rect->height * view_scale);
|
|
||||||
|
|
||||||
backend = clutter_get_default_backend ();
|
|
||||||
context = clutter_backend_get_cogl_context (backend);
|
|
||||||
bitmap = cogl_bitmap_new_for_data (context,
|
|
||||||
texture_width, texture_height,
|
|
||||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||||
stride,
|
CLUTTER_PAINT_FLAG_NO_CURSORS,
|
||||||
data);
|
&error))
|
||||||
|
g_warning ("Failed to capture stage: %s", error->message);
|
||||||
clutter_stage_view_get_layout (view, &view_layout);
|
|
||||||
|
|
||||||
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
|
||||||
roundf ((rect->x - view_layout.x) * view_scale),
|
|
||||||
roundf ((rect->y - view_layout.y) * view_scale),
|
|
||||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
|
||||||
bitmap);
|
|
||||||
|
|
||||||
cogl_object_unref (bitmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -204,6 +204,8 @@ meta_stage_paint (ClutterActor *actor,
|
|||||||
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
|
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(clutter_paint_context_get_paint_flags (paint_context) &
|
||||||
|
CLUTTER_PAINT_FLAG_NO_PAINT_SIGNAL))
|
||||||
g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
|
g_signal_emit (stage, signals[ACTORS_PAINTED], 0);
|
||||||
|
|
||||||
if (!(clutter_paint_context_get_paint_flags (paint_context) &
|
if (!(clutter_paint_context_get_paint_flags (paint_context) &
|
||||||
|
Loading…
Reference in New Issue
Block a user