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
This commit is contained in:
parent
0dac0ad516
commit
f5c058a036
@ -389,11 +389,17 @@ recorder_draw_cursor (ShellRecorder *recorder,
|
|||||||
/* Retrieve a frame and feed it into the pipeline
|
/* Retrieve a frame and feed it into the pipeline
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
recorder_record_frame (ShellRecorder *recorder)
|
recorder_record_frame (ShellRecorder *recorder,
|
||||||
|
gboolean paint)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
guint8 *data;
|
ClutterCapture *captures;
|
||||||
|
int n_captures;
|
||||||
|
cairo_surface_t *image;
|
||||||
guint size;
|
guint size;
|
||||||
|
uint8_t *data;
|
||||||
|
GstMemory *memory;
|
||||||
|
int i;
|
||||||
GstClock *clock;
|
GstClock *clock;
|
||||||
GstClockTime now, base_time;
|
GstClockTime now, base_time;
|
||||||
|
|
||||||
@ -425,21 +431,31 @@ recorder_record_frame (ShellRecorder *recorder)
|
|||||||
return;
|
return;
|
||||||
recorder->last_frame_time = now;
|
recorder->last_frame_time = now;
|
||||||
|
|
||||||
size = recorder->area.width * recorder->area.height * 4;
|
clutter_stage_capture (recorder->stage, paint, &recorder->area,
|
||||||
|
&captures, &n_captures);
|
||||||
|
|
||||||
data = g_malloc (size);
|
if (n_captures == 0)
|
||||||
cogl_framebuffer_read_pixels (cogl_get_draw_framebuffer (),
|
return;
|
||||||
recorder->area.x,
|
|
||||||
recorder->area.y,
|
/*
|
||||||
recorder->area.width,
|
* TODO: Deal with each capture region separately, instead of dropping
|
||||||
recorder->area.height,
|
* anything except the first one.
|
||||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
*/
|
||||||
data);
|
|
||||||
|
image = captures[0].image;
|
||||||
|
data = cairo_image_surface_get_data (image);
|
||||||
|
size = captures[0].rect.width * captures[0].rect.height * 4;
|
||||||
|
|
||||||
|
/* 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();
|
buffer = gst_buffer_new();
|
||||||
gst_buffer_insert_memory (buffer, -1,
|
memory = gst_memory_new_wrapped (0, data, size, 0, size,
|
||||||
gst_memory_new_wrapped (0, data, size, 0,
|
image,
|
||||||
size, data, g_free));
|
(GDestroyNotify) cairo_surface_destroy);
|
||||||
|
gst_buffer_insert_memory (buffer, -1, memory);
|
||||||
|
|
||||||
GST_BUFFER_PTS(buffer) = now;
|
GST_BUFFER_PTS(buffer) = now;
|
||||||
|
|
||||||
@ -463,7 +479,7 @@ recorder_on_stage_paint (ClutterActor *actor,
|
|||||||
ShellRecorder *recorder)
|
ShellRecorder *recorder)
|
||||||
{
|
{
|
||||||
if (recorder->state == RECORDER_STATE_RECORDING)
|
if (recorder->state == RECORDER_STATE_RECORDING)
|
||||||
recorder_record_frame (recorder);
|
recorder_record_frame (recorder, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1561,7 +1577,7 @@ shell_recorder_close (ShellRecorder *recorder)
|
|||||||
/* We want to record one more frame since some time may have
|
/* We want to record one more frame since some time may have
|
||||||
* elapsed since the last frame
|
* elapsed since the last frame
|
||||||
*/
|
*/
|
||||||
clutter_actor_paint (CLUTTER_ACTOR (recorder->stage));
|
recorder_record_frame (recorder, TRUE);
|
||||||
|
|
||||||
recorder_remove_update_pointer_timeout (recorder);
|
recorder_remove_update_pointer_timeout (recorder);
|
||||||
recorder_close_pipeline (recorder);
|
recorder_close_pipeline (recorder);
|
||||||
|
@ -210,41 +210,40 @@ write_screenshot_thread (GTask *result,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
do_grab_screenshot (ShellScreenshot *screenshot,
|
do_grab_screenshot (ShellScreenshot *screenshot,
|
||||||
|
ClutterStage *stage,
|
||||||
int x,
|
int x,
|
||||||
int y,
|
int y,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
CoglBitmap *bitmap;
|
|
||||||
ClutterBackend *backend;
|
|
||||||
CoglContext *context;
|
|
||||||
int stride;
|
|
||||||
guchar *data;
|
|
||||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||||
|
ClutterCapture *captures;
|
||||||
|
int n_captures;
|
||||||
|
int i;
|
||||||
|
|
||||||
backend = clutter_get_default_backend ();
|
clutter_stage_capture (stage, FALSE,
|
||||||
context = clutter_backend_get_cogl_context (backend);
|
&(cairo_rectangle_int_t) {
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = width,
|
||||||
|
.height = height
|
||||||
|
},
|
||||||
|
&captures,
|
||||||
|
&n_captures);
|
||||||
|
|
||||||
priv->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
if (n_captures == 0)
|
||||||
width, height);
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Deal with each capture region separately, instead of dropping
|
||||||
|
* anything except the first one.
|
||||||
|
*/
|
||||||
|
priv->image = captures[0].image;
|
||||||
|
|
||||||
data = cairo_image_surface_get_data (priv->image);
|
for (i = 1; i < n_captures; i++)
|
||||||
stride = cairo_image_surface_get_stride (priv->image);
|
cairo_surface_destroy (captures[i].image);
|
||||||
|
|
||||||
bitmap = cogl_bitmap_new_for_data (context,
|
g_free (captures);
|
||||||
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);
|
|
||||||
|
|
||||||
cairo_surface_mark_dirty (priv->image);
|
|
||||||
cogl_object_unref (bitmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -312,7 +311,7 @@ grab_screenshot (ClutterActor *stage,
|
|||||||
screen = shell_global_get_screen (priv->global);
|
screen = shell_global_get_screen (priv->global);
|
||||||
meta_screen_get_size (screen, &width, &height);
|
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)
|
if (meta_screen_get_n_monitors (screen) > 1)
|
||||||
{
|
{
|
||||||
@ -381,6 +380,7 @@ grab_area_screenshot (ClutterActor *stage,
|
|||||||
ShellScreenshotPrivate *priv = screenshot->priv;
|
ShellScreenshotPrivate *priv = screenshot->priv;
|
||||||
|
|
||||||
do_grab_screenshot (screenshot,
|
do_grab_screenshot (screenshot,
|
||||||
|
CLUTTER_STAGE (stage),
|
||||||
priv->screenshot_area.x,
|
priv->screenshot_area.x,
|
||||||
priv->screenshot_area.y,
|
priv->screenshot_area.y,
|
||||||
priv->screenshot_area.width,
|
priv->screenshot_area.width,
|
||||||
|
Loading…
Reference in New Issue
Block a user