[gnome-shell] Use clutter_stage_capture instead of cogl's read_pixels
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] Use clutter_stage_capture instead of cogl's read_pixels
- Date: Wed, 20 Jul 2016 06:26:04 +0000 (UTC)
commit f5c058a036b21da747921d0ed9eefa64331e4f17
Author: Jonas Ådahl <jadahl gmail com>
Date: Mon Jun 27 15:57:28 2016 +0800
Use clutter_stage_capture instead of cogl's read_pixels
There is no longer any guarantee that there'll be one single
framebuffer to read pixels from. In order to still read pixels from the
stage, use the new clutter_stage_capture API.
https://bugzilla.gnome.org/show_bug.cgi?id=768979
src/shell-recorder.c | 48 +++++++++++++++++++++++++------------
src/shell-screenshot.c | 60 ++++++++++++++++++++++++------------------------
2 files changed, 62 insertions(+), 46 deletions(-)
---
diff --git a/src/shell-recorder.c b/src/shell-recorder.c
index e7562ef..981b7d1 100644
--- a/src/shell-recorder.c
+++ b/src/shell-recorder.c
@@ -389,11 +389,17 @@ recorder_draw_cursor (ShellRecorder *recorder,
/* Retrieve a frame and feed it into the pipeline
*/
static void
-recorder_record_frame (ShellRecorder *recorder)
+recorder_record_frame (ShellRecorder *recorder,
+ gboolean paint)
{
GstBuffer *buffer;
- guint8 *data;
+ ClutterCapture *captures;
+ int n_captures;
+ cairo_surface_t *image;
guint size;
+ uint8_t *data;
+ GstMemory *memory;
+ int i;
GstClock *clock;
GstClockTime now, base_time;
@@ -425,21 +431,31 @@ recorder_record_frame (ShellRecorder *recorder)
return;
recorder->last_frame_time = now;
- size = recorder->area.width * recorder->area.height * 4;
+ clutter_stage_capture (recorder->stage, paint, &recorder->area,
+ &captures, &n_captures);
+
+ if (n_captures == 0)
+ return;
+
+ /*
+ * TODO: Deal with each capture region separately, instead of dropping
+ * anything except the first one.
+ */
+
+ image = captures[0].image;
+ data = cairo_image_surface_get_data (image);
+ size = captures[0].rect.width * captures[0].rect.height * 4;
- data = g_malloc (size);
- cogl_framebuffer_read_pixels (cogl_get_draw_framebuffer (),
- recorder->area.x,
- recorder->area.y,
- recorder->area.width,
- recorder->area.height,
- CLUTTER_CAIRO_FORMAT_ARGB32,
- data);
+ /* TODO: Capture more than the first framebuffer. */
+ for (i = 1; i < n_captures; i++)
+ cairo_surface_destroy (captures[i].image);
+ g_free (captures);
buffer = gst_buffer_new();
- gst_buffer_insert_memory (buffer, -1,
- gst_memory_new_wrapped (0, data, size, 0,
- size, data, g_free));
+ memory = gst_memory_new_wrapped (0, data, size, 0, size,
+ image,
+ (GDestroyNotify) cairo_surface_destroy);
+ gst_buffer_insert_memory (buffer, -1, memory);
GST_BUFFER_PTS(buffer) = now;
@@ -463,7 +479,7 @@ recorder_on_stage_paint (ClutterActor *actor,
ShellRecorder *recorder)
{
if (recorder->state == RECORDER_STATE_RECORDING)
- recorder_record_frame (recorder);
+ recorder_record_frame (recorder, FALSE);
}
static void
@@ -1561,7 +1577,7 @@ shell_recorder_close (ShellRecorder *recorder)
/* We want to record one more frame since some time may have
* elapsed since the last frame
*/
- clutter_actor_paint (CLUTTER_ACTOR (recorder->stage));
+ recorder_record_frame (recorder, TRUE);
recorder_remove_update_pointer_timeout (recorder);
recorder_close_pipeline (recorder);
diff --git a/src/shell-screenshot.c b/src/shell-screenshot.c
index 9480bad..d7c8088 100644
--- a/src/shell-screenshot.c
+++ b/src/shell-screenshot.c
@@ -210,41 +210,40 @@ write_screenshot_thread (GTask *result,
static void
do_grab_screenshot (ShellScreenshot *screenshot,
+ ClutterStage *stage,
int x,
int y,
int width,
int height)
{
- CoglBitmap *bitmap;
- ClutterBackend *backend;
- CoglContext *context;
- int stride;
- guchar *data;
ShellScreenshotPrivate *priv = screenshot->priv;
+ ClutterCapture *captures;
+ int n_captures;
+ int i;
+
+ clutter_stage_capture (stage, FALSE,
+ &(cairo_rectangle_int_t) {
+ .x = x,
+ .y = y,
+ .width = width,
+ .height = height
+ },
+ &captures,
+ &n_captures);
+
+ if (n_captures == 0)
+ return;
- backend = clutter_get_default_backend ();
- context = clutter_backend_get_cogl_context (backend);
-
- priv->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- width, height);
-
-
- data = cairo_image_surface_get_data (priv->image);
- stride = cairo_image_surface_get_stride (priv->image);
+ /*
+ * TODO: Deal with each capture region separately, instead of dropping
+ * anything except the first one.
+ */
+ priv->image = captures[0].image;
- bitmap = cogl_bitmap_new_for_data (context,
- width,
- height,
- CLUTTER_CAIRO_FORMAT_ARGB32,
- stride,
- data);
- cogl_framebuffer_read_pixels_into_bitmap (cogl_get_draw_framebuffer (),
- x, y,
- COGL_READ_PIXELS_COLOR_BUFFER,
- bitmap);
+ for (i = 1; i < n_captures; i++)
+ cairo_surface_destroy (captures[i].image);
- cairo_surface_mark_dirty (priv->image);
- cogl_object_unref (bitmap);
+ g_free (captures);
}
static void
@@ -312,7 +311,7 @@ grab_screenshot (ClutterActor *stage,
screen = shell_global_get_screen (priv->global);
meta_screen_get_size (screen, &width, &height);
- do_grab_screenshot (screenshot, 0, 0, width, height);
+ do_grab_screenshot (screenshot, CLUTTER_STAGE (stage), 0, 0, width, height);
if (meta_screen_get_n_monitors (screen) > 1)
{
@@ -381,6 +380,7 @@ grab_area_screenshot (ClutterActor *stage,
ShellScreenshotPrivate *priv = screenshot->priv;
do_grab_screenshot (screenshot,
+ CLUTTER_STAGE (stage),
priv->screenshot_area.x,
priv->screenshot_area.y,
priv->screenshot_area.width,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]