[PATCH 2/2] screenshooter: Move buffer assembly to client side
Scott Moreau
oreaus at gmail.com
Fri Apr 20 02:08:08 PDT 2012
---
clients/screenshot.c | 45 +++++++++++++++++++++++++++++++--------------
src/screenshooter.c | 44 +++++++++++++++++++-------------------------
2 files changed, 50 insertions(+), 39 deletions(-)
diff --git a/clients/screenshot.c b/clients/screenshot.c
index da22423..648d334 100644
--- a/clients/screenshot.c
+++ b/clients/screenshot.c
@@ -47,6 +47,7 @@ struct screenshooter_output {
struct wl_output *output;
struct wl_buffer *buffer;
int width, height, offset_x, offset_y;
+ void *data;
struct wl_list link;
};
@@ -165,23 +166,45 @@ create_shm_buffer(int width, int height, void **data_out)
}
static void
-write_png(int width, int height, void *data)
+write_png(int width, int height, struct wl_list wl_list)
{
+ int output_stride, buffer_stride, i;
cairo_surface_t *surface;
+ void *data, *d, *s;
+ struct screenshooter_output *output, *next;
+
+ buffer_stride = width * 4;
+
+ data = malloc(buffer_stride * height);
+ if (!data)
+ return;
+
+ wl_list_for_each_safe(output, next, &output_list, link) {
+ output_stride = output->width * 4;
+ s = output->data;
+ d = data + output->offset_y * buffer_stride + output->offset_x * 4;
+
+ for (i = 0; i < output->height; i++) {
+ memcpy(d, s, output_stride);
+ d += buffer_stride;
+ s += output_stride;
+ }
+
+ free(output);
+ }
surface = cairo_image_surface_create_for_data(data,
CAIRO_FORMAT_ARGB32,
- width, height, width * 4);
+ width, height, buffer_stride);
cairo_surface_write_to_png(surface, "wayland-screenshot.png");
cairo_surface_destroy(surface);
+ free(data);
}
int main(int argc, char *argv[])
{
struct wl_display *display;
- struct wl_buffer *buffer;
- void *data = NULL;
- struct screenshooter_output *output, *next;
+ struct screenshooter_output *output;
int width = 0, height = 0;
display = wl_display_connect(NULL);
@@ -202,22 +225,16 @@ int main(int argc, char *argv[])
screenshooter_add_listener(screenshooter, &screenshooter_listener, screenshooter);
wl_list_for_each(output, &output_list, link) {
+ output->buffer = create_shm_buffer(output->width, output->height, &output->data);
+ screenshooter_shoot(screenshooter, output->output, output->buffer);
width = MAX(width, output->offset_x + output->width);
height = MAX(height, output->offset_y + output->height);
- }
-
- buffer = create_shm_buffer(width, height, &data);
-
- wl_list_for_each_safe(output, next, &output_list, link) {
- screenshooter_shoot(screenshooter, output->output, buffer);
buffer_copy_done = 0;
while (!buffer_copy_done)
wl_display_roundtrip(display);
- free(output);
}
-
- write_png(width, height, data);
+ write_png(width, height, output_list);
return 0;
}
diff --git a/src/screenshooter.c b/src/screenshooter.c
index 87f1a9a..1fddfab 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -43,16 +43,15 @@ struct screenshooter_read_pixels {
};
static void
-copy_bgra_yflip(uint8_t *dst, uint8_t *src, int height,
- int dst_stride, int src_stride)
+copy_bgra_yflip(uint8_t *dst, uint8_t *src, int height, int stride)
{
uint8_t *end;
- end = dst + height * dst_stride;
+ end = dst + height * stride;
while (dst < end) {
- memcpy(dst, src, src_stride);
- dst += dst_stride;
- src -= src_stride;
+ memcpy(dst, src, stride);
+ dst += stride;
+ src -= stride;
}
}
@@ -74,16 +73,15 @@ copy_row_swap_RB(void *vdst, void *vsrc, int bytes)
}
static void
-copy_rgba_yflip(uint8_t *dst, uint8_t *src, int height,
- int dst_stride, int src_stride)
+copy_rgba_yflip(uint8_t *dst, uint8_t *src, int height, int stride)
{
uint8_t *end;
- end = dst + height * dst_stride;
+ end = dst + height * stride;
while (dst < end) {
- copy_row_swap_RB(dst, src, src_stride);
- dst += dst_stride;
- src -= src_stride;
+ copy_row_swap_RB(dst, src, stride);
+ dst += stride;
+ src -= stride;
}
}
@@ -93,24 +91,20 @@ screenshooter_read_pixels_done(struct weston_read_pixels *base,
{
struct screenshooter_read_pixels *r =
(struct screenshooter_read_pixels *) base;
- int32_t buffer_stride, output_stride;
+ int32_t stride;
uint8_t *d, *s;
- buffer_stride = wl_shm_buffer_get_stride(r->buffer);
- output_stride = output->current->width * 4;
+ stride = wl_shm_buffer_get_stride(r->buffer);
- d = wl_shm_buffer_get_data(r->buffer) +
- output->y * buffer_stride + output->x * 4;
- s = r->base.data + output_stride * (output->current->height - 1);
+ d = wl_shm_buffer_get_data(r->buffer);
+ s = r->base.data + stride * (r->buffer->height - 1);
switch (output->compositor->read_format) {
case GL_BGRA_EXT:
- copy_bgra_yflip(d, s, output->current->height,
- buffer_stride, output_stride);
+ copy_bgra_yflip(d, s, output->current->height, stride);
break;
case GL_RGBA:
- copy_rgba_yflip(d, s, output->current->height,
- buffer_stride, output_stride);
+ copy_rgba_yflip(d, s, output->current->height, stride);
break;
default:
break;
@@ -133,7 +127,7 @@ screenshooter_shoot(struct wl_client *client,
struct weston_output *output = output_resource->data;
struct screenshooter_read_pixels *r;
struct wl_buffer *buffer = buffer_resource->data;
- int32_t output_stride;
+ int32_t stride;
if (!wl_buffer_is_shm(buffer))
return;
@@ -155,8 +149,8 @@ screenshooter_shoot(struct wl_client *client,
r->base.done = screenshooter_read_pixels_done;
r->buffer = buffer;
r->resource = resource;
- output_stride = output->current->width * 4;
- r->base.data = malloc(output_stride * output->current->height);
+ stride = output->current->width * 4;
+ r->base.data = malloc(stride * buffer->height);
if (r->base.data == NULL) {
free(r);
--
1.7.4.1
More information about the wayland-devel
mailing list