From 0b3d56384ff7605c550f1cfc2a7313082085bed1 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 10 Aug 2017 15:14:41 -0400 Subject: [PATCH 01/12] implement surface_damage_buffer --- types/wlr_surface.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 3a12f3a6..ebeda20e 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -107,6 +107,7 @@ static void surface_commit(struct wl_client *client, // &surface->current.surface_damage, // 0, 0, surface->width, surface->height); pixman_region32_clear(&surface->pending.surface_damage); + pixman_region32_clear(&surface->pending.buffer_damage); } // TODO: Commit other changes @@ -151,6 +152,9 @@ void wlr_surface_flush_damage(struct wlr_surface *surface) { } pixman_region32_fini(&surface->current.surface_damage); pixman_region32_init(&surface->current.surface_damage); + + pixman_region32_fini(&surface->current.buffer_damage); + pixman_region32_init(&surface->current.buffer_damage); release: wl_resource_queue_event(surface->current.buffer, WL_BUFFER_RELEASE); } @@ -170,7 +174,14 @@ static void surface_damage_buffer(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) { - wlr_log(L_DEBUG, "TODO: surface damage buffer"); + struct wlr_surface *surface = wl_resource_get_user_data(resource); + if (width < 0 || height < 0) { + return; + } + surface->pending.invalid |= WLR_SURFACE_INVALID_SURFACE_DAMAGE; + pixman_region32_union_rect(&surface->pending.buffer_damage, + &surface->pending.buffer_damage, + x, y, width, height); } const struct wl_surface_interface surface_interface = { From e22e443717fcdae72d4e2e9db22f9929ab010643 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 11 Aug 2017 11:48:59 -0400 Subject: [PATCH 02/12] fix formatting in surface_damage --- types/wlr_surface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/wlr_surface.c b/types/wlr_surface.c index ebeda20e..3151673c 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -27,8 +27,8 @@ static void surface_damage(struct wl_client *client, } surface->pending.invalid |= WLR_SURFACE_INVALID_SURFACE_DAMAGE; pixman_region32_union_rect(&surface->pending.surface_damage, - &surface->pending.surface_damage, - x, y, width, height); + &surface->pending.surface_damage, + x, y, width, height); } static void destroy_frame_callback(struct wl_resource *resource) { From f0f190bfa5b7ebf2dbb5cc62e20e3b80038382b4 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 13 Aug 2017 17:54:27 -0400 Subject: [PATCH 03/12] implement buffer scale Keep track of the scale of the buffer set by surface.set_buffer_scale. Calculate the height and width of the texture from the buffer depending on the scale when it is attached. Use buffer damage to determine the damage of the buffer when flushing damage. Convert surface damage to buffer damage and union to the surface buffer_damage prior to flushing damage. --- include/wlr/render.h | 1 + types/wlr_surface.c | 53 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/include/wlr/render.h b/include/wlr/render.h index 96b61ddf..90081b7a 100644 --- a/include/wlr/render.h +++ b/include/wlr/render.h @@ -61,6 +61,7 @@ struct wlr_texture { bool valid; uint32_t format; int width, height; + int height_from_buffer, width_from_buffer; struct wl_signal destroy_signal; struct wl_resource *resource; }; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 3151673c..e862d00e 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -14,8 +14,11 @@ static void surface_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, int32_t sx, int32_t sy) { struct wlr_surface *surface = wl_resource_get_user_data(resource); + int scale = surface->current.scale; surface->pending.invalid |= WLR_SURFACE_INVALID_BUFFER; surface->pending.buffer = buffer; + surface->texture->height_from_buffer = surface->texture->height / scale; + surface->texture->width_from_buffer = surface->texture->width / scale; } static void surface_damage(struct wl_client *client, @@ -90,18 +93,59 @@ static void surface_set_input_region(struct wl_client *client, } } +static void wlr_surface_to_buffer_region(struct wlr_surface *surface, + pixman_region32_t *surface_region, pixman_region32_t *buffer_region) { + pixman_box32_t *src_rects, *dest_rects; + int nrects, i; + int scale = surface->current.scale; + + src_rects = pixman_region32_rectangles(surface_region, &nrects); + dest_rects = malloc(nrects * sizeof(*dest_rects)); + if (!dest_rects) { + return; + } + + for (i = 0; i < nrects; i++) { + dest_rects[i].x1 = src_rects[i].x1 * scale; + dest_rects[i].y1 = src_rects[i].y1 * scale; + dest_rects[i].x2 = src_rects[i].x2 * scale; + dest_rects[i].y2 = src_rects[i].y2 * scale; + } + + pixman_region32_fini(buffer_region); + pixman_region32_init_rects(buffer_region, dest_rects, nrects); + free(dest_rects); +} + static void surface_commit(struct wl_client *client, struct wl_resource *resource) { struct wlr_surface *surface = wl_resource_get_user_data(resource); + surface->current.scale = surface->pending.scale; if ((surface->pending.invalid & WLR_SURFACE_INVALID_BUFFER)) { surface->current.buffer = surface->pending.buffer; } if ((surface->pending.invalid & WLR_SURFACE_INVALID_SURFACE_DAMAGE)) { - // TODO: Sort out buffer damage too pixman_region32_union(&surface->current.surface_damage, &surface->current.surface_damage, &surface->pending.surface_damage); + + pixman_region32_union(&surface->current.buffer_damage, + &surface->current.buffer_damage, + &surface->pending.buffer_damage); + + pixman_region32_t buffer_damage; + wlr_surface_to_buffer_region(surface, &surface->current.surface_damage, + &buffer_damage); + pixman_region32_union(&surface->current.buffer_damage, + &surface->current.buffer_damage, &buffer_damage); + + struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current.buffer); + pixman_region32_intersect_rect(&surface->current.buffer_damage, + &surface->current.buffer_damage, 0, 0, + wl_shm_buffer_get_width(buffer), + wl_shm_buffer_get_height(buffer)); + // TODO: Surface sizing is complicated //pixman_region32_intersect_rect(&surface->current.surface_damage, // &surface->current.surface_damage, @@ -133,7 +177,7 @@ void wlr_surface_flush_damage(struct wlr_surface *surface) { return; } } - pixman_region32_t damage = surface->current.surface_damage; + pixman_region32_t damage = surface->current.buffer_damage; if (!pixman_region32_not_empty(&damage)) { goto release; } @@ -167,7 +211,8 @@ static void surface_set_buffer_transform(struct wl_client *client, static void surface_set_buffer_scale(struct wl_client *client, struct wl_resource *resource, int32_t scale) { - wlr_log(L_DEBUG, "TODO: surface set buffer scale"); + struct wlr_surface *surface = wl_resource_get_user_data(resource); + surface->pending.scale = scale; } static void surface_damage_buffer(struct wl_client *client, @@ -215,6 +260,8 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res, surface->renderer = renderer; surface->texture = wlr_render_texture_init(renderer); surface->resource = res; + surface->current.scale = 1; + surface->pending.scale = 1; wl_signal_init(&surface->signals.commit); wl_list_init(&surface->frame_callback_list); wl_resource_set_implementation(res, &surface_interface, From 72a33b736fdf2a03d45010182b16532df0753690 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 14 Aug 2017 13:28:59 -0400 Subject: [PATCH 04/12] implement texture get buffer size --- include/wlr/render/interface.h | 4 ++++ render/gles2/texture.c | 13 +++++++++++++ render/wlr_texture.c | 5 +++++ types/wlr_surface.c | 12 ++++-------- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index 59ece8b1..f98c3bc2 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -46,6 +46,8 @@ struct wlr_texture_impl { struct wl_resource *drm_buf); void (*get_matrix)(struct wlr_texture *state, float (*matrix)[16], const float (*projection)[16], int x, int y); + void (*get_buffer_size)(struct wlr_texture *texture, + struct wl_resource *resource, int *width, int *height); void (*bind)(struct wlr_texture *texture); void (*destroy)(struct wlr_texture *texture); }; @@ -53,5 +55,7 @@ struct wlr_texture_impl { void wlr_texture_init(struct wlr_texture *texture, struct wlr_texture_impl *impl); void wlr_texture_bind(struct wlr_texture *texture); +void wlr_texture_get_buffer_size(struct wlr_texture *texture, + struct wl_resource *resource, int *width, int *height); #endif diff --git a/render/gles2/texture.c b/render/gles2/texture.c index 1e80a8d6..1f4ae22c 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -218,6 +218,18 @@ static void gles2_texture_get_matrix(struct wlr_texture *_texture, wlr_matrix_mul(projection, matrix, matrix); } +static void gles2_texture_get_buffer_size(struct wlr_texture *texture, struct + wl_resource *resource, int *width, int *height) { + struct wl_shm_buffer *buffer = wl_shm_buffer_get(resource); + if (!buffer) { + wlr_log(L_ERROR, "getting buffer size is only implemented for shm buffers"); + return; + } + + *width = wl_shm_buffer_get_width(buffer); + *height = wl_shm_buffer_get_height(buffer); +} + static void gles2_texture_bind(struct wlr_texture *_texture) { struct wlr_gles2_texture *texture = (struct wlr_gles2_texture *)_texture; GL_CALL(glBindTexture(GL_TEXTURE_2D, texture->tex_id)); @@ -247,6 +259,7 @@ static struct wlr_texture_impl wlr_texture_impl = { .update_shm = gles2_texture_update_shm, .upload_drm = gles2_texture_upload_drm, .get_matrix = gles2_texture_get_matrix, + .get_buffer_size = gles2_texture_get_buffer_size, .bind = gles2_texture_bind, .destroy = gles2_texture_destroy, }; diff --git a/render/wlr_texture.c b/render/wlr_texture.c index f98284a1..9faea820 100644 --- a/render/wlr_texture.c +++ b/render/wlr_texture.c @@ -52,3 +52,8 @@ void wlr_texture_get_matrix(struct wlr_texture *texture, float (*matrix)[16], const float (*projection)[16], int x, int y) { texture->impl->get_matrix(texture, matrix, projection, x, y); } + +void wlr_texture_get_buffer_size(struct wlr_texture *texture, struct wl_resource + *resource, int *width, int *height) { + texture->impl->get_buffer_size(texture, resource, width, height); +} diff --git a/types/wlr_surface.c b/types/wlr_surface.c index e862d00e..0861e2e8 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -126,6 +126,9 @@ static void surface_commit(struct wl_client *client, surface->current.buffer = surface->pending.buffer; } if ((surface->pending.invalid & WLR_SURFACE_INVALID_SURFACE_DAMAGE)) { + int width, height; + wlr_texture_get_buffer_size(surface->texture, surface->current.buffer, &width, &height); + pixman_region32_union(&surface->current.surface_damage, &surface->current.surface_damage, &surface->pending.surface_damage); @@ -140,16 +143,9 @@ static void surface_commit(struct wl_client *client, pixman_region32_union(&surface->current.buffer_damage, &surface->current.buffer_damage, &buffer_damage); - struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current.buffer); pixman_region32_intersect_rect(&surface->current.buffer_damage, - &surface->current.buffer_damage, 0, 0, - wl_shm_buffer_get_width(buffer), - wl_shm_buffer_get_height(buffer)); + &surface->current.buffer_damage, 0, 0, width, height); - // TODO: Surface sizing is complicated - //pixman_region32_intersect_rect(&surface->current.surface_damage, - // &surface->current.surface_damage, - // 0, 0, surface->width, surface->height); pixman_region32_clear(&surface->pending.surface_damage); pixman_region32_clear(&surface->pending.buffer_damage); } From d87c58416ba32c265b905b6eca8b2a59c6233af5 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 14 Aug 2017 13:29:21 -0400 Subject: [PATCH 05/12] clip surface damage to surface size --- types/wlr_surface.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 0861e2e8..a94ed4c5 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -132,6 +132,9 @@ static void surface_commit(struct wl_client *client, pixman_region32_union(&surface->current.surface_damage, &surface->current.surface_damage, &surface->pending.surface_damage); + pixman_region32_intersect_rect(&surface->current.surface_damage, + &surface->current.surface_damage, 0, 0, width / + surface->current.scale, height / surface->current.scale); pixman_region32_union(&surface->current.buffer_damage, &surface->current.buffer_damage, From b49650b5552d4323a23a1662761d87bb084421a4 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 14 Aug 2017 13:29:41 -0400 Subject: [PATCH 06/12] initialize buffer damage before conversion --- types/wlr_surface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/types/wlr_surface.c b/types/wlr_surface.c index a94ed4c5..b1f273af 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -141,6 +141,7 @@ static void surface_commit(struct wl_client *client, &surface->pending.buffer_damage); pixman_region32_t buffer_damage; + pixman_region32_init(&buffer_damage); wlr_surface_to_buffer_region(surface, &surface->current.surface_damage, &buffer_damage); pixman_region32_union(&surface->current.buffer_damage, From e46ec57b43054705a6ff649ba358c5d14cccbca5 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 14 Aug 2017 13:54:57 -0400 Subject: [PATCH 07/12] implement surface sizing --- examples/compositor/main.c | 4 ++-- include/wlr/types/wlr_surface.h | 2 ++ types/wlr_surface.c | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/examples/compositor/main.c b/examples/compositor/main.c index 933e27c7..079f0243 100644 --- a/examples/compositor/main.c +++ b/examples/compositor/main.c @@ -45,8 +45,8 @@ void handle_output_frame(struct output_state *output, struct timespec *ts) { struct wlr_surface *surface = wl_resource_get_user_data(_res); wlr_surface_flush_damage(surface); if (surface->texture->valid) { - wlr_texture_get_matrix(surface->texture, &matrix, - &wlr_output->transform_matrix, 200, 200); + wlr_surface_get_matrix(surface, &matrix, + &wlr_output->transform_matrix, 200, 200); wlr_render_with_matrix(sample->renderer, surface->texture, &matrix); struct wlr_frame_callback *cb, *cnext; diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 60d8b2f6..d3104741 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -53,5 +53,7 @@ struct wlr_renderer; struct wlr_surface *wlr_surface_create(struct wl_resource *res, struct wlr_renderer *renderer); void wlr_surface_flush_damage(struct wlr_surface *surface); +void wlr_surface_get_matrix(struct wlr_surface *surface, float (*matrix)[16], + const float (*projection)[16], int x, int y); #endif diff --git a/types/wlr_surface.c b/types/wlr_surface.c index b1f273af..12220807 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -5,6 +5,7 @@ #include #include #include +#include static void surface_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); @@ -268,3 +269,16 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res, surface, destroy_surface); return surface; } + +void wlr_surface_get_matrix(struct wlr_surface *surface, + float (*matrix)[16], const float (*projection)[16], int x, int y) { + int width = surface->texture->width / surface->current.scale; + int height = surface->texture->height / surface->current.scale; + float world[16]; + wlr_matrix_identity(matrix); + wlr_matrix_translate(&world, x, y, 0); + wlr_matrix_mul(matrix, &world, matrix); + wlr_matrix_scale(&world, width, height, 1); + wlr_matrix_mul(matrix, &world, matrix); + wlr_matrix_mul(projection, matrix, matrix); +} From 84c6dbd58d0dc862488c9c6364f9f78276a893f0 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 14 Aug 2017 15:32:20 -0400 Subject: [PATCH 08/12] remove unused dimension from buffer calculations --- include/wlr/render.h | 1 - types/wlr_surface.c | 3 --- 2 files changed, 4 deletions(-) diff --git a/include/wlr/render.h b/include/wlr/render.h index 90081b7a..96b61ddf 100644 --- a/include/wlr/render.h +++ b/include/wlr/render.h @@ -61,7 +61,6 @@ struct wlr_texture { bool valid; uint32_t format; int width, height; - int height_from_buffer, width_from_buffer; struct wl_signal destroy_signal; struct wl_resource *resource; }; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 12220807..2345bfd1 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -15,11 +15,8 @@ static void surface_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, int32_t sx, int32_t sy) { struct wlr_surface *surface = wl_resource_get_user_data(resource); - int scale = surface->current.scale; surface->pending.invalid |= WLR_SURFACE_INVALID_BUFFER; surface->pending.buffer = buffer; - surface->texture->height_from_buffer = surface->texture->height / scale; - surface->texture->width_from_buffer = surface->texture->width / scale; } static void surface_damage(struct wl_client *client, From 5b1ce84350d78fa1bf7dc8ff421ae7c919542346 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 14 Aug 2017 16:30:53 -0400 Subject: [PATCH 09/12] implement buffer transform --- include/wlr/types/wlr_surface.h | 2 +- types/wlr_surface.c | 107 +++++++++++++++++++++++++++++--- 2 files changed, 98 insertions(+), 11 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index d3104741..6dbee113 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -23,7 +23,7 @@ struct wlr_surface_state { int32_t sx, sy; pixman_region32_t surface_damage, buffer_damage; pixman_region32_t opaque, input; - uint32_t transform; + enum wl_output_transform transform; int32_t scale; }; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 2345bfd1..1872ac3b 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -91,11 +91,33 @@ static void surface_set_input_region(struct wl_client *client, } } +static void wlr_surface_get_effective_size(struct wlr_surface *surface, + int swidth, int sheight, int *width, int *height) { + int scale = surface->current.scale; + enum wl_output_transform transform = surface->current.transform; + int _width = swidth / scale; + int _height = sheight / scale; + + if (transform == WL_OUTPUT_TRANSFORM_90 || + transform == WL_OUTPUT_TRANSFORM_270 || + transform == WL_OUTPUT_TRANSFORM_FLIPPED_90 || + transform == WL_OUTPUT_TRANSFORM_FLIPPED_270) { + int tmp = _width; + _width = _height; + _height = tmp; + } + + *width = _width; + *height = _height; +} + static void wlr_surface_to_buffer_region(struct wlr_surface *surface, - pixman_region32_t *surface_region, pixman_region32_t *buffer_region) { + pixman_region32_t *surface_region, pixman_region32_t *buffer_region, + int width, int height) { pixman_box32_t *src_rects, *dest_rects; int nrects, i; int scale = surface->current.scale; + enum wl_output_transform transform = surface->current.transform; src_rects = pixman_region32_rectangles(surface_region, &nrects); dest_rects = malloc(nrects * sizeof(*dest_rects)); @@ -104,10 +126,66 @@ static void wlr_surface_to_buffer_region(struct wlr_surface *surface, } for (i = 0; i < nrects; i++) { - dest_rects[i].x1 = src_rects[i].x1 * scale; - dest_rects[i].y1 = src_rects[i].y1 * scale; - dest_rects[i].x2 = src_rects[i].x2 * scale; - dest_rects[i].y2 = src_rects[i].y2 * scale; + switch (transform) { + default: + case WL_OUTPUT_TRANSFORM_NORMAL: + dest_rects[i].x1 = src_rects[i].x1; + dest_rects[i].y1 = src_rects[i].y1; + dest_rects[i].x2 = src_rects[i].x2; + dest_rects[i].y2 = src_rects[i].y2; + break; + case WL_OUTPUT_TRANSFORM_90: + dest_rects[i].x1 = height - src_rects[i].y2; + dest_rects[i].y1 = src_rects[i].x1; + dest_rects[i].x2 = height - src_rects[i].y1; + dest_rects[i].y2 = src_rects[i].x2; + break; + case WL_OUTPUT_TRANSFORM_180: + dest_rects[i].x1 = width - src_rects[i].x2; + dest_rects[i].y1 = height - src_rects[i].y2; + dest_rects[i].x2 = width - src_rects[i].x1; + dest_rects[i].y2 = height - src_rects[i].y1; + break; + case WL_OUTPUT_TRANSFORM_270: + dest_rects[i].x1 = src_rects[i].y1; + dest_rects[i].y1 = width - src_rects[i].x2; + dest_rects[i].x2 = src_rects[i].y2; + dest_rects[i].y2 = width - src_rects[i].x1; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED: + dest_rects[i].x1 = width - src_rects[i].x2; + dest_rects[i].y1 = src_rects[i].y1; + dest_rects[i].x2 = width - src_rects[i].x1; + dest_rects[i].y2 = src_rects[i].y2; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + dest_rects[i].x1 = height - src_rects[i].y2; + dest_rects[i].y1 = width - src_rects[i].x2; + dest_rects[i].x2 = height - src_rects[i].y1; + dest_rects[i].y2 = width - src_rects[i].x1; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + dest_rects[i].x1 = src_rects[i].x1; + dest_rects[i].y1 = height - src_rects[i].y2; + dest_rects[i].x2 = src_rects[i].x2; + dest_rects[i].y2 = height - src_rects[i].y1; + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + dest_rects[i].x1 = src_rects[i].y1; + dest_rects[i].y1 = src_rects[i].x1; + dest_rects[i].x2 = src_rects[i].y2; + dest_rects[i].y2 = src_rects[i].x2; + break; + } + } + + if (scale != 1) { + for (i = 0; i < nrects; i++) { + dest_rects[i].x1 *= scale; + dest_rects[i].x2 *= scale; + dest_rects[i].y1 *= scale; + dest_rects[i].y2 *= scale; + } } pixman_region32_fini(buffer_region); @@ -119,20 +197,26 @@ static void surface_commit(struct wl_client *client, struct wl_resource *resource) { struct wlr_surface *surface = wl_resource_get_user_data(resource); surface->current.scale = surface->pending.scale; + surface->current.transform = surface->pending.transform; if ((surface->pending.invalid & WLR_SURFACE_INVALID_BUFFER)) { surface->current.buffer = surface->pending.buffer; } if ((surface->pending.invalid & WLR_SURFACE_INVALID_SURFACE_DAMAGE)) { int width, height; - wlr_texture_get_buffer_size(surface->texture, surface->current.buffer, &width, &height); + wlr_texture_get_buffer_size(surface->texture, surface->current.buffer, + &width, &height); + + int surface_width, surface_height; + wlr_surface_get_effective_size(surface, width, height, &surface_width, + &surface_height); pixman_region32_union(&surface->current.surface_damage, &surface->current.surface_damage, &surface->pending.surface_damage); pixman_region32_intersect_rect(&surface->current.surface_damage, - &surface->current.surface_damage, 0, 0, width / - surface->current.scale, height / surface->current.scale); + &surface->current.surface_damage, 0, 0, surface_width, + surface_height); pixman_region32_union(&surface->current.buffer_damage, &surface->current.buffer_damage, @@ -141,7 +225,7 @@ static void surface_commit(struct wl_client *client, pixman_region32_t buffer_damage; pixman_region32_init(&buffer_damage); wlr_surface_to_buffer_region(surface, &surface->current.surface_damage, - &buffer_damage); + &buffer_damage, surface_width, surface_height); pixman_region32_union(&surface->current.buffer_damage, &surface->current.buffer_damage, &buffer_damage); @@ -203,7 +287,8 @@ release: static void surface_set_buffer_transform(struct wl_client *client, struct wl_resource *resource, int transform) { - wlr_log(L_DEBUG, "TODO: surface surface buffer transform"); + struct wlr_surface *surface = wl_resource_get_user_data(resource); + surface->pending.transform = transform; } static void surface_set_buffer_scale(struct wl_client *client, @@ -260,6 +345,8 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res, surface->resource = res; surface->current.scale = 1; surface->pending.scale = 1; + surface->current.transform = WL_OUTPUT_TRANSFORM_NORMAL; + surface->pending.transform = WL_OUTPUT_TRANSFORM_NORMAL; wl_signal_init(&surface->signals.commit); wl_list_init(&surface->frame_callback_list); wl_resource_set_implementation(res, &surface_interface, From 2bf2dbb2bd85d9cd471d784c25ad6a21d1c7a6a5 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 15 Aug 2017 07:40:26 -0400 Subject: [PATCH 10/12] formatting fixup --- types/wlr_surface.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 1872ac3b..98a5ac27 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -58,7 +58,7 @@ static void surface_frame(struct wl_client *client, } wl_resource_set_implementation(cb->resource, - NULL, cb, destroy_frame_callback); + NULL, cb, destroy_frame_callback); wl_list_insert(surface->frame_callback_list.prev, &cb->link); } @@ -87,7 +87,7 @@ static void surface_set_input_region(struct wl_client *client, } else { pixman_region32_fini(&surface->pending.input); pixman_region32_init_rect(&surface->pending.input, - INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); + INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); } } @@ -212,8 +212,8 @@ static void surface_commit(struct wl_client *client, &surface_height); pixman_region32_union(&surface->current.surface_damage, - &surface->current.surface_damage, - &surface->pending.surface_damage); + &surface->current.surface_damage, + &surface->pending.surface_damage); pixman_region32_intersect_rect(&surface->current.surface_damage, &surface->current.surface_damage, 0, 0, surface_width, surface_height); @@ -350,7 +350,7 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res, wl_signal_init(&surface->signals.commit); wl_list_init(&surface->frame_callback_list); wl_resource_set_implementation(res, &surface_interface, - surface, destroy_surface); + surface, destroy_surface); return surface; } From 4f2b1cc930b3f805358571e809ccba4bf6d6272c Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 15 Aug 2017 07:58:07 -0400 Subject: [PATCH 11/12] implement get_buffer_size for egl buffers --- render/gles2/texture.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/render/gles2/texture.c b/render/gles2/texture.c index 1f4ae22c..4eb79374 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -222,7 +222,19 @@ static void gles2_texture_get_buffer_size(struct wlr_texture *texture, struct wl_resource *resource, int *width, int *height) { struct wl_shm_buffer *buffer = wl_shm_buffer_get(resource); if (!buffer) { - wlr_log(L_ERROR, "getting buffer size is only implemented for shm buffers"); + struct wlr_gles2_texture *tex = (struct wlr_gles2_texture *)texture; + if (!glEGLImageTargetTexture2DOES) { + return; + } + if (!wlr_egl_query_buffer(tex->egl, resource, EGL_WIDTH, + (EGLint*)&width)) { + wlr_log(L_ERROR, "could not get size of the buffer " + "(no buffer found)"); + return; + }; + wlr_egl_query_buffer(tex->egl, resource, EGL_HEIGHT, + (EGLint*)&height); + return; } From d5f98dbf61e3627f46c499a2ecac0e581241299b Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 15 Aug 2017 08:17:17 -0400 Subject: [PATCH 12/12] refactor getting surface size into a function --- include/wlr/types/wlr_surface.h | 2 ++ types/wlr_surface.c | 32 +++++++++++++++----------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 6dbee113..811097ad 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -25,6 +25,8 @@ struct wlr_surface_state { pixman_region32_t opaque, input; enum wl_output_transform transform; int32_t scale; + int width, height; + int buffer_width, buffer_height; }; struct wlr_surface { diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 98a5ac27..77acff02 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -91,12 +91,15 @@ static void surface_set_input_region(struct wl_client *client, } } -static void wlr_surface_get_effective_size(struct wlr_surface *surface, - int swidth, int sheight, int *width, int *height) { +static void wlr_surface_update_size(struct wlr_surface *surface) { int scale = surface->current.scale; enum wl_output_transform transform = surface->current.transform; - int _width = swidth / scale; - int _height = sheight / scale; + + wlr_texture_get_buffer_size(surface->texture, surface->current.buffer, + &surface->current.buffer_width, &surface->current.buffer_height); + + int _width = surface->current.buffer_width / scale; + int _height = surface->current.buffer_height / scale; if (transform == WL_OUTPUT_TRANSFORM_90 || transform == WL_OUTPUT_TRANSFORM_270 || @@ -107,8 +110,8 @@ static void wlr_surface_get_effective_size(struct wlr_surface *surface, _height = tmp; } - *width = _width; - *height = _height; + surface->current.width = _width; + surface->current.height = _height; } static void wlr_surface_to_buffer_region(struct wlr_surface *surface, @@ -203,20 +206,14 @@ static void surface_commit(struct wl_client *client, surface->current.buffer = surface->pending.buffer; } if ((surface->pending.invalid & WLR_SURFACE_INVALID_SURFACE_DAMAGE)) { - int width, height; - wlr_texture_get_buffer_size(surface->texture, surface->current.buffer, - &width, &height); - - int surface_width, surface_height; - wlr_surface_get_effective_size(surface, width, height, &surface_width, - &surface_height); + wlr_surface_update_size(surface); pixman_region32_union(&surface->current.surface_damage, &surface->current.surface_damage, &surface->pending.surface_damage); pixman_region32_intersect_rect(&surface->current.surface_damage, - &surface->current.surface_damage, 0, 0, surface_width, - surface_height); + &surface->current.surface_damage, 0, 0, surface->current.width, + surface->current.height); pixman_region32_union(&surface->current.buffer_damage, &surface->current.buffer_damage, @@ -225,12 +222,13 @@ static void surface_commit(struct wl_client *client, pixman_region32_t buffer_damage; pixman_region32_init(&buffer_damage); wlr_surface_to_buffer_region(surface, &surface->current.surface_damage, - &buffer_damage, surface_width, surface_height); + &buffer_damage, surface->current.width, surface->current.height); pixman_region32_union(&surface->current.buffer_damage, &surface->current.buffer_damage, &buffer_damage); pixman_region32_intersect_rect(&surface->current.buffer_damage, - &surface->current.buffer_damage, 0, 0, width, height); + &surface->current.buffer_damage, 0, 0, + surface->current.buffer_width, surface->current.buffer_height); pixman_region32_clear(&surface->pending.surface_damage); pixman_region32_clear(&surface->pending.buffer_damage);