[mutter/gbsneto/dmabuf-screencast: 6/7] window-stream-source: Draw into DMA buffer image



commit 555929b4049e1e8caa9f32e84933cec537fbe010
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Feb 28 12:23:15 2020 -0300

    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.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086

 src/backends/meta-screen-cast-window-stream-src.c | 21 ++++++++
 src/backends/meta-screen-cast-window.c            | 11 ++++
 src/backends/meta-screen-cast-window.h            |  8 +++
 src/compositor/meta-window-actor.c                | 64 +++++++++++++++++++++++
 4 files changed, 104 insertions(+)
---
diff --git a/src/backends/meta-screen-cast-window-stream-src.c 
b/src/backends/meta-screen-cast-window-stream-src.c
index 63ac5eb38..1159ddb69 100644
--- a/src/backends/meta-screen-cast-window-stream-src.c
+++ b/src/backends/meta-screen-cast-window-stream-src.c
@@ -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;
 }
diff --git a/src/backends/meta-screen-cast-window.c b/src/backends/meta-screen-cast-window.c
index bc6249a47..ab3e4ebe3 100644
--- a/src/backends/meta-screen-cast-window.c
+++ b/src/backends/meta-screen-cast-window.c
@@ -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)
 {
diff --git a/src/backends/meta-screen-cast-window.h b/src/backends/meta-screen-cast-window.h
index 28734d8fb..e149646ed 100644
--- a/src/backends/meta-screen-cast-window.h
+++ b/src/backends/meta-screen-cast-window.h
@@ -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
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index c4781d3b2..0523d97bf 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -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;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]