From 4afc933ea4946e00977c18dbed5dea47ddf8b204 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Wed, 31 Jan 2018 12:54:57 +0100 Subject: [PATCH 1/3] fixes 90 degree rotation screenshots This fixes the screenshot example application when an output is rotated by 90 degrees. Other tranformations are not taken into account yet. --- examples/screenshot.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/examples/screenshot.c b/examples/screenshot.c index ba225023..12892476 100644 --- a/examples/screenshot.c +++ b/examples/screenshot.c @@ -48,6 +48,7 @@ struct screenshooter_output { struct wl_output *output; struct wl_buffer *buffer; int width, height, offset_x, offset_y; + int transform; void *data; struct wl_list link; }; @@ -60,6 +61,7 @@ static void output_handle_geometry(void *data, struct wl_output *wl_output, if (wl_output == output->output) { output->offset_x = x; output->offset_y = y; + output->transform = transform; } } @@ -163,10 +165,21 @@ static void write_image(const char *filename, int width, int height) { void *d = data + (output->offset_y - min_y) * buffer_stride + (output->offset_x - min_x) * 4; - for (int i = 0; i < output->height; i++) { - memcpy(d, s, output_stride); - d += buffer_stride; - s += output_stride; + if (output->transform == WL_OUTPUT_TRANSFORM_90) { + uint32_t *ss = s; + uint32_t *sd = d; + for (int i = 0; i < output->width; ++i) { + for (int j = 0; j < output->height; ++j) { + sd[i * width + j] + = ss[j * output->width + (output->width - i)]; + } + } + } else { + for (int i = 0; i < output->height; i++) { + memcpy(d, s, output_stride); + d += buffer_stride; + s += output_stride; + } } free(output); @@ -211,15 +224,23 @@ static void write_image(const char *filename, int width, int height) { } static int set_buffer_size(int *width, int *height) { + int owidth, oheight; min_x = min_y = INT_MAX; max_x = max_y = INT_MIN; struct screenshooter_output *output; wl_list_for_each(output, &output_list, link) { + if (output->transform & 0x1) { + owidth = output->height; + oheight = output->width; + } else { + owidth = output->width; + oheight = output->height; + } min_x = MIN(min_x, output->offset_x); min_y = MIN(min_y, output->offset_y); - max_x = MAX(max_x, output->offset_x + output->width); - max_y = MAX(max_y, output->offset_y + output->height); + max_x = MAX(max_x, output->offset_x + owidth); + max_y = MAX(max_y, output->offset_y + oheight); } if (max_x <= min_x || max_y <= min_y) { From 3a404e4f8d722bb6fbde0bdcd9a560179f9a52c6 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Wed, 31 Jan 2018 16:05:33 +0100 Subject: [PATCH 2/3] handle the other transformations for screenshots This handles all current transformations for outputs properly. This ensures an output is drawn in readable orientation/flipping no matter the actual transformations applied to it. --- examples/screenshot.c | 78 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/examples/screenshot.c b/examples/screenshot.c index 12892476..b305e56f 100644 --- a/examples/screenshot.c +++ b/examples/screenshot.c @@ -48,7 +48,7 @@ struct screenshooter_output { struct wl_output *output; struct wl_buffer *buffer; int width, height, offset_x, offset_y; - int transform; + enum wl_output_transform transform; void *data; struct wl_list link; }; @@ -161,25 +161,75 @@ static void write_image(const char *filename, int width, int height) { struct screenshooter_output *output, *next; wl_list_for_each_safe(output, next, &output_list, link) { int output_stride = output->width * 4; - void *s = output->data; - void *d = data + (output->offset_y - min_y) * buffer_stride + - (output->offset_x - min_x) * 4; + uint32_t *src = (uint32_t *)output->data; + uint32_t *dst = (uint32_t *)(data + + (output->offset_y - min_y) * buffer_stride + + (output->offset_x - min_x) * 4); - if (output->transform == WL_OUTPUT_TRANSFORM_90) { - uint32_t *ss = s; - uint32_t *sd = d; + switch (output->transform) { + case WL_OUTPUT_TRANSFORM_NORMAL: + for (int i = 0; i < output->height; i++) { + memcpy(dst, src, output_stride); + dst += width; + src += output->width; + } + break; + case WL_OUTPUT_TRANSFORM_FLIPPED: + for (int i = 0; i < output->height; ++i) { + for (int j = 0; j < output->width; ++j) { + dst[i * width + j] = + src[i * output->width + output->width - j]; + } + } + break; + case WL_OUTPUT_TRANSFORM_90: for (int i = 0; i < output->width; ++i) { for (int j = 0; j < output->height; ++j) { - sd[i * width + j] - = ss[j * output->width + (output->width - i)]; + dst[i * width + j] = + src[j * output->width + output->width - i]; } } - } else { - for (int i = 0; i < output->height; i++) { - memcpy(d, s, output_stride); - d += buffer_stride; - s += output_stride; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + for (int i = 0; i < output->width; ++i) { + for (int j = 0; j < output->height; ++j) { + dst[i * width + j] = + src[(output->height - j) * output->width + output->width - i]; + } + } + break; + case WL_OUTPUT_TRANSFORM_180: + for (int i = 0; i < output->height; ++i) { + for (int j = 0; j < output->width; ++j) { + dst[i * width + j] = + src[(output->height - i) * output->width + output->width - j]; + } + } + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + for (int i = 0; i < output->height; ++i) { + for (int j = 0; j < output->width; ++j) { + dst[i * width + j] = + src[(output->height - i) * output->width + j]; + } + } + break; + case WL_OUTPUT_TRANSFORM_270: + for (int i = 0; i < output->width; ++i) { + for (int j = 0; j < output->height; ++j) { + dst[i * width + j] = + src[(output->height - j) * output->width + i]; + } + } + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + for (int i = 0; i < output->width; ++i) { + for (int j = 0; j < output->height; ++j) { + dst[i * width + j] = + src[j * output->width + i]; + } } + break; } free(output); From cd925f496c2e1f644de0ff7f79f7dce49759e769 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Thu, 1 Feb 2018 21:36:14 +0100 Subject: [PATCH 3/3] fixes the off by one errors in examples/screenshot The inverse loop iterations for the transformed outputs had an off by one error, iterating 1 based, not 0 based. This commit fixes that. --- examples/screenshot.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/screenshot.c b/examples/screenshot.c index b305e56f..7de2ab8e 100644 --- a/examples/screenshot.c +++ b/examples/screenshot.c @@ -178,7 +178,7 @@ static void write_image(const char *filename, int width, int height) { for (int i = 0; i < output->height; ++i) { for (int j = 0; j < output->width; ++j) { dst[i * width + j] = - src[i * output->width + output->width - j]; + src[i * output->width + output->width - 1 - j]; } } break; @@ -186,7 +186,7 @@ static void write_image(const char *filename, int width, int height) { for (int i = 0; i < output->width; ++i) { for (int j = 0; j < output->height; ++j) { dst[i * width + j] = - src[j * output->width + output->width - i]; + src[j * output->width + output->width - 1 - i]; } } break; @@ -194,7 +194,7 @@ static void write_image(const char *filename, int width, int height) { for (int i = 0; i < output->width; ++i) { for (int j = 0; j < output->height; ++j) { dst[i * width + j] = - src[(output->height - j) * output->width + output->width - i]; + src[(output->height - 1 - j) * output->width + output->width - 1 - i]; } } break; @@ -202,7 +202,7 @@ static void write_image(const char *filename, int width, int height) { for (int i = 0; i < output->height; ++i) { for (int j = 0; j < output->width; ++j) { dst[i * width + j] = - src[(output->height - i) * output->width + output->width - j]; + src[(output->height - 1 - i) * output->width + output->width - 1 - j]; } } break; @@ -210,7 +210,7 @@ static void write_image(const char *filename, int width, int height) { for (int i = 0; i < output->height; ++i) { for (int j = 0; j < output->width; ++j) { dst[i * width + j] = - src[(output->height - i) * output->width + j]; + src[(output->height - 1 - i) * output->width + j]; } } break; @@ -218,7 +218,7 @@ static void write_image(const char *filename, int width, int height) { for (int i = 0; i < output->width; ++i) { for (int j = 0; j < output->height; ++j) { dst[i * width + j] = - src[(output->height - j) * output->width + i]; + src[(output->height - 1 - j) * output->width + i]; } } break;