From ae2ba9b01bb97795801648e5050f6bab7a5f8ccf Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 20 Jun 2012 00:05:46 -0400 Subject: [PATCH] screenshooter: Just use frame signal for screenshots too We'll remove the odd do_read_pixels callback next. --- src/screenshooter.c | 74 +++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/src/screenshooter.c b/src/screenshooter.c index 765369c..03067a3 100644 --- a/src/screenshooter.c +++ b/src/screenshooter.c @@ -42,10 +42,11 @@ struct screenshooter { struct wl_listener destroy_listener; }; -struct screenshooter_read_pixels { - struct weston_read_pixels base; +struct screenshooter_frame_listener { + struct wl_listener listener; struct wl_buffer *buffer; struct wl_resource *resource; + struct weston_output *output; }; static void @@ -92,18 +93,34 @@ copy_rgba_yflip(uint8_t *dst, uint8_t *src, int height, int stride) } static void -screenshooter_read_pixels_done(struct weston_read_pixels *base, - struct weston_output *output) +screenshooter_frame_notify(struct wl_listener *listener, void *data) { - struct screenshooter_read_pixels *r = - (struct screenshooter_read_pixels *) base; + struct screenshooter_frame_listener *l = + container_of(listener, + struct screenshooter_frame_listener, listener); + struct weston_output *output = l->output; int32_t stride; - uint8_t *d, *s; + uint8_t *pixels, *d, *s; + + wl_list_remove(&listener->link); + stride = l->buffer->width * 4; + pixels = malloc(stride * l->buffer->height); + + if (pixels == NULL) { + wl_resource_post_no_memory(l->resource); + free(l); + return; + } + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(0, 0, output->current->width, output->current->height, + output->compositor->read_format, + GL_UNSIGNED_BYTE, pixels); - stride = wl_shm_buffer_get_stride(r->buffer); + stride = wl_shm_buffer_get_stride(l->buffer); - d = wl_shm_buffer_get_data(r->buffer); - s = r->base.data + stride * (r->buffer->height - 1); + d = wl_shm_buffer_get_data(l->buffer); + s = pixels + stride * (l->buffer->height - 1); switch (output->compositor->read_format) { case GL_BGRA_EXT: @@ -116,12 +133,9 @@ screenshooter_read_pixels_done(struct weston_read_pixels *base, break; } - wl_list_remove(&r->base.link); - - screenshooter_send_done(r->resource); - free(r->base.data); - free(r); - + screenshooter_send_done(l->resource); + free(pixels); + free(l); } static void @@ -131,9 +145,8 @@ screenshooter_shoot(struct wl_client *client, struct wl_resource *buffer_resource) { struct weston_output *output = output_resource->data; - struct screenshooter_read_pixels *r; + struct screenshooter_frame_listener *l; struct wl_buffer *buffer = buffer_resource->data; - int32_t stride; if (!wl_buffer_is_shm(buffer)) return; @@ -142,29 +155,18 @@ screenshooter_shoot(struct wl_client *client, buffer->height < output->current->height) return; - r = malloc(sizeof *r); - if (r == NULL) { + l = malloc(sizeof *l); + if (l == NULL) { wl_resource_post_no_memory(resource); return; } - r->base.x = 0; - r->base.y = 0; - r->base.width = output->current->width; - r->base.height = output->current->height; - r->base.done = screenshooter_read_pixels_done; - r->buffer = buffer; - r->resource = resource; - stride = buffer->width * 4; - r->base.data = malloc(stride * buffer->height); - - if (r->base.data == NULL) { - free(r); - wl_resource_post_no_memory(resource); - return; - } + l->buffer = buffer; + l->resource = resource; + l->output = output; - wl_list_insert(output->read_pixels_list.prev, &r->base.link); + l->listener.notify = screenshooter_frame_notify; + wl_signal_add(&output->frame_signal, &l->listener); weston_compositor_schedule_repaint(output->compositor); } -- 2.7.4