From 3ee86b6105d72e9b0965fd1d0dc546c204552686 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 20 Jun 2018 22:35:59 +0100 Subject: [PATCH 01/14] surface: rename invalid state --- include/wlr/types/wlr_surface.h | 29 ++++++++++-------- types/wlr_surface.c | 53 ++++++++++++++++----------------- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 46588f0a..2ea4e35a 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -8,18 +8,21 @@ #include #include -#define WLR_SURFACE_INVALID_BUFFER 1 -#define WLR_SURFACE_INVALID_SURFACE_DAMAGE 2 -#define WLR_SURFACE_INVALID_BUFFER_DAMAGE 4 -#define WLR_SURFACE_INVALID_OPAQUE_REGION 8 -#define WLR_SURFACE_INVALID_INPUT_REGION 16 -#define WLR_SURFACE_INVALID_TRANSFORM 32 -#define WLR_SURFACE_INVALID_SCALE 64 -#define WLR_SURFACE_INVALID_SUBSURFACE_POSITION 128 -#define WLR_SURFACE_INVALID_FRAME_CALLBACK_LIST 256 +enum wlr_surface_state_field { + WLR_SURFACE_STATE_BUFFER = 1, + WLR_SURFACE_STATE_SURFACE_DAMAGE = 2, + WLR_SURFACE_STATE_BUFFER_DAMAGE = 2, + WLR_SURFACE_STATE_OPAQUE_REGION = 8, + WLR_SURFACE_STATE_INPUT_REGION = 16, + WLR_SURFACE_STATE_TRANSFORM = 32, + WLR_SURFACE_STATE_SCALE = 64, + WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 128, + WLR_SURFACE_STATE_SUBSURFACE_POSITION = 256, +}; struct wlr_surface_state { - uint32_t invalid; + uint32_t committed; // enum wlr_surface_state_field + struct wl_resource *buffer; struct wl_listener buffer_destroy_listener; int32_t sx, sy; @@ -27,14 +30,14 @@ 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 wl_list frame_callback_list; // wl_resource struct { int32_t x, y; } subsurface_position; - struct wl_list frame_callback_list; // wl_surface.frame + int width, height; // in surface-local coordinates + int buffer_width, buffer_height; }; struct wlr_subsurface { diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 9c32bda2..0d50a366 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -67,7 +67,7 @@ static void surface_attach(struct wl_client *client, struct wl_resource *buffer, int32_t sx, int32_t sy) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - surface->pending->invalid |= WLR_SURFACE_INVALID_BUFFER; + surface->pending->committed |= WLR_SURFACE_STATE_BUFFER; surface->pending->sx = sx; surface->pending->sy = sy; surface_state_set_buffer(surface->pending, buffer); @@ -80,7 +80,7 @@ static void surface_damage(struct wl_client *client, if (width < 0 || height < 0) { return; } - surface->pending->invalid |= WLR_SURFACE_INVALID_SURFACE_DAMAGE; + surface->pending->committed |= WLR_SURFACE_STATE_SURFACE_DAMAGE; pixman_region32_union_rect(&surface->pending->surface_damage, &surface->pending->surface_damage, x, y, width, height); @@ -106,17 +106,17 @@ static void surface_frame(struct wl_client *client, wl_list_insert(surface->pending->frame_callback_list.prev, wl_resource_get_link(callback_resource)); - surface->pending->invalid |= WLR_SURFACE_INVALID_FRAME_CALLBACK_LIST; + surface->pending->committed |= WLR_SURFACE_STATE_FRAME_CALLBACK_LIST; } static void surface_set_opaque_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region_resource) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - if ((surface->pending->invalid & WLR_SURFACE_INVALID_OPAQUE_REGION)) { + if ((surface->pending->committed & WLR_SURFACE_STATE_OPAQUE_REGION)) { pixman_region32_clear(&surface->pending->opaque); } - surface->pending->invalid |= WLR_SURFACE_INVALID_OPAQUE_REGION; + surface->pending->committed |= WLR_SURFACE_STATE_OPAQUE_REGION; if (region_resource) { pixman_region32_t *region = wlr_region_from_resource(region_resource); pixman_region32_copy(&surface->pending->opaque, region); @@ -128,7 +128,7 @@ static void surface_set_opaque_region(struct wl_client *client, static void surface_set_input_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region_resource) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - surface->pending->invalid |= WLR_SURFACE_INVALID_INPUT_REGION; + surface->pending->committed |= WLR_SURFACE_STATE_INPUT_REGION; if (region_resource) { pixman_region32_t *region = wlr_region_from_resource(region_resource); pixman_region32_copy(&surface->pending->input, region); @@ -159,9 +159,9 @@ static bool surface_update_size(struct wlr_surface *surface, int height = state->buffer_height / scale; if (transform == WL_OUTPUT_TRANSFORM_90 || - transform == WL_OUTPUT_TRANSFORM_270 || - transform == WL_OUTPUT_TRANSFORM_FLIPPED_90 || - transform == WL_OUTPUT_TRANSFORM_FLIPPED_270) { + transform == WL_OUTPUT_TRANSFORM_270 || + transform == WL_OUTPUT_TRANSFORM_FLIPPED_90 || + transform == WL_OUTPUT_TRANSFORM_FLIPPED_270) { int tmp = width; width = height; height = tmp; @@ -195,15 +195,15 @@ static void surface_move_state(struct wlr_surface *surface, int oldw = state->width; int oldh = state->height; - if ((next->invalid & WLR_SURFACE_INVALID_SCALE)) { + if ((next->committed & WLR_SURFACE_STATE_SCALE)) { state->scale = next->scale; update_size = true; } - if ((next->invalid & WLR_SURFACE_INVALID_TRANSFORM)) { + if ((next->committed & WLR_SURFACE_STATE_TRANSFORM)) { state->transform = next->transform; update_size = true; } - if ((next->invalid & WLR_SURFACE_INVALID_BUFFER)) { + if ((next->committed & WLR_SURFACE_STATE_BUFFER)) { surface_state_set_buffer(state, next->buffer); surface_state_reset_buffer(next); state->sx = next->sx; @@ -213,7 +213,7 @@ static void surface_move_state(struct wlr_surface *surface, if (update_size) { update_damage = surface_update_size(surface, state); } - if ((next->invalid & WLR_SURFACE_INVALID_SURFACE_DAMAGE)) { + if ((next->committed & WLR_SURFACE_STATE_SURFACE_DAMAGE)) { pixman_region32_intersect_rect(&next->surface_damage, &next->surface_damage, 0, 0, state->width, state->height); pixman_region32_union(&state->surface_damage, &state->surface_damage, @@ -221,7 +221,7 @@ static void surface_move_state(struct wlr_surface *surface, pixman_region32_clear(&next->surface_damage); update_damage = true; } - if ((next->invalid & WLR_SURFACE_INVALID_BUFFER_DAMAGE)) { + if ((next->committed & WLR_SURFACE_STATE_BUFFER_DAMAGE)) { pixman_region32_intersect_rect(&next->buffer_damage, &next->buffer_damage, 0, 0, state->buffer_width, state->buffer_height); @@ -256,15 +256,15 @@ static void surface_move_state(struct wlr_surface *surface, pixman_region32_fini(&buffer_damage); pixman_region32_fini(&surface_damage); } - if ((next->invalid & WLR_SURFACE_INVALID_OPAQUE_REGION)) { + if ((next->committed & WLR_SURFACE_STATE_OPAQUE_REGION)) { // TODO: process buffer pixman_region32_clear(&next->opaque); } - if ((next->invalid & WLR_SURFACE_INVALID_INPUT_REGION)) { + if ((next->committed & WLR_SURFACE_STATE_INPUT_REGION)) { // TODO: process buffer pixman_region32_copy(&state->input, &next->input); } - if ((next->invalid & WLR_SURFACE_INVALID_SUBSURFACE_POSITION)) { + if ((next->committed & WLR_SURFACE_STATE_SUBSURFACE_POSITION)) { // Subsurface has moved int dx = state->subsurface_position.x - next->subsurface_position.x; int dy = state->subsurface_position.y - next->subsurface_position.y; @@ -281,14 +281,14 @@ static void surface_move_state(struct wlr_surface *surface, &state->surface_damage, 0, 0, state->width, state->height); } } - if ((next->invalid & WLR_SURFACE_INVALID_FRAME_CALLBACK_LIST)) { + if ((next->committed & WLR_SURFACE_STATE_FRAME_CALLBACK_LIST)) { wl_list_insert_list(&state->frame_callback_list, &next->frame_callback_list); wl_list_init(&next->frame_callback_list); } - state->invalid |= next->invalid; - next->invalid = 0; + state->committed |= next->committed; + next->committed = 0; } static void surface_damage_subsurfaces(struct wlr_subsurface *subsurface) { @@ -350,7 +350,7 @@ static void surface_apply_damage(struct wlr_surface *surface) { } static void surface_commit_pending(struct wlr_surface *surface) { - bool invalid_buffer = surface->pending->invalid & WLR_SURFACE_INVALID_BUFFER; + bool invalid_buffer = surface->pending->committed & WLR_SURFACE_STATE_BUFFER; surface_move_state(surface, surface->pending, surface->current); @@ -375,7 +375,6 @@ static void surface_commit_pending(struct wlr_surface *surface) { surface->role_committed(surface, surface->role_data); } - // TODO: add the invalid bitfield to this callback wlr_signal_emit_safe(&surface->events.commit, surface); pixman_region32_clear(&surface->current->surface_damage); @@ -412,7 +411,7 @@ static void subsurface_parent_commit(struct wlr_subsurface *subsurface, surface_move_state(surface, subsurface->cached, surface->pending); surface_commit_pending(surface); subsurface->has_cache = false; - subsurface->cached->invalid = 0; + subsurface->cached->committed = 0; } struct wlr_subsurface *tmp; @@ -467,7 +466,7 @@ static void surface_commit(struct wl_client *client, static void surface_set_buffer_transform(struct wl_client *client, struct wl_resource *resource, int transform) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - surface->pending->invalid |= WLR_SURFACE_INVALID_TRANSFORM; + surface->pending->committed |= WLR_SURFACE_STATE_TRANSFORM; surface->pending->transform = transform; } @@ -475,7 +474,7 @@ static void surface_set_buffer_scale(struct wl_client *client, struct wl_resource *resource, int32_t scale) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - surface->pending->invalid |= WLR_SURFACE_INVALID_SCALE; + surface->pending->committed |= WLR_SURFACE_STATE_SCALE; surface->pending->scale = scale; } @@ -487,7 +486,7 @@ static void surface_damage_buffer(struct wl_client *client, if (width < 0 || height < 0) { return; } - surface->pending->invalid |= WLR_SURFACE_INVALID_BUFFER_DAMAGE; + surface->pending->committed |= WLR_SURFACE_STATE_BUFFER_DAMAGE; pixman_region32_union_rect(&surface->pending->buffer_damage, &surface->pending->buffer_damage, x, y, width, height); @@ -697,7 +696,7 @@ static void subsurface_handle_set_position(struct wl_client *client, } struct wlr_surface *surface = subsurface->surface; - surface->pending->invalid |= WLR_SURFACE_INVALID_SUBSURFACE_POSITION; + surface->pending->committed |= WLR_SURFACE_STATE_SUBSURFACE_POSITION; surface->pending->subsurface_position.x = x; surface->pending->subsurface_position.y = y; } From 64836ddfe7fe9097ed4ebe289d1ad17295c32763 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 21 Jun 2018 22:15:39 +0100 Subject: [PATCH 02/14] surface: remove wlr_surface_state.subsurface_position --- include/wlr/types/wlr_surface.h | 59 ++++++++++----------- types/wlr_surface.c | 90 ++++++++++++++++----------------- 2 files changed, 74 insertions(+), 75 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 2ea4e35a..526679d6 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -17,7 +17,6 @@ enum wlr_surface_state_field { WLR_SURFACE_STATE_TRANSFORM = 32, WLR_SURFACE_STATE_SCALE = 64, WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 128, - WLR_SURFACE_STATE_SUBSURFACE_POSITION = 256, }; struct wlr_surface_state { @@ -32,38 +31,10 @@ struct wlr_surface_state { int32_t scale; struct wl_list frame_callback_list; // wl_resource - struct { - int32_t x, y; - } subsurface_position; - int width, height; // in surface-local coordinates int buffer_width, buffer_height; }; -struct wlr_subsurface { - struct wl_resource *resource; - struct wlr_surface *surface; - struct wlr_surface *parent; - - struct wlr_surface_state *cached; - bool has_cache; - - bool synchronized; - bool reordered; - - struct wl_list parent_link; - struct wl_list parent_pending_link; - - struct wl_listener surface_destroy; - struct wl_listener parent_destroy; - - struct { - struct wl_signal destroy; - } events; - - void *data; -}; - struct wlr_surface { struct wl_resource *resource; struct wlr_renderer *renderer; @@ -97,6 +68,36 @@ struct wlr_surface { void *data; }; +struct wlr_subsurface_state { + int32_t x, y; +}; + +struct wlr_subsurface { + struct wl_resource *resource; + struct wlr_surface *surface; + struct wlr_surface *parent; + + struct wlr_subsurface_state current, pending; + + struct wlr_surface_state *cached; + bool has_cache; + + bool synchronized; + bool reordered; + + struct wl_list parent_link; + struct wl_list parent_pending_link; + + struct wl_listener surface_destroy; + struct wl_listener parent_destroy; + + struct { + struct wl_signal destroy; + } events; + + void *data; +}; + typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface, int sx, int sy, void *data); diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 0d50a366..1dab1888 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -192,9 +192,6 @@ static void surface_move_state(struct wlr_surface *surface, bool update_damage = false; bool update_size = false; - int oldw = state->width; - int oldh = state->height; - if ((next->committed & WLR_SURFACE_STATE_SCALE)) { state->scale = next->scale; update_size = true; @@ -264,23 +261,6 @@ static void surface_move_state(struct wlr_surface *surface, // TODO: process buffer pixman_region32_copy(&state->input, &next->input); } - if ((next->committed & WLR_SURFACE_STATE_SUBSURFACE_POSITION)) { - // Subsurface has moved - int dx = state->subsurface_position.x - next->subsurface_position.x; - int dy = state->subsurface_position.y - next->subsurface_position.y; - - state->subsurface_position.x = next->subsurface_position.x; - state->subsurface_position.y = next->subsurface_position.y; - next->subsurface_position.x = 0; - next->subsurface_position.y = 0; - - if (dx != 0 || dy != 0) { - pixman_region32_union_rect(&state->surface_damage, - &state->surface_damage, dx, dy, oldw, oldh); - pixman_region32_union_rect(&state->surface_damage, - &state->surface_damage, 0, 0, state->width, state->height); - } - } if ((next->committed & WLR_SURFACE_STATE_FRAME_CALLBACK_LIST)) { wl_list_insert_list(&state->frame_callback_list, &next->frame_callback_list); @@ -405,7 +385,7 @@ static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) { */ static void subsurface_parent_commit(struct wlr_subsurface *subsurface, bool synchronized) { - struct wlr_surface *surface = subsurface->surface; + struct wlr_surface *surface = subsurface->surface; if (synchronized || subsurface->synchronized) { if (subsurface->has_cache) { surface_move_state(surface, subsurface->cached, surface->pending); @@ -414,9 +394,9 @@ static void subsurface_parent_commit(struct wlr_subsurface *subsurface, subsurface->cached->committed = 0; } - struct wlr_subsurface *tmp; - wl_list_for_each(tmp, &surface->subsurfaces, parent_link) { - subsurface_parent_commit(tmp, true); + struct wlr_subsurface *subsurface; + wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) { + subsurface_parent_commit(subsurface, true); } } } @@ -432,15 +412,9 @@ static void subsurface_commit(struct wlr_subsurface *subsurface) { surface_move_state(surface, subsurface->cached, surface->pending); surface_commit_pending(surface); subsurface->has_cache = false; - } else { surface_commit_pending(surface); } - - struct wlr_subsurface *tmp; - wl_list_for_each(tmp, &surface->subsurfaces, parent_link) { - subsurface_parent_commit(tmp, false); - } } } @@ -452,14 +426,13 @@ static void surface_commit(struct wl_client *client, struct wlr_subsurface *subsurface = wlr_subsurface_from_wlr_surface(surface); subsurface_commit(subsurface); - return; + } else { + surface_commit_pending(surface); } - surface_commit_pending(surface); - - struct wlr_subsurface *tmp; - wl_list_for_each(tmp, &surface->subsurfaces, parent_link) { - subsurface_parent_commit(tmp, false); + struct wlr_subsurface *subsurface; + wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) { + subsurface_parent_commit(subsurface, false); } } @@ -695,10 +668,8 @@ static void subsurface_handle_set_position(struct wl_client *client, return; } - struct wlr_surface *surface = subsurface->surface; - surface->pending->committed |= WLR_SURFACE_STATE_SUBSURFACE_POSITION; - surface->pending->subsurface_position.x = x; - surface->pending->subsurface_position.y = y; + subsurface->pending.x = x; + subsurface->pending.y = y; } static struct wlr_subsurface *subsurface_find_sibling( @@ -805,6 +776,32 @@ static const struct wl_subsurface_interface subsurface_implementation = { .set_desync = subsurface_handle_set_desync, }; +static void subsurface_role_committed(struct wlr_surface *surface, void *data) { + struct wlr_subsurface *subsurface = data; + + if (subsurface->current.x != subsurface->pending.x || + subsurface->current.y != subsurface->pending.y) { + // Subsurface has moved + int dx = subsurface->pending.x - subsurface->current.x; + int dy = subsurface->pending.y - subsurface->current.y; + + subsurface->current.x = subsurface->pending.x; + subsurface->current.y = subsurface->pending.y; + + // TODO: take the previous size + pixman_region32_union_rect( + &subsurface->surface->pending->surface_damage, + &subsurface->surface->pending->surface_damage, dx, dy, + subsurface->surface->current->width, + subsurface->surface->current->height); + pixman_region32_union_rect( + &subsurface->surface->pending->surface_damage, + &subsurface->surface->pending->surface_damage, 0, 0, + subsurface->surface->pending->width, + subsurface->surface->pending->height); + } +} + static void subsurface_handle_parent_destroy(struct wl_listener *listener, void *data) { struct wlr_subsurface *subsurface = @@ -868,7 +865,8 @@ struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface, wl_list_insert(parent->subsurface_pending_list.prev, &subsurface->parent_pending_link); - surface->role_data = subsurface; + wlr_surface_set_role_committed(surface, subsurface_role_committed, + subsurface); struct wl_list *resource_link = wl_resource_get_link(subsurface->resource); if (resource_list != NULL) { @@ -903,8 +901,8 @@ struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface, double sx, double sy, double *sub_x, double *sub_y) { struct wlr_subsurface *subsurface; wl_list_for_each_reverse(subsurface, &surface->subsurfaces, parent_link) { - double _sub_x = subsurface->surface->current->subsurface_position.x; - double _sub_y = subsurface->surface->current->subsurface_position.y; + double _sub_x = subsurface->current.x; + double _sub_y = subsurface->current.y; struct wlr_surface *sub = wlr_surface_surface_at(subsurface->surface, sx - _sub_x, sy - _sub_y, sub_x, sub_y); if (sub != NULL) { @@ -970,9 +968,9 @@ static void surface_for_each_surface(struct wlr_surface *surface, int x, int y, struct wlr_subsurface *subsurface; wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) { - struct wlr_surface_state *state = subsurface->surface->current; - int sx = state->subsurface_position.x; - int sy = state->subsurface_position.y; + struct wlr_subsurface_state *state = &subsurface->current; + int sx = state->x; + int sy = state->y; surface_for_each_surface(subsurface->surface, x + sx, y + sy, iterator, user_data); From 3c0d672ebd9e1776f106ca7d963654893585a5ca Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 21 Jun 2018 22:39:26 +0100 Subject: [PATCH 03/14] surface: make pending and current embedded structs --- include/wlr/types/wlr_surface.h | 12 +- rootston/cursor.c | 8 +- rootston/desktop.c | 6 +- rootston/output.c | 30 ++--- rootston/wl_shell.c | 8 +- rootston/xwayland.c | 8 +- types/data_device/wlr_drag.c | 4 +- types/wlr_output.c | 32 ++--- types/wlr_surface.c | 145 +++++++++++------------ types/xdg_shell/wlr_xdg_toplevel.c | 4 +- types/xdg_shell_v6/wlr_xdg_toplevel_v6.c | 4 +- 11 files changed, 127 insertions(+), 134 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 526679d6..423cc886 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -23,7 +23,6 @@ struct wlr_surface_state { uint32_t committed; // enum wlr_surface_state_field struct wl_resource *buffer; - struct wl_listener buffer_destroy_listener; int32_t sx, sy; pixman_region32_t surface_damage, buffer_damage; pixman_region32_t opaque, input; @@ -33,6 +32,8 @@ struct wlr_surface_state { int width, height; // in surface-local coordinates int buffer_width, buffer_height; + + struct wl_listener buffer_destroy_listener; }; struct wlr_surface { @@ -45,7 +46,12 @@ struct wlr_surface { * or something went wrong with uploading the buffer. */ struct wlr_buffer *buffer; - struct wlr_surface_state *current, *pending; + /** + * `current` contains the current, committed surface state. `pending` + * accumulates state changes from the client between commits and shouldn't + * be accessed by the compositor directly. + */ + struct wlr_surface_state current, pending; const char *role; // the lifetime-bound role or null struct { @@ -79,7 +85,7 @@ struct wlr_subsurface { struct wlr_subsurface_state current, pending; - struct wlr_surface_state *cached; + struct wlr_surface_state cached; bool has_cache; bool synchronized; diff --git a/rootston/cursor.c b/rootston/cursor.c index 1cf81704..904af67f 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -200,8 +200,8 @@ static void roots_cursor_update_position( case ROOTS_CURSOR_ROTATE: view = roots_seat_get_focus(seat); if (view != NULL) { - int ox = view->x + view->wlr_surface->current->width/2, - oy = view->y + view->wlr_surface->current->height/2; + int ox = view->x + view->wlr_surface->current.width/2, + oy = view->y + view->wlr_surface->current.height/2; int ux = cursor->offs_x - ox, uy = cursor->offs_y - oy; int vx = cursor->cursor->x - ox, @@ -239,12 +239,12 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, break; case BTN_RIGHT: edges = 0; - if (sx < view->wlr_surface->current->width/2) { + if (sx < view->wlr_surface->current.width/2) { edges |= WLR_EDGE_LEFT; } else { edges |= WLR_EDGE_RIGHT; } - if (sy < view->wlr_surface->current->height/2) { + if (sy < view->wlr_surface->current.height/2) { edges |= WLR_EDGE_TOP; } else { edges |= WLR_EDGE_BOTTOM; diff --git a/rootston/desktop.c b/rootston/desktop.c index d670c33b..4b5a5c9a 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -69,8 +69,8 @@ enum roots_deco_part view_get_deco_part(struct roots_view *view, double sx, return ROOTS_DECO_PART_NONE; } - int sw = view->wlr_surface->current->width; - int sh = view->wlr_surface->current->height; + int sw = view->wlr_surface->current.width; + int sh = view->wlr_surface->current.height; int bw = view->border_width; int titlebar_h = view->titlebar_height; @@ -558,7 +558,7 @@ static bool view_at(struct roots_view *view, double lx, double ly, double view_sx = lx - view->x; double view_sy = ly - view->y; - struct wlr_surface_state *state = view->wlr_surface->current; + struct wlr_surface_state *state = &view->wlr_surface->current; struct wlr_box box = { .x = 0, .y = 0, .width = state->width, .height = state->height, diff --git a/rootston/output.c b/rootston/output.c index 8154816d..aecb0d76 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -44,8 +44,8 @@ struct layout_data { static void get_layout_position(struct layout_data *data, double *lx, double *ly, const struct wlr_surface *surface, int sx, int sy) { double _sx = sx, _sy = sy; - rotate_child_position(&_sx, &_sy, surface->current->width, - surface->current->height, data->width, data->height, data->rotation); + rotate_child_position(&_sx, &_sy, surface->current.width, + surface->current.height, data->width, data->height, data->rotation); *lx = data->x + _sx; *ly = data->y + _sy; } @@ -55,8 +55,8 @@ static void surface_for_each_surface(struct wlr_surface *surface, wlr_surface_iterator_func_t iterator, void *user_data) { layout_data->x = lx; layout_data->y = ly; - layout_data->width = surface->current->width; - layout_data->height = surface->current->height; + layout_data->width = surface->current.width; + layout_data->height = surface->current.height; layout_data->rotation = rotation; wlr_surface_for_each_surface(surface, iterator, user_data); @@ -67,8 +67,8 @@ static void view_for_each_surface(struct roots_view *view, void *user_data) { layout_data->x = view->x; layout_data->y = view->y; - layout_data->width = view->wlr_surface->current->width; - layout_data->height = view->wlr_surface->current->height; + layout_data->width = view->wlr_surface->current.width; + layout_data->height = view->wlr_surface->current.height; layout_data->rotation = view->rotation; switch (view->type) { @@ -149,13 +149,13 @@ static bool surface_intersect_output(struct wlr_surface *surface, if (box != NULL) { box->x = ox * wlr_output->scale; box->y = oy * wlr_output->scale; - box->width = surface->current->width * wlr_output->scale; - box->height = surface->current->height * wlr_output->scale; + box->width = surface->current.width * wlr_output->scale; + box->height = surface->current.height * wlr_output->scale; } struct wlr_box layout_box = { .x = lx, .y = ly, - .width = surface->current->width, .height = surface->current->height, + .width = surface->current.width, .height = surface->current.height, }; wlr_box_rotated_bounds(&layout_box, rotation, &layout_box); return wlr_output_layout_intersects(output_layout, wlr_output, &layout_box); @@ -223,7 +223,7 @@ static void render_surface(struct wlr_surface *surface, int sx, int sy, float matrix[9]; enum wl_output_transform transform = - wlr_output_transform_invert(surface->current->transform); + wlr_output_transform_invert(surface->current.transform); wlr_matrix_project_box(matrix, &box, transform, rotation, output->wlr_output->transform_matrix); @@ -247,8 +247,8 @@ static void get_decoration_box(struct roots_view *view, double sx = deco_box.x - view->x; double sy = deco_box.y - view->y; rotate_child_position(&sx, &sy, deco_box.width, deco_box.height, - view->wlr_surface->current->width, - view->wlr_surface->current->height, view->rotation); + view->wlr_surface->current.width, + view->wlr_surface->current.height, view->rotation); double x = sx + view->x; double y = sy + view->y; @@ -694,13 +694,13 @@ static void damage_from_surface(struct wlr_surface *surface, int sx, int sy, pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->current->surface_damage); + pixman_region32_copy(&damage, &surface->current.surface_damage); wlr_region_scale(&damage, &damage, wlr_output->scale); - if (ceil(wlr_output->scale) > surface->current->scale) { + if (ceil(wlr_output->scale) > surface->current.scale) { // When scaling up a surface, it'll become blurry so we need to // expand the damage region wlr_region_expand(&damage, &damage, - ceil(wlr_output->scale) - surface->current->scale); + ceil(wlr_output->scale) - surface->current.scale); } pixman_region32_translate(&damage, box.x, box.y); wlr_region_rotated_bounds(&damage, &damage, rotation, center_x, center_y); diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index d58f030a..02160773 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -158,8 +158,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { view_apply_damage(view); - int width = wlr_surface->current->width; - int height = wlr_surface->current->height; + int width = wlr_surface->current.width; + int height = wlr_surface->current.height; view_update_size(view, width, height); double x = view->x; @@ -236,8 +236,8 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { return; } view->type = ROOTS_WL_SHELL_VIEW; - view->width = surface->surface->current->width; - view->height = surface->surface->current->height; + view->width = surface->surface->current.width; + view->height = surface->surface->current.height; view->wl_shell_surface = surface; view->roots_wl_shell_surface = roots_surface; diff --git a/rootston/xwayland.c b/rootston/xwayland.c index b7dbab54..d0b80821 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -206,8 +206,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { view_apply_damage(view); - int width = wlr_surface->current->width; - int height = wlr_surface->current->height; + int width = wlr_surface->current.width; + int height = wlr_surface->current.height; view_update_size(view, width, height); double x = view->x; @@ -233,8 +233,8 @@ static void handle_map(struct wl_listener *listener, void *data) { view->x = surface->x; view->y = surface->y; - view->width = surface->surface->current->width; - view->height = surface->surface->current->height; + view->width = surface->surface->current.width; + view->height = surface->surface->current.height; roots_surface->surface_commit.notify = handle_surface_commit; wl_signal_add(&surface->surface->events.commit, diff --git a/types/data_device/wlr_drag.c b/types/data_device/wlr_drag.c index 4f0b2521..b1eafd9c 100644 --- a/types/data_device/wlr_drag.c +++ b/types/data_device/wlr_drag.c @@ -341,8 +341,8 @@ static void drag_icon_handle_surface_destroy(struct wl_listener *listener, static void drag_icon_handle_surface_commit(struct wlr_surface *surface, void *role_data) { struct wlr_drag_icon *icon = role_data; - icon->sx += icon->surface->current->sx; - icon->sy += icon->surface->current->sy; + icon->sx += icon->surface->current.sx; + icon->sy += icon->surface->current.sy; drag_icon_set_mapped(icon, wlr_surface_has_buffer(surface)); } diff --git a/types/wlr_output.c b/types/wlr_output.c index 9f13bef4..9659eb85 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -352,13 +352,13 @@ static void output_fullscreen_surface_get_box(struct wlr_output *output, int width, height; wlr_output_effective_resolution(output, &width, &height); - int x = (width - surface->current->width) / 2; - int y = (height - surface->current->height) / 2; + int x = (width - surface->current.width) / 2; + int y = (height - surface->current.height) / 2; box->x = x * output->scale; box->y = y * output->scale; - box->width = surface->current->width * output->scale; - box->height = surface->current->height * output->scale; + box->width = surface->current.width * output->scale; + box->height = surface->current.height * output->scale; } static void output_fullscreen_surface_render(struct wlr_output *output, @@ -378,7 +378,7 @@ static void output_fullscreen_surface_render(struct wlr_output *output, float matrix[9]; enum wl_output_transform transform = - wlr_output_transform_invert(surface->current->transform); + wlr_output_transform_invert(surface->current.transform); wlr_matrix_project_box(matrix, &box, transform, 0, output->transform_matrix); @@ -405,8 +405,8 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor, box->height = cursor->height; if (cursor->surface != NULL) { - box->x += cursor->surface->current->sx * cursor->output->scale; - box->y += cursor->surface->current->sy * cursor->output->scale; + box->x += cursor->surface->current.sx * cursor->output->scale; + box->y += cursor->surface->current.sy * cursor->output->scale; } } @@ -602,10 +602,10 @@ static void output_fullscreen_surface_handle_commit( fullscreen_surface_commit); struct wlr_surface *surface = output->fullscreen_surface; - if (output->fullscreen_width != surface->current->width || - output->fullscreen_height != surface->current->height) { - output->fullscreen_width = surface->current->width; - output->fullscreen_height = surface->current->height; + if (output->fullscreen_width != surface->current.width || + output->fullscreen_height != surface->current.height) { + output->fullscreen_width = surface->current.width; + output->fullscreen_height = surface->current.height; wlr_output_damage_whole(output); return; } @@ -615,7 +615,7 @@ static void output_fullscreen_surface_handle_commit( pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->current->surface_damage); + pixman_region32_copy(&damage, &surface->current.surface_damage); wlr_region_scale(&damage, &damage, output->scale); pixman_region32_translate(&damage, box.x, box.y); pixman_region32_union(&output->damage, &output->damage, &damage); @@ -714,8 +714,8 @@ static bool output_cursor_attempt_hardware(struct wlr_output_cursor *cursor) { struct wlr_texture *texture = cursor->texture; if (cursor->surface != NULL) { texture = wlr_surface_get_texture(cursor->surface); - scale = cursor->surface->current->scale; - transform = cursor->surface->current->transform; + scale = cursor->surface->current.scale; + transform = cursor->surface->current.transform; } struct wlr_output_cursor *hwcur = cursor->output->hardware_cursor; @@ -778,8 +778,8 @@ static void output_cursor_commit(struct wlr_output_cursor *cursor) { // Some clients commit a cursor surface with a NULL buffer to hide it. cursor->enabled = wlr_surface_has_buffer(cursor->surface); - cursor->width = cursor->surface->current->width * cursor->output->scale; - cursor->height = cursor->surface->current->height * cursor->output->scale; + cursor->width = cursor->surface->current.width * cursor->output->scale; + cursor->height = cursor->surface->current.height * cursor->output->scale; if (output_cursor_attempt_hardware(cursor)) { struct timespec now; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 1dab1888..29d55312 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -67,10 +67,10 @@ static void surface_attach(struct wl_client *client, struct wl_resource *buffer, int32_t sx, int32_t sy) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - surface->pending->committed |= WLR_SURFACE_STATE_BUFFER; - surface->pending->sx = sx; - surface->pending->sy = sy; - surface_state_set_buffer(surface->pending, buffer); + surface->pending.committed |= WLR_SURFACE_STATE_BUFFER; + surface->pending.sx = sx; + surface->pending.sy = sy; + surface_state_set_buffer(&surface->pending, buffer); } static void surface_damage(struct wl_client *client, @@ -80,9 +80,9 @@ static void surface_damage(struct wl_client *client, if (width < 0 || height < 0) { return; } - surface->pending->committed |= WLR_SURFACE_STATE_SURFACE_DAMAGE; - pixman_region32_union_rect(&surface->pending->surface_damage, - &surface->pending->surface_damage, + surface->pending.committed |= WLR_SURFACE_STATE_SURFACE_DAMAGE; + pixman_region32_union_rect(&surface->pending.surface_damage, + &surface->pending.surface_damage, x, y, width, height); } @@ -103,38 +103,38 @@ static void surface_frame(struct wl_client *client, wl_resource_set_implementation(callback_resource, NULL, NULL, callback_handle_resource_destroy); - wl_list_insert(surface->pending->frame_callback_list.prev, + wl_list_insert(surface->pending.frame_callback_list.prev, wl_resource_get_link(callback_resource)); - surface->pending->committed |= WLR_SURFACE_STATE_FRAME_CALLBACK_LIST; + surface->pending.committed |= WLR_SURFACE_STATE_FRAME_CALLBACK_LIST; } static void surface_set_opaque_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region_resource) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - if ((surface->pending->committed & WLR_SURFACE_STATE_OPAQUE_REGION)) { - pixman_region32_clear(&surface->pending->opaque); + if ((surface->pending.committed & WLR_SURFACE_STATE_OPAQUE_REGION)) { + pixman_region32_clear(&surface->pending.opaque); } - surface->pending->committed |= WLR_SURFACE_STATE_OPAQUE_REGION; + surface->pending.committed |= WLR_SURFACE_STATE_OPAQUE_REGION; if (region_resource) { pixman_region32_t *region = wlr_region_from_resource(region_resource); - pixman_region32_copy(&surface->pending->opaque, region); + pixman_region32_copy(&surface->pending.opaque, region); } else { - pixman_region32_clear(&surface->pending->opaque); + pixman_region32_clear(&surface->pending.opaque); } } static void surface_set_input_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region_resource) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - surface->pending->committed |= WLR_SURFACE_STATE_INPUT_REGION; + surface->pending.committed |= WLR_SURFACE_STATE_INPUT_REGION; if (region_resource) { pixman_region32_t *region = wlr_region_from_resource(region_resource); - pixman_region32_copy(&surface->pending->input, region); + pixman_region32_copy(&surface->pending.input, region); } else { - pixman_region32_fini(&surface->pending->input); - pixman_region32_init_rect(&surface->pending->input, + pixman_region32_fini(&surface->pending.input); + pixman_region32_init_rect(&surface->pending.input, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); } } @@ -277,10 +277,10 @@ static void surface_damage_subsurfaces(struct wlr_subsurface *subsurface) { // seems to work ok. See the comment on weston_surface_damage for more info // about a better approach. struct wlr_surface *surface = subsurface->surface; - pixman_region32_union_rect(&surface->current->surface_damage, - &surface->current->surface_damage, - 0, 0, surface->current->width, - surface->current->height); + pixman_region32_union_rect(&surface->current.surface_damage, + &surface->current.surface_damage, + 0, 0, surface->current.width, + surface->current.height); subsurface->reordered = false; @@ -291,7 +291,7 @@ static void surface_damage_subsurfaces(struct wlr_subsurface *subsurface) { } static void surface_apply_damage(struct wlr_surface *surface) { - struct wl_resource *resource = surface->current->buffer; + struct wl_resource *resource = surface->current.buffer; if (resource == NULL) { // NULL commit wlr_buffer_unref(surface->buffer); @@ -302,9 +302,9 @@ static void surface_apply_damage(struct wlr_surface *surface) { if (surface->buffer != NULL && surface->buffer->released) { pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->current->buffer_damage); + pixman_region32_copy(&damage, &surface->current.buffer_damage); pixman_region32_intersect_rect(&damage, &damage, 0, 0, - surface->current->buffer_width, surface->current->buffer_height); + surface->current.buffer_width, surface->current.buffer_height); struct wlr_buffer *updated_buffer = wlr_buffer_apply_damage(surface->buffer, resource, &damage); @@ -330,9 +330,9 @@ static void surface_apply_damage(struct wlr_surface *surface) { } static void surface_commit_pending(struct wlr_surface *surface) { - bool invalid_buffer = surface->pending->committed & WLR_SURFACE_STATE_BUFFER; + bool invalid_buffer = surface->pending.committed & WLR_SURFACE_STATE_BUFFER; - surface_move_state(surface, surface->pending, surface->current); + surface_move_state(surface, &surface->pending, &surface->current); if (invalid_buffer) { surface_apply_damage(surface); @@ -357,8 +357,8 @@ static void surface_commit_pending(struct wlr_surface *surface) { wlr_signal_emit_safe(&surface->events.commit, surface); - pixman_region32_clear(&surface->current->surface_damage); - pixman_region32_clear(&surface->current->buffer_damage); + pixman_region32_clear(&surface->current.surface_damage); + pixman_region32_clear(&surface->current.buffer_damage); } static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) { @@ -388,10 +388,10 @@ static void subsurface_parent_commit(struct wlr_subsurface *subsurface, struct wlr_surface *surface = subsurface->surface; if (synchronized || subsurface->synchronized) { if (subsurface->has_cache) { - surface_move_state(surface, subsurface->cached, surface->pending); + surface_move_state(surface, &subsurface->cached, &surface->pending); surface_commit_pending(surface); subsurface->has_cache = false; - subsurface->cached->committed = 0; + subsurface->cached.committed = 0; } struct wlr_subsurface *subsurface; @@ -405,11 +405,11 @@ static void subsurface_commit(struct wlr_subsurface *subsurface) { struct wlr_surface *surface = subsurface->surface; if (subsurface_is_synchronized(subsurface)) { - surface_move_state(surface, surface->pending, subsurface->cached); + surface_move_state(surface, &surface->pending, &subsurface->cached); subsurface->has_cache = true; } else { if (subsurface->has_cache) { - surface_move_state(surface, subsurface->cached, surface->pending); + surface_move_state(surface, &subsurface->cached, &surface->pending); surface_commit_pending(surface); subsurface->has_cache = false; } else { @@ -439,16 +439,16 @@ static void surface_commit(struct wl_client *client, static void surface_set_buffer_transform(struct wl_client *client, struct wl_resource *resource, int transform) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - surface->pending->committed |= WLR_SURFACE_STATE_TRANSFORM; - surface->pending->transform = transform; + surface->pending.committed |= WLR_SURFACE_STATE_TRANSFORM; + surface->pending.transform = transform; } static void surface_set_buffer_scale(struct wl_client *client, struct wl_resource *resource, int32_t scale) { struct wlr_surface *surface = wlr_surface_from_resource(resource); - surface->pending->committed |= WLR_SURFACE_STATE_SCALE; - surface->pending->scale = scale; + surface->pending.committed |= WLR_SURFACE_STATE_SCALE; + surface->pending.scale = scale; } static void surface_damage_buffer(struct wl_client *client, @@ -459,9 +459,9 @@ static void surface_damage_buffer(struct wl_client *client, if (width < 0 || height < 0) { return; } - surface->pending->committed |= WLR_SURFACE_STATE_BUFFER_DAMAGE; - pixman_region32_union_rect(&surface->pending->buffer_damage, - &surface->pending->buffer_damage, + surface->pending.committed |= WLR_SURFACE_STATE_BUFFER_DAMAGE; + pixman_region32_union_rect(&surface->pending.buffer_damage, + &surface->pending.buffer_damage, x, y, width, height); } @@ -484,12 +484,7 @@ struct wlr_surface *wlr_surface_from_resource(struct wl_resource *resource) { return wl_resource_get_user_data(resource); } -static struct wlr_surface_state *surface_state_create(void) { - struct wlr_surface_state *state = - calloc(1, sizeof(struct wlr_surface_state)); - if (state == NULL) { - return NULL; - } +static void surface_state_init(struct wlr_surface_state *state) { state->scale = 1; state->transform = WL_OUTPUT_TRANSFORM_NORMAL; @@ -500,12 +495,11 @@ static struct wlr_surface_state *surface_state_create(void) { pixman_region32_init(&state->opaque); pixman_region32_init_rect(&state->input, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); - - return state; } -static void surface_state_destroy(struct wlr_surface_state *state) { +static void surface_state_finish(struct wlr_surface_state *state) { surface_state_reset_buffer(state); + struct wl_resource *resource, *tmp; wl_resource_for_each_safe(resource, tmp, &state->frame_callback_list) { wl_resource_destroy(resource); @@ -515,8 +509,6 @@ static void surface_state_destroy(struct wlr_surface_state *state) { pixman_region32_fini(&state->buffer_damage); pixman_region32_fini(&state->opaque); pixman_region32_fini(&state->input); - - free(state); } static void subsurface_destroy(struct wlr_subsurface *subsurface) { @@ -527,7 +519,7 @@ static void subsurface_destroy(struct wlr_subsurface *subsurface) { wlr_signal_emit_safe(&subsurface->events.destroy, subsurface); wl_list_remove(&subsurface->surface_destroy.link); - surface_state_destroy(subsurface->cached); + surface_state_finish(&subsurface->cached); if (subsurface->parent) { wl_list_remove(&subsurface->parent_link); @@ -550,8 +542,8 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) { wl_list_remove(wl_resource_get_link(surface->resource)); wl_list_remove(&surface->renderer_destroy.link); - surface_state_destroy(surface->pending); - surface_state_destroy(surface->current); + surface_state_finish(&surface->pending); + surface_state_finish(&surface->current); wlr_buffer_unref(surface->buffer); free(surface); } @@ -587,8 +579,8 @@ struct wlr_surface *wlr_surface_create(struct wl_client *client, surface->renderer = renderer; - surface->current = surface_state_create(); - surface->pending = surface_state_create(); + surface_state_init(&surface->current); + surface_state_init(&surface->pending); wl_signal_init(&surface->events.commit); wl_signal_init(&surface->events.destroy); @@ -790,15 +782,15 @@ static void subsurface_role_committed(struct wlr_surface *surface, void *data) { // TODO: take the previous size pixman_region32_union_rect( - &subsurface->surface->pending->surface_damage, - &subsurface->surface->pending->surface_damage, dx, dy, - subsurface->surface->current->width, - subsurface->surface->current->height); + &subsurface->surface->pending.surface_damage, + &subsurface->surface->pending.surface_damage, dx, dy, + subsurface->surface->current.width, + subsurface->surface->current.height); pixman_region32_union_rect( - &subsurface->surface->pending->surface_damage, - &subsurface->surface->pending->surface_damage, 0, 0, - subsurface->surface->pending->width, - subsurface->surface->pending->height); + &subsurface->surface->pending.surface_damage, + &subsurface->surface->pending.surface_damage, 0, 0, + subsurface->surface->pending.width, + subsurface->surface->pending.height); } } @@ -832,18 +824,13 @@ struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface, wl_client_post_no_memory(client); return NULL; } - subsurface->cached = surface_state_create(); - if (subsurface->cached == NULL) { - free(subsurface); - wl_client_post_no_memory(client); - return NULL; - } + surface_state_init(&subsurface->cached); subsurface->synchronized = true; subsurface->surface = surface; subsurface->resource = wl_resource_create(client, &wl_subsurface_interface, version, id); if (subsurface->resource == NULL) { - surface_state_destroy(subsurface->cached); + surface_state_finish(&subsurface->cached); free(subsurface); wl_client_post_no_memory(client); return NULL; @@ -892,9 +879,9 @@ struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface) { bool wlr_surface_point_accepts_input(struct wlr_surface *surface, double sx, double sy) { - return sx >= 0 && sx < surface->current->width && - sy >= 0 && sy < surface->current->height && - pixman_region32_contains_point(&surface->current->input, sx, sy, NULL); + return sx >= 0 && sx < surface->current.width && + sy >= 0 && sy < surface->current.height && + pixman_region32_contains_point(&surface->current.input, sx, sy, NULL); } struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface, @@ -949,7 +936,7 @@ void wlr_surface_send_frame_done(struct wlr_surface *surface, const struct timespec *when) { struct wl_resource *resource, *tmp; wl_resource_for_each_safe(resource, tmp, - &surface->current->frame_callback_list) { + &surface->current.frame_callback_list) { wl_callback_send_done(resource, timespec_to_msec(when)); wl_resource_destroy(resource); } @@ -994,16 +981,16 @@ static void handle_bounding_box_surface(struct wlr_surface *surface, acc->min_x = min(x, acc->min_x); acc->min_y = min(y, acc->min_y); - acc->max_x = max(x + surface->current->width, acc->max_x); - acc->max_y = max(y + surface->current->height, acc->max_y); + acc->max_x = max(x + surface->current.width, acc->max_x); + acc->max_y = max(y + surface->current.height, acc->max_y); } void wlr_surface_get_extends(struct wlr_surface *surface, struct wlr_box *box) { struct bound_acc acc = { .min_x = 0, .min_y = 0, - .max_x = surface->current->width, - .max_y = surface->current->height, + .max_x = surface->current.width, + .max_y = surface->current.height, }; wlr_surface_for_each_surface(surface, handle_bounding_box_surface, &acc); diff --git a/types/xdg_shell/wlr_xdg_toplevel.c b/types/xdg_shell/wlr_xdg_toplevel.c index c1350931..5d0bfa1f 100644 --- a/types/xdg_shell/wlr_xdg_toplevel.c +++ b/types/xdg_shell/wlr_xdg_toplevel.c @@ -39,8 +39,8 @@ bool compare_xdg_surface_toplevel_state(struct wlr_xdg_toplevel *state) { if (wl_list_empty(&state->base->configure_list)) { // last configure is actually the current state, just use it configured.state = state->current; - configured.width = state->base->surface->current->width; - configured.height = state->base->surface->current->height; + configured.width = state->base->surface->current.width; + configured.height = state->base->surface->current.height; } else { struct wlr_xdg_surface_configure *configure = wl_container_of(state->base->configure_list.prev, configure, link); diff --git a/types/xdg_shell_v6/wlr_xdg_toplevel_v6.c b/types/xdg_shell_v6/wlr_xdg_toplevel_v6.c index e2e1e480..29cbe2dd 100644 --- a/types/xdg_shell_v6/wlr_xdg_toplevel_v6.c +++ b/types/xdg_shell_v6/wlr_xdg_toplevel_v6.c @@ -287,8 +287,8 @@ bool compare_xdg_surface_v6_toplevel_state(struct wlr_xdg_toplevel_v6 *state) { if (wl_list_empty(&state->base->configure_list)) { // last configure is actually the current state, just use it configured.state = state->current; - configured.width = state->base->surface->current->width; - configured.height = state->base->surface->current->height; + configured.width = state->base->surface->current.width; + configured.height = state->base->surface->current.height; } else { struct wlr_xdg_surface_v6_configure *configure = wl_container_of(state->base->configure_list.prev, configure, link); From e6399c61b76c9005be228b218126a2f073069600 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 22 Jun 2018 08:47:01 +0100 Subject: [PATCH 04/14] surface: fix WLR_SURFACE_STATE_BUFFER_DAMAGE value --- include/wlr/types/wlr_surface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 423cc886..ca33423e 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -11,7 +11,7 @@ enum wlr_surface_state_field { WLR_SURFACE_STATE_BUFFER = 1, WLR_SURFACE_STATE_SURFACE_DAMAGE = 2, - WLR_SURFACE_STATE_BUFFER_DAMAGE = 2, + WLR_SURFACE_STATE_BUFFER_DAMAGE = 4, WLR_SURFACE_STATE_OPAQUE_REGION = 8, WLR_SURFACE_STATE_INPUT_REGION = 16, WLR_SURFACE_STATE_TRANSFORM = 32, From adf0423f7cc2758f5c0958038d5b937f531f22d6 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 25 Jun 2018 22:38:40 +0100 Subject: [PATCH 05/14] surface: better buffer position handling --- include/wlr/types/wlr_surface.h | 3 ++- types/data_device/wlr_drag.c | 4 ++-- types/wlr_surface.c | 15 ++++++++++----- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index ca33423e..ad1ee6f6 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -23,7 +23,7 @@ struct wlr_surface_state { uint32_t committed; // enum wlr_surface_state_field struct wl_resource *buffer; - int32_t sx, sy; + int32_t dx, dy; // relative to previous position pixman_region32_t surface_damage, buffer_damage; pixman_region32_t opaque, input; enum wl_output_transform transform; @@ -32,6 +32,7 @@ struct wlr_surface_state { int width, height; // in surface-local coordinates int buffer_width, buffer_height; + int sx, sy; // in surface-local coordinates struct wl_listener buffer_destroy_listener; }; diff --git a/types/data_device/wlr_drag.c b/types/data_device/wlr_drag.c index b1eafd9c..bae098c5 100644 --- a/types/data_device/wlr_drag.c +++ b/types/data_device/wlr_drag.c @@ -341,8 +341,8 @@ static void drag_icon_handle_surface_destroy(struct wl_listener *listener, static void drag_icon_handle_surface_commit(struct wlr_surface *surface, void *role_data) { struct wlr_drag_icon *icon = role_data; - icon->sx += icon->surface->current.sx; - icon->sy += icon->surface->current.sy; + icon->sx += icon->surface->current.dx; + icon->sy += icon->surface->current.dy; drag_icon_set_mapped(icon, wlr_surface_has_buffer(surface)); } diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 29d55312..964fe964 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -64,12 +64,12 @@ static void surface_destroy(struct wl_client *client, static void surface_attach(struct wl_client *client, struct wl_resource *resource, - struct wl_resource *buffer, int32_t sx, int32_t sy) { + struct wl_resource *buffer, int32_t dx, int32_t dy) { struct wlr_surface *surface = wlr_surface_from_resource(resource); surface->pending.committed |= WLR_SURFACE_STATE_BUFFER; - surface->pending.sx = sx; - surface->pending.sy = sy; + surface->pending.dx = dx; + surface->pending.dy = dy; surface_state_set_buffer(&surface->pending, buffer); } @@ -203,9 +203,14 @@ static void surface_move_state(struct wlr_surface *surface, if ((next->committed & WLR_SURFACE_STATE_BUFFER)) { surface_state_set_buffer(state, next->buffer); surface_state_reset_buffer(next); - state->sx = next->sx; - state->sy = next->sy; + state->dx = next->dx; + state->dy = next->dy; + next->dx = next->dy = 0; + state->sx += state->dx; + state->sy += state->dy; update_size = true; + } else { + state->dx = state->dy = 0; } if (update_size) { update_damage = surface_update_size(surface, state); From 233bfe2f4f7859fa293a33a5b4022eaae7eb6cb3 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 25 Jun 2018 23:35:02 +0100 Subject: [PATCH 06/14] surface: do not monkey-patch state damage --- include/wlr/types/wlr_surface.h | 1 + rootston/output.c | 8 +- types/wlr_surface.c | 170 +++++++++++++++----------------- 3 files changed, 89 insertions(+), 90 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index ad1ee6f6..fdfc716d 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -33,6 +33,7 @@ struct wlr_surface_state { int width, height; // in surface-local coordinates int buffer_width, buffer_height; int sx, sy; // in surface-local coordinates + pixman_region32_t damage; // in buffer-local coordinates struct wl_listener buffer_destroy_listener; }; diff --git a/rootston/output.c b/rootston/output.c index aecb0d76..6abd60ae 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -146,6 +146,9 @@ static bool surface_intersect_output(struct wlr_surface *surface, double ox = lx, oy = ly; wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy); + ox += surface->current.sx; + oy += surface->current.sy; + if (box != NULL) { box->x = ox * wlr_output->scale; box->y = oy * wlr_output->scale; @@ -694,8 +697,9 @@ static void damage_from_surface(struct wlr_surface *surface, int sx, int sy, pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->current.surface_damage); - wlr_region_scale(&damage, &damage, wlr_output->scale); + pixman_region32_copy(&damage, &surface->current.damage); + wlr_region_scale(&damage, &damage, + wlr_output->scale / (float)surface->current.scale); if (ceil(wlr_output->scale) > surface->current.scale) { // When scaling up a surface, it'll become blurry so we need to // expand the damage region diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 964fe964..e6a67208 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -139,49 +139,49 @@ static void surface_set_input_region(struct wl_client *client, } } -static bool surface_update_size(struct wlr_surface *surface, - struct wlr_surface_state *state) { - if (!state->buffer) { - pixman_region32_union_rect(&state->surface_damage, - &state->surface_damage, 0, 0, state->width, state->height); - state->height = 0; - state->width = 0; - return true; - } - - int scale = state->scale; - enum wl_output_transform transform = state->transform; - - wlr_buffer_get_resource_size(state->buffer, surface->renderer, - &state->buffer_width, &state->buffer_height); +static void surface_state_update_size(struct wlr_surface_state *state) { + int width = state->buffer_width / state->scale; + int height = state->buffer_height / state->scale; - int width = state->buffer_width / scale; - int height = state->buffer_height / scale; - - if (transform == WL_OUTPUT_TRANSFORM_90 || - transform == WL_OUTPUT_TRANSFORM_270 || - transform == WL_OUTPUT_TRANSFORM_FLIPPED_90 || - transform == WL_OUTPUT_TRANSFORM_FLIPPED_270) { + if ((state->transform & WL_OUTPUT_TRANSFORM_90) != 0) { int tmp = width; width = height; height = tmp; } - bool update_damage = false; - if (width != state->width || height != state->height) { - // Damage the whole surface on resize - // This isn't in the spec, but Weston does it and QT expects it - pixman_region32_union_rect(&state->surface_damage, - &state->surface_damage, 0, 0, state->width, state->height); - pixman_region32_union_rect(&state->surface_damage, - &state->surface_damage, 0, 0, width, height); - update_damage = true; - } - state->width = width; state->height = height; +} + +static void surface_state_update_damage(struct wlr_surface_state *state, + struct wlr_surface_state *next) { + pixman_region32_clear(&state->damage); + + if (next->buffer_width != state->buffer_width || + next->buffer_height != state->buffer_height) { + // Damage the whole surface on resize + pixman_region32_union_rect(&state->damage, + &state->damage, state->sx * state->scale, state->sy * state->scale, + state->buffer_width, state->buffer_height); + pixman_region32_union_rect(&state->damage, + &state->damage, next->sx * next->scale, next->sy * next->scale, + next->buffer_width, next->buffer_height); + } else { + // Copy over surface damage + buffer damage + pixman_region32_union(&state->damage, &state->damage, + &next->buffer_damage); + + pixman_region32_t surface_damage; + pixman_region32_init(&surface_damage); + pixman_region32_copy(&surface_damage, &next->surface_damage); + wlr_region_transform(&surface_damage, &surface_damage, next->transform, + next->buffer_width, next->buffer_height); + wlr_region_scale(&surface_damage, &surface_damage, next->scale); + pixman_region32_union(&state->damage, &state->damage, &surface_damage); + pixman_region32_fini(&surface_damage); - return update_damage; + // TODO: handle sx, sy + } } /** @@ -189,16 +189,49 @@ static bool surface_update_size(struct wlr_surface *surface, */ static void surface_move_state(struct wlr_surface *surface, struct wlr_surface_state *next, struct wlr_surface_state *state) { - bool update_damage = false; - bool update_size = false; + // Commit next state + + if ((next->committed & WLR_SURFACE_STATE_BUFFER)) { + wlr_buffer_get_resource_size(next->buffer, surface->renderer, + &next->buffer_width, &next->buffer_height); + } + + surface_state_update_size(next); + + next->sx += next->dx; + next->sy += next->dy; + + pixman_region32_intersect_rect(&next->surface_damage, + &next->surface_damage, 0, 0, next->width, next->height); + + pixman_region32_intersect_rect(&next->buffer_damage, + &next->buffer_damage, 0, 0, next->buffer_width, + next->buffer_height); + + pixman_region32_intersect_rect(&next->opaque, &next->opaque, + 0, 0, next->width, next->height); + + pixman_region32_intersect_rect(&next->input, &next->input, + 0, 0, next->width, next->height); + + // Compute new state + + surface_state_update_damage(state, next); + + state->width = next->width; + state->height = next->height; + state->buffer_width = next->buffer_width; + state->buffer_height = next->buffer_height; + state->sx = next->sx; + state->sy = next->sy; + + // Move state from next one, clear next state if ((next->committed & WLR_SURFACE_STATE_SCALE)) { state->scale = next->scale; - update_size = true; } if ((next->committed & WLR_SURFACE_STATE_TRANSFORM)) { state->transform = next->transform; - update_size = true; } if ((next->committed & WLR_SURFACE_STATE_BUFFER)) { surface_state_set_buffer(state, next->buffer); @@ -206,64 +239,25 @@ static void surface_move_state(struct wlr_surface *surface, state->dx = next->dx; state->dy = next->dy; next->dx = next->dy = 0; - state->sx += state->dx; - state->sy += state->dy; - update_size = true; } else { state->dx = state->dy = 0; } - if (update_size) { - update_damage = surface_update_size(surface, state); - } if ((next->committed & WLR_SURFACE_STATE_SURFACE_DAMAGE)) { - pixman_region32_intersect_rect(&next->surface_damage, - &next->surface_damage, 0, 0, state->width, state->height); - pixman_region32_union(&state->surface_damage, &state->surface_damage, - &next->surface_damage); + pixman_region32_copy(&state->surface_damage, &next->surface_damage); pixman_region32_clear(&next->surface_damage); - update_damage = true; + } else { + pixman_region32_clear(&state->surface_damage); } if ((next->committed & WLR_SURFACE_STATE_BUFFER_DAMAGE)) { - pixman_region32_intersect_rect(&next->buffer_damage, - &next->buffer_damage, 0, 0, state->buffer_width, - state->buffer_height); - pixman_region32_union(&state->buffer_damage, &state->buffer_damage, - &next->buffer_damage); + pixman_region32_copy(&state->buffer_damage, &next->buffer_damage); pixman_region32_clear(&next->buffer_damage); - update_damage = true; - } - if (update_damage) { - pixman_region32_t buffer_damage, surface_damage; - pixman_region32_init(&buffer_damage); - pixman_region32_init(&surface_damage); - - // Surface to buffer damage - pixman_region32_copy(&buffer_damage, &state->surface_damage); - wlr_region_transform(&buffer_damage, &buffer_damage, - wlr_output_transform_invert(state->transform), - state->width, state->height); - wlr_region_scale(&buffer_damage, &buffer_damage, state->scale); - - // Buffer to surface damage - pixman_region32_copy(&surface_damage, &state->buffer_damage); - wlr_region_transform(&surface_damage, &surface_damage, state->transform, - state->buffer_width, state->buffer_height); - wlr_region_scale(&surface_damage, &surface_damage, 1.0f/state->scale); - - pixman_region32_union(&state->buffer_damage, &state->buffer_damage, - &buffer_damage); - pixman_region32_union(&state->surface_damage, &state->surface_damage, - &surface_damage); - - pixman_region32_fini(&buffer_damage); - pixman_region32_fini(&surface_damage); + } else { + pixman_region32_clear(&state->buffer_damage); } if ((next->committed & WLR_SURFACE_STATE_OPAQUE_REGION)) { - // TODO: process buffer - pixman_region32_clear(&next->opaque); + pixman_region32_copy(&state->opaque, &next->opaque); } if ((next->committed & WLR_SURFACE_STATE_INPUT_REGION)) { - // TODO: process buffer pixman_region32_copy(&state->input, &next->input); } if ((next->committed & WLR_SURFACE_STATE_FRAME_CALLBACK_LIST)) { @@ -307,7 +301,8 @@ static void surface_apply_damage(struct wlr_surface *surface) { if (surface->buffer != NULL && surface->buffer->released) { pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->current.buffer_damage); + pixman_region32_copy(&damage, &surface->current.damage); + // TODO: translate sx, sy pixman_region32_intersect_rect(&damage, &damage, 0, 0, surface->current.buffer_width, surface->current.buffer_height); @@ -361,9 +356,6 @@ static void surface_commit_pending(struct wlr_surface *surface) { } wlr_signal_emit_safe(&surface->events.commit, surface); - - pixman_region32_clear(&surface->current.surface_damage); - pixman_region32_clear(&surface->current.buffer_damage); } static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) { @@ -500,6 +492,7 @@ static void surface_state_init(struct wlr_surface_state *state) { pixman_region32_init(&state->opaque); pixman_region32_init_rect(&state->input, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); + pixman_region32_init(&state->damage); } static void surface_state_finish(struct wlr_surface_state *state) { @@ -514,6 +507,7 @@ static void surface_state_finish(struct wlr_surface_state *state) { pixman_region32_fini(&state->buffer_damage); pixman_region32_fini(&state->opaque); pixman_region32_fini(&state->input); + pixman_region32_fini(&state->damage); } static void subsurface_destroy(struct wlr_subsurface *subsurface) { From 78555abba3fdd272f50dcb8b8bf3b7811ddd9fc5 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 28 Jun 2018 23:49:40 +0100 Subject: [PATCH 07/14] surface: move position and scale out of wlr_surface_state --- include/wlr/types/wlr_surface.h | 17 ++- rootston/output.c | 11 +- types/wlr_output.c | 4 +- types/wlr_surface.c | 180 +++++++++++++++++--------------- 4 files changed, 121 insertions(+), 91 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index fdfc716d..a587e7bc 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -32,8 +32,6 @@ struct wlr_surface_state { int width, height; // in surface-local coordinates int buffer_width, buffer_height; - int sx, sy; // in surface-local coordinates - pixman_region32_t damage; // in buffer-local coordinates struct wl_listener buffer_destroy_listener; }; @@ -48,6 +46,21 @@ struct wlr_surface { * or something went wrong with uploading the buffer. */ struct wlr_buffer *buffer; + /** + * The buffer position, in surface-local units. + */ + int sx, sy; + /** + * The last commit's buffer damage, in buffer-local coordinates. This + * contains both the damage accumulated by the client via + * `wlr_surface_state.surface_damage` and `wlr_surface_state.buffer_damage`. + * If the buffer has changed its size or moved, the whole buffer is + * damaged. + * + * This region needs to be scaled and transformed into output coordinates, + * just like the buffer's texture. + */ + pixman_region32_t buffer_damage; /** * `current` contains the current, committed surface state. `pending` * accumulates state changes from the client between commits and shouldn't diff --git a/rootston/output.c b/rootston/output.c index 6abd60ae..fd7df99c 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -146,8 +146,8 @@ static bool surface_intersect_output(struct wlr_surface *surface, double ox = lx, oy = ly; wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy); - ox += surface->current.sx; - oy += surface->current.sy; + ox += surface->sx; + oy += surface->sy; if (box != NULL) { box->x = ox * wlr_output->scale; @@ -695,9 +695,14 @@ static void damage_from_surface(struct wlr_surface *surface, int sx, int sy, int center_x = box.x + box.width/2; int center_y = box.y + box.height/2; + enum wl_output_transform transform = + wlr_output_transform_invert(surface->current.transform); + pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->current.damage); + pixman_region32_copy(&damage, &surface->buffer_damage); + wlr_region_transform(&damage, &damage, transform, + surface->current.buffer_width, surface->current.buffer_height); wlr_region_scale(&damage, &damage, wlr_output->scale / (float)surface->current.scale); if (ceil(wlr_output->scale) > surface->current.scale) { diff --git a/types/wlr_output.c b/types/wlr_output.c index 9659eb85..831f1086 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -405,8 +405,8 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor, box->height = cursor->height; if (cursor->surface != NULL) { - box->x += cursor->surface->current.sx * cursor->output->scale; - box->y += cursor->surface->current.sy * cursor->output->scale; + box->x += cursor->surface->sx * cursor->output->scale; + box->y += cursor->surface->sy * cursor->output->scale; } } diff --git a/types/wlr_surface.c b/types/wlr_surface.c index e6a67208..7611d492 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -139,93 +139,83 @@ static void surface_set_input_region(struct wl_client *client, } } -static void surface_state_update_size(struct wlr_surface_state *state) { +static void surface_state_finalize(struct wlr_surface *surface, + struct wlr_surface_state *state) { + if ((state->committed & WLR_SURFACE_STATE_BUFFER)) { + wlr_buffer_get_resource_size(state->buffer, surface->renderer, + &state->buffer_width, &state->buffer_height); + } + int width = state->buffer_width / state->scale; int height = state->buffer_height / state->scale; - if ((state->transform & WL_OUTPUT_TRANSFORM_90) != 0) { int tmp = width; width = height; height = tmp; } - state->width = width; state->height = height; + + pixman_region32_intersect_rect(&state->surface_damage, + &state->surface_damage, 0, 0, state->width, state->height); + + pixman_region32_intersect_rect(&state->buffer_damage, + &state->buffer_damage, 0, 0, state->buffer_width, + state->buffer_height); + + pixman_region32_intersect_rect(&state->opaque, &state->opaque, + 0, 0, state->width, state->height); + + pixman_region32_intersect_rect(&state->input, &state->input, + 0, 0, state->width, state->height); } -static void surface_state_update_damage(struct wlr_surface_state *state, - struct wlr_surface_state *next) { - pixman_region32_clear(&state->damage); - - if (next->buffer_width != state->buffer_width || - next->buffer_height != state->buffer_height) { - // Damage the whole surface on resize - pixman_region32_union_rect(&state->damage, - &state->damage, state->sx * state->scale, state->sy * state->scale, - state->buffer_width, state->buffer_height); - pixman_region32_union_rect(&state->damage, - &state->damage, next->sx * next->scale, next->sy * next->scale, - next->buffer_width, next->buffer_height); +static void surface_update_damage(pixman_region32_t *buffer_damage, + struct wlr_surface_state *previous, struct wlr_surface_state *current) { + pixman_region32_clear(buffer_damage); + + if (current->buffer_width != previous->buffer_width || + current->buffer_height != previous->buffer_height || + current->dx != 0 || current->dy != 0) { + // Damage the whole surface on resize or move + int prev_x = -current->dx; + int prev_y = -current->dy; + if ((previous->transform & WL_OUTPUT_TRANSFORM_90) != 0) { + int tmp = prev_x; + prev_x = prev_y; + prev_y = tmp; + } + + pixman_region32_union_rect(buffer_damage, buffer_damage, + prev_x * previous->scale, prev_y * previous->scale, + previous->buffer_width, previous->buffer_height); + pixman_region32_union_rect(buffer_damage, buffer_damage, 0, 0, + current->buffer_width, current->buffer_height); } else { // Copy over surface damage + buffer damage - pixman_region32_union(&state->damage, &state->damage, - &next->buffer_damage); + pixman_region32_union(buffer_damage, buffer_damage, + ¤t->buffer_damage); pixman_region32_t surface_damage; pixman_region32_init(&surface_damage); - pixman_region32_copy(&surface_damage, &next->surface_damage); - wlr_region_transform(&surface_damage, &surface_damage, next->transform, - next->buffer_width, next->buffer_height); - wlr_region_scale(&surface_damage, &surface_damage, next->scale); - pixman_region32_union(&state->damage, &state->damage, &surface_damage); + pixman_region32_copy(&surface_damage, ¤t->surface_damage); + wlr_region_transform(&surface_damage, &surface_damage, + current->transform, current->buffer_width, current->buffer_height); + wlr_region_scale(&surface_damage, &surface_damage, current->scale); + pixman_region32_union(buffer_damage, buffer_damage, &surface_damage); pixman_region32_fini(&surface_damage); - - // TODO: handle sx, sy } } /** * Append pending state to current state and clear pending state. */ -static void surface_move_state(struct wlr_surface *surface, - struct wlr_surface_state *next, struct wlr_surface_state *state) { - // Commit next state - - if ((next->committed & WLR_SURFACE_STATE_BUFFER)) { - wlr_buffer_get_resource_size(next->buffer, surface->renderer, - &next->buffer_width, &next->buffer_height); - } - - surface_state_update_size(next); - - next->sx += next->dx; - next->sy += next->dy; - - pixman_region32_intersect_rect(&next->surface_damage, - &next->surface_damage, 0, 0, next->width, next->height); - - pixman_region32_intersect_rect(&next->buffer_damage, - &next->buffer_damage, 0, 0, next->buffer_width, - next->buffer_height); - - pixman_region32_intersect_rect(&next->opaque, &next->opaque, - 0, 0, next->width, next->height); - - pixman_region32_intersect_rect(&next->input, &next->input, - 0, 0, next->width, next->height); - - // Compute new state - - surface_state_update_damage(state, next); - +static void surface_state_move(struct wlr_surface_state *state, + struct wlr_surface_state *next) { state->width = next->width; state->height = next->height; state->buffer_width = next->buffer_width; state->buffer_height = next->buffer_height; - state->sx = next->sx; - state->sy = next->sy; - - // Move state from next one, clear next state if ((next->committed & WLR_SURFACE_STATE_SCALE)) { state->scale = next->scale; @@ -276,10 +266,9 @@ static void surface_damage_subsurfaces(struct wlr_subsurface *subsurface) { // seems to work ok. See the comment on weston_surface_damage for more info // about a better approach. struct wlr_surface *surface = subsurface->surface; - pixman_region32_union_rect(&surface->current.surface_damage, - &surface->current.surface_damage, - 0, 0, surface->current.width, - surface->current.height); + pixman_region32_union_rect(&surface->buffer_damage, + &surface->buffer_damage, 0, 0, + surface->current.buffer_width, surface->current.buffer_height); subsurface->reordered = false; @@ -301,8 +290,19 @@ static void surface_apply_damage(struct wlr_surface *surface) { if (surface->buffer != NULL && surface->buffer->released) { pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->current.damage); - // TODO: translate sx, sy + pixman_region32_copy(&damage, &surface->current.buffer_damage); + + pixman_region32_t surface_damage; + pixman_region32_init(&surface_damage); + pixman_region32_copy(&surface_damage, &surface->current.surface_damage); + wlr_region_transform(&surface_damage, &surface_damage, + surface->current.transform, + surface->current.buffer_width, surface->current.buffer_height); + wlr_region_scale(&surface_damage, &surface_damage, + surface->current.scale); + pixman_region32_union(&damage, &damage, &surface_damage); + pixman_region32_fini(&surface_damage); + pixman_region32_intersect_rect(&damage, &damage, 0, 0, surface->current.buffer_width, surface->current.buffer_height); @@ -332,7 +332,14 @@ static void surface_apply_damage(struct wlr_surface *surface) { static void surface_commit_pending(struct wlr_surface *surface) { bool invalid_buffer = surface->pending.committed & WLR_SURFACE_STATE_BUFFER; - surface_move_state(surface, &surface->pending, &surface->current); + surface_state_finalize(surface, &surface->pending); + + surface->sx += surface->pending.dx; + surface->sy += surface->pending.dy; + surface_update_damage(&surface->buffer_damage, + &surface->current, &surface->pending); + + surface_state_move(&surface->current, &surface->pending); if (invalid_buffer) { surface_apply_damage(surface); @@ -385,7 +392,7 @@ static void subsurface_parent_commit(struct wlr_subsurface *subsurface, struct wlr_surface *surface = subsurface->surface; if (synchronized || subsurface->synchronized) { if (subsurface->has_cache) { - surface_move_state(surface, &subsurface->cached, &surface->pending); + surface_state_move(&surface->pending, &subsurface->cached); surface_commit_pending(surface); subsurface->has_cache = false; subsurface->cached.committed = 0; @@ -402,11 +409,11 @@ static void subsurface_commit(struct wlr_subsurface *subsurface) { struct wlr_surface *surface = subsurface->surface; if (subsurface_is_synchronized(subsurface)) { - surface_move_state(surface, &surface->pending, &subsurface->cached); + surface_state_move(&subsurface->cached, &surface->pending); subsurface->has_cache = true; } else { if (subsurface->has_cache) { - surface_move_state(surface, &subsurface->cached, &surface->pending); + surface_state_move(&surface->pending, &subsurface->cached); surface_commit_pending(surface); subsurface->has_cache = false; } else { @@ -492,7 +499,6 @@ static void surface_state_init(struct wlr_surface_state *state) { pixman_region32_init(&state->opaque); pixman_region32_init_rect(&state->input, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); - pixman_region32_init(&state->damage); } static void surface_state_finish(struct wlr_surface_state *state) { @@ -507,7 +513,6 @@ static void surface_state_finish(struct wlr_surface_state *state) { pixman_region32_fini(&state->buffer_damage); pixman_region32_fini(&state->opaque); pixman_region32_fini(&state->input); - pixman_region32_fini(&state->damage); } static void subsurface_destroy(struct wlr_subsurface *subsurface) { @@ -543,6 +548,7 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) { wl_list_remove(&surface->renderer_destroy.link); surface_state_finish(&surface->pending); surface_state_finish(&surface->current); + pixman_region32_fini(&surface->buffer_damage); wlr_buffer_unref(surface->buffer); free(surface); } @@ -586,6 +592,7 @@ struct wlr_surface *wlr_surface_create(struct wl_client *client, wl_signal_init(&surface->events.new_subsurface); wl_list_init(&surface->subsurfaces); wl_list_init(&surface->subsurface_pending_list); + pixman_region32_init(&surface->buffer_damage); wl_signal_add(&renderer->events.destroy, &surface->renderer_destroy); surface->renderer_destroy.notify = surface_handle_renderer_destroy; @@ -773,23 +780,28 @@ static void subsurface_role_committed(struct wlr_surface *surface, void *data) { if (subsurface->current.x != subsurface->pending.x || subsurface->current.y != subsurface->pending.y) { // Subsurface has moved - int dx = subsurface->pending.x - subsurface->current.x; - int dy = subsurface->pending.y - subsurface->current.y; + int dx = subsurface->current.x - subsurface->pending.x; + int dy = subsurface->current.y - subsurface->pending.y; subsurface->current.x = subsurface->pending.x; subsurface->current.y = subsurface->pending.y; + if ((surface->current.transform & WL_OUTPUT_TRANSFORM_90) != 0) { + int tmp = dx; + dx = dy; + dy = tmp; + } + // TODO: take the previous size - pixman_region32_union_rect( - &subsurface->surface->pending.surface_damage, - &subsurface->surface->pending.surface_damage, dx, dy, - subsurface->surface->current.width, - subsurface->surface->current.height); - pixman_region32_union_rect( - &subsurface->surface->pending.surface_damage, - &subsurface->surface->pending.surface_damage, 0, 0, - subsurface->surface->pending.width, - subsurface->surface->pending.height); + pixman_region32_union_rect(&surface->buffer_damage, + &surface->buffer_damage, + dx * surface->current.scale, dy * surface->current.scale, + surface->current.width, + surface->current.height); + pixman_region32_union_rect(&surface->buffer_damage, + &surface->buffer_damage, 0, 0, + surface->pending.width, + surface->pending.height); } } From 012e38fbe55dad39a9b3c882195efc69e8aedb1f Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 1 Jul 2018 11:54:42 +0100 Subject: [PATCH 08/14] surface: add wlr_surface.previous --- include/wlr/types/wlr_surface.h | 5 +++-- types/wlr_surface.c | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index a587e7bc..76f09cc6 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -64,9 +64,10 @@ struct wlr_surface { /** * `current` contains the current, committed surface state. `pending` * accumulates state changes from the client between commits and shouldn't - * be accessed by the compositor directly. + * be accessed by the compositor directly. `previous` contains the state of + * the previous commit. */ - struct wlr_surface_state current, pending; + struct wlr_surface_state current, pending, previous; const char *role; // the lifetime-bound role or null struct { diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 7611d492..e197dde3 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -339,6 +339,7 @@ static void surface_commit_pending(struct wlr_surface *surface) { surface_update_damage(&surface->buffer_damage, &surface->current, &surface->pending); + surface_state_move(&surface->previous, &surface->current); surface_state_move(&surface->current, &surface->pending); if (invalid_buffer) { @@ -548,6 +549,7 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) { wl_list_remove(&surface->renderer_destroy.link); surface_state_finish(&surface->pending); surface_state_finish(&surface->current); + surface_state_finish(&surface->previous); pixman_region32_fini(&surface->buffer_damage); wlr_buffer_unref(surface->buffer); free(surface); @@ -586,6 +588,7 @@ struct wlr_surface *wlr_surface_create(struct wl_client *client, surface_state_init(&surface->current); surface_state_init(&surface->pending); + surface_state_init(&surface->previous); wl_signal_init(&surface->events.commit); wl_signal_init(&surface->events.destroy); @@ -792,16 +795,13 @@ static void subsurface_role_committed(struct wlr_surface *surface, void *data) { dy = tmp; } - // TODO: take the previous size pixman_region32_union_rect(&surface->buffer_damage, &surface->buffer_damage, - dx * surface->current.scale, dy * surface->current.scale, - surface->current.width, - surface->current.height); + dx * surface->previous.scale, dy * surface->previous.scale, + surface->previous.width, surface->previous.height); pixman_region32_union_rect(&surface->buffer_damage, &surface->buffer_damage, 0, 0, - surface->pending.width, - surface->pending.height); + surface->current.width, surface->current.height); } } From f4407082743aba44ee7bbede402576a17bd41043 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 1 Jul 2018 12:08:30 +0100 Subject: [PATCH 09/14] output: fix cursor attach coords handling --- types/wlr_output.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/types/wlr_output.c b/types/wlr_output.c index 831f1086..fc86f411 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -403,11 +403,6 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor, box->y = cursor->y - cursor->hotspot_y; box->width = cursor->width; box->height = cursor->height; - - if (cursor->surface != NULL) { - box->x += cursor->surface->sx * cursor->output->scale; - box->y += cursor->surface->sy * cursor->output->scale; - } } static void output_cursor_render(struct wlr_output_cursor *cursor, @@ -771,20 +766,28 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, return true; } -static void output_cursor_commit(struct wlr_output_cursor *cursor) { +static void output_cursor_commit(struct wlr_output_cursor *cursor, + bool update_hotspot) { if (cursor->output->hardware_cursor != cursor) { output_cursor_damage_whole(cursor); } + struct wlr_surface *surface = cursor->surface; + assert(surface != NULL); + // Some clients commit a cursor surface with a NULL buffer to hide it. - cursor->enabled = wlr_surface_has_buffer(cursor->surface); - cursor->width = cursor->surface->current.width * cursor->output->scale; - cursor->height = cursor->surface->current.height * cursor->output->scale; + cursor->enabled = wlr_surface_has_buffer(surface); + cursor->width = surface->current.width * cursor->output->scale; + cursor->height = surface->current.height * cursor->output->scale; + if (update_hotspot) { + cursor->hotspot_x -= surface->current.dx * cursor->output->scale; + cursor->hotspot_y -= surface->current.dy * cursor->output->scale; + } if (output_cursor_attempt_hardware(cursor)) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - wlr_surface_send_frame_done(cursor->surface, &now); + wlr_surface_send_frame_done(surface, &now); return; } @@ -794,9 +797,9 @@ static void output_cursor_commit(struct wlr_output_cursor *cursor) { static void output_cursor_handle_commit(struct wl_listener *listener, void *data) { - struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, - surface_commit); - output_cursor_commit(cursor); + struct wlr_output_cursor *cursor = + wl_container_of(listener, cursor, surface_commit); + output_cursor_commit(cursor, true); } static void output_cursor_handle_destroy(struct wl_listener *listener, @@ -842,7 +845,7 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, if (surface != NULL) { wl_signal_add(&surface->events.commit, &cursor->surface_commit); wl_signal_add(&surface->events.destroy, &cursor->surface_destroy); - output_cursor_commit(cursor); + output_cursor_commit(cursor, false); cursor->visible = false; output_cursor_update_visible(cursor); From 6f0eb11024e364df530b134e572e4943f3c4e76d Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 1 Jul 2018 12:22:43 +0100 Subject: [PATCH 10/14] surface: fix previous state eating current state resources --- types/wlr_surface.c | 51 ++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/types/wlr_surface.c b/types/wlr_surface.c index e197dde3..57732649 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -207,56 +207,69 @@ static void surface_update_damage(pixman_region32_t *buffer_damage, } } -/** - * Append pending state to current state and clear pending state. - */ -static void surface_state_move(struct wlr_surface_state *state, +static void surface_state_copy(struct wlr_surface_state *state, struct wlr_surface_state *next) { state->width = next->width; state->height = next->height; state->buffer_width = next->buffer_width; state->buffer_height = next->buffer_height; - if ((next->committed & WLR_SURFACE_STATE_SCALE)) { + if (next->committed & WLR_SURFACE_STATE_SCALE) { state->scale = next->scale; } - if ((next->committed & WLR_SURFACE_STATE_TRANSFORM)) { + if (next->committed & WLR_SURFACE_STATE_TRANSFORM) { state->transform = next->transform; } - if ((next->committed & WLR_SURFACE_STATE_BUFFER)) { - surface_state_set_buffer(state, next->buffer); - surface_state_reset_buffer(next); + if (next->committed & WLR_SURFACE_STATE_BUFFER) { state->dx = next->dx; state->dy = next->dy; - next->dx = next->dy = 0; } else { state->dx = state->dy = 0; } - if ((next->committed & WLR_SURFACE_STATE_SURFACE_DAMAGE)) { + if (next->committed & WLR_SURFACE_STATE_SURFACE_DAMAGE) { pixman_region32_copy(&state->surface_damage, &next->surface_damage); - pixman_region32_clear(&next->surface_damage); } else { pixman_region32_clear(&state->surface_damage); } - if ((next->committed & WLR_SURFACE_STATE_BUFFER_DAMAGE)) { + if (next->committed & WLR_SURFACE_STATE_BUFFER_DAMAGE) { pixman_region32_copy(&state->buffer_damage, &next->buffer_damage); - pixman_region32_clear(&next->buffer_damage); } else { pixman_region32_clear(&state->buffer_damage); } - if ((next->committed & WLR_SURFACE_STATE_OPAQUE_REGION)) { + if (next->committed & WLR_SURFACE_STATE_OPAQUE_REGION) { pixman_region32_copy(&state->opaque, &next->opaque); } - if ((next->committed & WLR_SURFACE_STATE_INPUT_REGION)) { + if (next->committed & WLR_SURFACE_STATE_INPUT_REGION) { pixman_region32_copy(&state->input, &next->input); } - if ((next->committed & WLR_SURFACE_STATE_FRAME_CALLBACK_LIST)) { + + state->committed |= next->committed; +} + +/** + * Append pending state to current state and clear pending state. + */ +static void surface_state_move(struct wlr_surface_state *state, + struct wlr_surface_state *next) { + surface_state_copy(state, next); + + if (next->committed & WLR_SURFACE_STATE_BUFFER) { + surface_state_set_buffer(state, next->buffer); + surface_state_reset_buffer(next); + next->dx = next->dy = 0; + } + if (next->committed & WLR_SURFACE_STATE_SURFACE_DAMAGE) { + pixman_region32_clear(&next->surface_damage); + } + if (next->committed & WLR_SURFACE_STATE_BUFFER_DAMAGE) { + pixman_region32_clear(&next->buffer_damage); + } + if (next->committed & WLR_SURFACE_STATE_FRAME_CALLBACK_LIST) { wl_list_insert_list(&state->frame_callback_list, &next->frame_callback_list); wl_list_init(&next->frame_callback_list); } - state->committed |= next->committed; next->committed = 0; } @@ -339,7 +352,7 @@ static void surface_commit_pending(struct wlr_surface *surface) { surface_update_damage(&surface->buffer_damage, &surface->current, &surface->pending); - surface_state_move(&surface->previous, &surface->current); + surface_state_copy(&surface->previous, &surface->current); surface_state_move(&surface->current, &surface->pending); if (invalid_buffer) { From 68c133da2fb49f4b7c26aacd49f535ef93d27116 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 1 Jul 2018 15:03:55 +0100 Subject: [PATCH 11/14] surface: fix crash on NULL commit --- types/wlr_surface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 57732649..5c594889 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -142,8 +142,12 @@ static void surface_set_input_region(struct wl_client *client, static void surface_state_finalize(struct wlr_surface *surface, struct wlr_surface_state *state) { if ((state->committed & WLR_SURFACE_STATE_BUFFER)) { - wlr_buffer_get_resource_size(state->buffer, surface->renderer, - &state->buffer_width, &state->buffer_height); + if (state->buffer != NULL) { + wlr_buffer_get_resource_size(state->buffer, surface->renderer, + &state->buffer_width, &state->buffer_height); + } else { + state->buffer_width = state->buffer_height = 0; + } } int width = state->buffer_width / state->scale; From 226306ed45a1bd9491107ff0b870b364eb25ca61 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 1 Jul 2018 15:08:30 +0100 Subject: [PATCH 12/14] surface: rename wlr_surface_state.buffer to buffer_resource --- include/wlr/types/wlr_surface.h | 4 ++-- types/wlr_surface.c | 30 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 76f09cc6..b89da87a 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -22,7 +22,7 @@ enum wlr_surface_state_field { struct wlr_surface_state { uint32_t committed; // enum wlr_surface_state_field - struct wl_resource *buffer; + struct wl_resource *buffer_resource; int32_t dx, dy; // relative to previous position pixman_region32_t surface_damage, buffer_damage; pixman_region32_t opaque, input; @@ -33,7 +33,7 @@ struct wlr_surface_state { int width, height; // in surface-local coordinates int buffer_width, buffer_height; - struct wl_listener buffer_destroy_listener; + struct wl_listener buffer_destroy; }; struct wlr_surface { diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 5c594889..a7ab17e4 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -32,28 +32,28 @@ static int max(int fst, int snd) { } static void surface_state_reset_buffer(struct wlr_surface_state *state) { - if (state->buffer) { - wl_list_remove(&state->buffer_destroy_listener.link); - state->buffer = NULL; + if (state->buffer_resource) { + wl_list_remove(&state->buffer_destroy.link); + state->buffer_resource = NULL; } } static void surface_handle_buffer_destroy(struct wl_listener *listener, void *data) { struct wlr_surface_state *state = - wl_container_of(listener, state, buffer_destroy_listener); + wl_container_of(listener, state, buffer_destroy); surface_state_reset_buffer(state); } static void surface_state_set_buffer(struct wlr_surface_state *state, - struct wl_resource *buffer) { + struct wl_resource *buffer_resource) { surface_state_reset_buffer(state); - state->buffer = buffer; - if (buffer) { - wl_resource_add_destroy_listener(buffer, - &state->buffer_destroy_listener); - state->buffer_destroy_listener.notify = surface_handle_buffer_destroy; + state->buffer_resource = buffer_resource; + if (buffer_resource != NULL) { + wl_resource_add_destroy_listener(buffer_resource, + &state->buffer_destroy); + state->buffer_destroy.notify = surface_handle_buffer_destroy; } } @@ -142,9 +142,9 @@ static void surface_set_input_region(struct wl_client *client, static void surface_state_finalize(struct wlr_surface *surface, struct wlr_surface_state *state) { if ((state->committed & WLR_SURFACE_STATE_BUFFER)) { - if (state->buffer != NULL) { - wlr_buffer_get_resource_size(state->buffer, surface->renderer, - &state->buffer_width, &state->buffer_height); + if (state->buffer_resource != NULL) { + wlr_buffer_get_resource_size(state->buffer_resource, + surface->renderer, &state->buffer_width, &state->buffer_height); } else { state->buffer_width = state->buffer_height = 0; } @@ -258,7 +258,7 @@ static void surface_state_move(struct wlr_surface_state *state, surface_state_copy(state, next); if (next->committed & WLR_SURFACE_STATE_BUFFER) { - surface_state_set_buffer(state, next->buffer); + surface_state_set_buffer(state, next->buffer_resource); surface_state_reset_buffer(next); next->dx = next->dy = 0; } @@ -296,7 +296,7 @@ static void surface_damage_subsurfaces(struct wlr_subsurface *subsurface) { } static void surface_apply_damage(struct wlr_surface *surface) { - struct wl_resource *resource = surface->current.buffer; + struct wl_resource *resource = surface->current.buffer_resource; if (resource == NULL) { // NULL commit wlr_buffer_unref(surface->buffer); From e665a7412212d8cbf241ba90f6828688d8a48f9e Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 1 Jul 2018 19:43:13 +0100 Subject: [PATCH 13/14] surface: don't clip input and opaque regions These can be set to e.g. regions larger than the surface. If the surface resizes itself, it doesn't need to set again these regions. --- types/wlr_surface.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/types/wlr_surface.c b/types/wlr_surface.c index a7ab17e4..87286d6d 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -166,12 +166,6 @@ static void surface_state_finalize(struct wlr_surface *surface, pixman_region32_intersect_rect(&state->buffer_damage, &state->buffer_damage, 0, 0, state->buffer_width, state->buffer_height); - - pixman_region32_intersect_rect(&state->opaque, &state->opaque, - 0, 0, state->width, state->height); - - pixman_region32_intersect_rect(&state->input, &state->input, - 0, 0, state->width, state->height); } static void surface_update_damage(pixman_region32_t *buffer_damage, From 515d68231252194a8c230d26658fd316179704c1 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 3 Jul 2018 11:55:46 +0100 Subject: [PATCH 14/14] surface: fix damage when moving subsurfaces with scale > 1 --- 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 87286d6d..973686ef 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -809,10 +809,10 @@ static void subsurface_role_committed(struct wlr_surface *surface, void *data) { pixman_region32_union_rect(&surface->buffer_damage, &surface->buffer_damage, dx * surface->previous.scale, dy * surface->previous.scale, - surface->previous.width, surface->previous.height); + surface->previous.buffer_width, surface->previous.buffer_height); pixman_region32_union_rect(&surface->buffer_damage, &surface->buffer_damage, 0, 0, - surface->current.width, surface->current.height); + surface->current.buffer_width, surface->current.buffer_height); } }