[mutter] clutter: Add capture API for reading stage pixels
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] clutter: Add capture API for reading stage pixels
- Date: Wed, 20 Jul 2016 06:30:04 +0000 (UTC)
commit ff6186f1ecd0f483754455b3096e774d4b28ad7e
Author: Jonas Ådahl <jadahl gmail com>
Date: Sat Jun 25 08:10:27 2016 +0800
clutter: Add capture API for reading stage pixels
clutter_stage_capture should be used instead of directly utilizing
cogl's read_pixels API's.
https://bugzilla.gnome.org/show_bug.cgi?id=768978
clutter/clutter/clutter-stage.c | 97 +++++++++++++++++++++++++++++++++++++++
clutter/clutter/clutter-stage.h | 13 +++++
2 files changed, 110 insertions(+), 0 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 8041262..edbc9b4 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -4661,3 +4661,100 @@ _clutter_stage_presented (ClutterStage *stage,
g_signal_emit (stage, stage_signals[PRESENTED], 0,
(int) frame_event, frame_info);
}
+
+static void
+capture_view (ClutterStage *stage,
+ gboolean paint,
+ ClutterStageView *view,
+ cairo_rectangle_int_t *rect,
+ ClutterCapture *capture)
+{
+ CoglFramebuffer *framebuffer;
+ ClutterBackend *backend;
+ CoglContext *context;
+ cairo_surface_t *image;
+ uint8_t *data;
+ int stride;
+ CoglBitmap *bitmap;
+
+ framebuffer = clutter_stage_view_get_framebuffer (view);
+
+ if (paint)
+ {
+ _clutter_stage_maybe_setup_viewport (stage, view);
+ cogl_push_framebuffer (framebuffer);
+ clutter_stage_do_paint_view (stage, view, rect);
+ }
+
+ image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ rect->width, rect->height);
+
+ data = cairo_image_surface_get_data (image);
+ stride = cairo_image_surface_get_stride (image);
+
+ backend = clutter_get_default_backend ();
+ context = clutter_backend_get_cogl_context (backend);
+ bitmap = cogl_bitmap_new_for_data (context,
+ rect->width, rect->height,
+ CLUTTER_CAIRO_FORMAT_ARGB32,
+ stride,
+ data);
+
+ cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
+ rect->x, rect->y,
+ COGL_READ_PIXELS_COLOR_BUFFER,
+ bitmap);
+
+ if (paint)
+ cogl_pop_framebuffer ();
+
+ capture->rect = *rect;
+ capture->image = image;
+
+ cairo_surface_mark_dirty (capture->image);
+ cogl_object_unref (bitmap);
+}
+
+gboolean
+clutter_stage_capture (ClutterStage *stage,
+ gboolean paint,
+ cairo_rectangle_int_t *rect,
+ ClutterCapture **out_captures,
+ int *out_n_captures)
+{
+ ClutterStagePrivate *priv = stage->priv;
+ GList *views = _clutter_stage_window_get_views (priv->impl);
+ GList *l;
+ ClutterCapture *captures;
+ int n_captures;
+
+ captures = g_new0 (ClutterCapture, g_list_length (views));
+ n_captures = 0;
+
+ for (l = views; l; l = l->next)
+ {
+ ClutterStageView *view = l->data;
+ cairo_rectangle_int_t view_layout;
+ cairo_region_t *region;
+ cairo_rectangle_int_t view_capture_rect;
+
+ clutter_stage_view_get_layout (view, &view_layout);
+ region = cairo_region_create_rectangle (&view_layout);
+ cairo_region_intersect_rectangle (region, rect);
+ cairo_region_get_extents (region, &view_capture_rect);
+ cairo_region_destroy (region);
+
+ if (view_capture_rect.width == 0 || view_capture_rect.height == 0)
+ continue;
+
+ capture_view (stage, paint, view, &view_capture_rect,
+ &captures[n_captures]);
+
+ n_captures++;
+ }
+
+ *out_captures = captures;
+ *out_n_captures = n_captures;
+
+ return TRUE;
+}
diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h
index e0911bc..e8fbda8 100644
--- a/clutter/clutter/clutter-stage.h
+++ b/clutter/clutter/clutter-stage.h
@@ -145,6 +145,12 @@ struct _ClutterFrameInfo
float refresh_rate;
};
+typedef struct _ClutterCapture
+{
+ cairo_surface_t *image;
+ cairo_rectangle_int_t rect;
+} ClutterCapture;
+
CLUTTER_AVAILABLE_IN_ALL
GType clutter_perspective_get_type (void) G_GNUC_CONST;
CLUTTER_DEPRECATED_IN_1_10
@@ -252,6 +258,13 @@ CLUTTER_AVAILABLE_IN_1_14
void clutter_stage_skip_sync_delay (ClutterStage *stage);
#endif
+CLUTTER_AVAILABLE_IN_MUTTER
+gboolean clutter_stage_capture (ClutterStage *stage,
+ gboolean paint,
+ cairo_rectangle_int_t *rect,
+ ClutterCapture **captures,
+ int *n_captures);
+
G_END_DECLS
#endif /* __CLUTTER_STAGE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]