window-stream-source: Draw into DMA buffer image
Much like monitor streaming, implement window streaming by making the window actor draw itself with a paint context that used the passed framebuffer. Now that all MetaScreenCastStreamSrc subclasses implement blit_to_framebuffer, remove the conditional check from meta_screen_cast_stream_src_blit_to_framebuffer(). https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
This commit is contained in:
parent
680a54aff6
commit
86168b945c
@ -149,10 +149,7 @@ meta_screen_cast_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
MetaScreenCastStreamSrcClass *klass =
|
||||
META_SCREEN_CAST_STREAM_SRC_GET_CLASS (src);
|
||||
|
||||
if (klass->blit_to_framebuffer)
|
||||
return klass->blit_to_framebuffer (src, framebuffer);
|
||||
|
||||
return FALSE;
|
||||
return klass->blit_to_framebuffer (src, framebuffer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -401,6 +401,25 @@ meta_screen_cast_window_stream_src_record_frame (MetaScreenCastStreamSrc *src,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_screen_cast_window_stream_src_blit_to_framebuffer (MetaScreenCastStreamSrc *src,
|
||||
CoglFramebuffer *framebuffer)
|
||||
{
|
||||
MetaScreenCastWindowStreamSrc *window_src =
|
||||
META_SCREEN_CAST_WINDOW_STREAM_SRC (src);
|
||||
MetaRectangle stream_rect;
|
||||
|
||||
stream_rect.x = 0;
|
||||
stream_rect.y = 0;
|
||||
stream_rect.width = get_stream_width (window_src);
|
||||
stream_rect.height = get_stream_height (window_src);
|
||||
|
||||
return
|
||||
meta_screen_cast_window_blit_to_framebuffer (window_src->screen_cast_window,
|
||||
&stream_rect,
|
||||
framebuffer);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_cast_window_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc *src,
|
||||
struct spa_meta_cursor *spa_meta_cursor)
|
||||
@ -485,6 +504,8 @@ meta_screen_cast_window_stream_src_class_init (MetaScreenCastWindowStreamSrcClas
|
||||
src_class->enable = meta_screen_cast_window_stream_src_enable;
|
||||
src_class->disable = meta_screen_cast_window_stream_src_disable;
|
||||
src_class->record_frame = meta_screen_cast_window_stream_src_record_frame;
|
||||
src_class->blit_to_framebuffer =
|
||||
meta_screen_cast_window_stream_src_blit_to_framebuffer;
|
||||
src_class->get_videocrop = meta_screen_cast_window_stream_src_get_videocrop;
|
||||
src_class->set_cursor_metadata = meta_screen_cast_window_stream_src_set_cursor_metadata;
|
||||
}
|
||||
|
@ -78,6 +78,17 @@ meta_screen_cast_window_capture_into (MetaScreenCastWindow *screen_cast_window,
|
||||
data);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_screen_cast_window_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
|
||||
MetaRectangle *bounds,
|
||||
CoglFramebuffer *framebuffer)
|
||||
{
|
||||
MetaScreenCastWindowInterface *iface =
|
||||
META_SCREEN_CAST_WINDOW_GET_IFACE (screen_cast_window);
|
||||
|
||||
return iface->blit_to_framebuffer (screen_cast_window, bounds, framebuffer);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_screen_cast_window_has_damage (MetaScreenCastWindow *screen_cast_window)
|
||||
{
|
||||
|
@ -56,6 +56,10 @@ struct _MetaScreenCastWindowInterface
|
||||
MetaRectangle *bounds,
|
||||
uint8_t *data);
|
||||
|
||||
gboolean (*blit_to_framebuffer) (MetaScreenCastWindow *screen_cast_window,
|
||||
MetaRectangle *bounds,
|
||||
CoglFramebuffer *framebuffer);
|
||||
|
||||
gboolean (*has_damage) (MetaScreenCastWindow *screen_cast_window);
|
||||
};
|
||||
|
||||
@ -78,6 +82,10 @@ void meta_screen_cast_window_capture_into (MetaScreenCastWindow *screen_cast_win
|
||||
MetaRectangle *bounds,
|
||||
uint8_t *data);
|
||||
|
||||
gboolean meta_screen_cast_window_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
|
||||
MetaRectangle *bounds,
|
||||
CoglFramebuffer *framebuffer);
|
||||
|
||||
gboolean meta_screen_cast_window_has_damage (MetaScreenCastWindow *screen_cast_window);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -1256,6 +1256,69 @@ meta_window_actor_capture_into (MetaScreenCastWindow *screen_cast_window,
|
||||
cairo_surface_destroy (image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_actor_blit_to_framebuffer (MetaScreenCastWindow *screen_cast_window,
|
||||
MetaRectangle *bounds,
|
||||
CoglFramebuffer *framebuffer)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (screen_cast_window);
|
||||
ClutterActor *actor = CLUTTER_ACTOR (window_actor);
|
||||
ClutterPaintContext *paint_context;
|
||||
MetaRectangle scaled_clip;
|
||||
CoglColor clear_color;
|
||||
float resource_scale;
|
||||
float width, height;
|
||||
float x, y;
|
||||
|
||||
if (meta_window_actor_is_destroyed (window_actor))
|
||||
return FALSE;
|
||||
|
||||
clutter_actor_get_size (actor, &width, &height);
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return FALSE;
|
||||
|
||||
if (!clutter_actor_get_resource_scale (actor, &resource_scale))
|
||||
return FALSE;
|
||||
|
||||
width = ceilf (width * resource_scale);
|
||||
height = ceilf (height * resource_scale);
|
||||
|
||||
cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0);
|
||||
clutter_actor_get_position (actor, &x, &y);
|
||||
|
||||
cogl_framebuffer_push_matrix (framebuffer);
|
||||
|
||||
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);
|
||||
|
||||
meta_rectangle_scale_double (bounds, resource_scale,
|
||||
META_ROUNDING_STRATEGY_GROW,
|
||||
&scaled_clip);
|
||||
meta_rectangle_intersect (&scaled_clip,
|
||||
&(MetaRectangle) {
|
||||
.width = width,
|
||||
.height = height,
|
||||
},
|
||||
&scaled_clip);
|
||||
|
||||
cogl_framebuffer_push_rectangle_clip (framebuffer,
|
||||
scaled_clip.x, scaled_clip.y,
|
||||
scaled_clip.x + scaled_clip.width,
|
||||
scaled_clip.y + scaled_clip.height);
|
||||
|
||||
paint_context = clutter_paint_context_new_for_framebuffer (framebuffer);
|
||||
clutter_actor_paint (actor, paint_context);
|
||||
clutter_paint_context_destroy (paint_context);
|
||||
|
||||
cogl_framebuffer_pop_clip (framebuffer);
|
||||
cogl_framebuffer_pop_matrix (framebuffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_actor_has_damage (MetaScreenCastWindow *screen_cast_window)
|
||||
{
|
||||
@ -1269,6 +1332,7 @@ screen_cast_window_iface_init (MetaScreenCastWindowInterface *iface)
|
||||
iface->transform_relative_position = meta_window_actor_transform_relative_position;
|
||||
iface->transform_cursor_position = meta_window_actor_transform_cursor_position;
|
||||
iface->capture_into = meta_window_actor_capture_into;
|
||||
iface->blit_to_framebuffer = meta_window_actor_blit_to_framebuffer;
|
||||
iface->has_damage = meta_window_actor_has_damage;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user