diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index 03376788..461e593f 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -66,7 +66,6 @@ struct wlr_surface { float buffer_to_surface_matrix[16]; float surface_to_buffer_matrix[16]; - bool reupload_buffer; struct { struct wl_signal commit; @@ -89,7 +88,6 @@ struct wlr_surface { struct wlr_renderer; struct wlr_surface *wlr_surface_create(struct wl_resource *res, struct wlr_renderer *renderer); -void wlr_surface_flush_damage(struct wlr_surface *surface); /** * Gets a matrix you can pass into wlr_render_with_matrix to display this * surface. `matrix` is the output matrix, `projection` is the wlr_output diff --git a/rootston/output.c b/rootston/output.c index 6c7fbf51..d1b2c7de 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -19,7 +19,6 @@ static inline int64_t timespec_to_msec(const struct timespec *a) { static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation) { - wlr_surface_flush_damage(surface); if (surface->texture->valid) { int width = surface->current->buffer_width; int height = surface->current->buffer_height; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index ca7a9af5..f0cce8a7 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -345,6 +345,52 @@ static void wlr_surface_damage_subsurfaces(struct wlr_subsurface *subsurface) { } } +static void wlr_surface_flush_damage(struct wlr_surface *surface, + bool reupload_buffer) { + if (!surface->current->buffer) { + return; + } + struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current->buffer); + if (!buffer) { + if (wlr_renderer_buffer_is_drm(surface->renderer, + surface->current->buffer)) { + wlr_texture_upload_drm(surface->texture, surface->current->buffer); + goto release; + } else { + wlr_log(L_INFO, "Unknown buffer handle attached"); + return; + } + } + + uint32_t format = wl_shm_buffer_get_format(buffer); + if (reupload_buffer) { + wlr_texture_upload_shm(surface->texture, format, buffer); + } else { + pixman_region32_t damage = surface->current->buffer_damage; + if (!pixman_region32_not_empty(&damage)) { + goto release; + } + int n; + pixman_box32_t *rects = pixman_region32_rectangles(&damage, &n); + for (int i = 0; i < n; ++i) { + pixman_box32_t rect = rects[i]; + if (!wlr_texture_update_shm(surface->texture, format, + rect.x1, rect.y1, + rect.x2 - rect.x1, + rect.y2 - rect.y1, + buffer)) { + break; + } + } + } + +release: + pixman_region32_clear(&surface->current->surface_damage); + pixman_region32_clear(&surface->current->buffer_damage); + + wlr_surface_state_release_buffer(surface->current); +} + static void wlr_surface_commit_pending(struct wlr_surface *surface) { int32_t oldw = surface->current->buffer_width; int32_t oldh = surface->current->buffer_height; @@ -359,6 +405,10 @@ static void wlr_surface_commit_pending(struct wlr_surface *surface) { surface->texture->valid = false; } + bool reupload_buffer = oldw != surface->current->buffer_width || + oldh != surface->current->buffer_height; + wlr_surface_flush_damage(surface, reupload_buffer); + // commit subsurface order struct wlr_subsurface *subsurface; wl_list_for_each_reverse(subsurface, &surface->subsurface_pending_list, @@ -372,9 +422,6 @@ static void wlr_surface_commit_pending(struct wlr_surface *surface) { } } - surface->reupload_buffer = oldw != surface->current->buffer_width || - oldh != surface->current->buffer_height; - // TODO: add the invalid bitfield to this callback wl_signal_emit(&surface->events.commit, surface); } @@ -459,51 +506,6 @@ static void surface_commit(struct wl_client *client, } } -void wlr_surface_flush_damage(struct wlr_surface *surface) { - if (!surface->current->buffer) { - return; - } - struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current->buffer); - if (!buffer) { - if (wlr_renderer_buffer_is_drm(surface->renderer, - surface->current->buffer)) { - wlr_texture_upload_drm(surface->texture, surface->current->buffer); - goto release; - } else { - wlr_log(L_INFO, "Unknown buffer handle attached"); - return; - } - } - - uint32_t format = wl_shm_buffer_get_format(buffer); - if (surface->reupload_buffer) { - wlr_texture_upload_shm(surface->texture, format, buffer); - } else { - pixman_region32_t damage = surface->current->buffer_damage; - if (!pixman_region32_not_empty(&damage)) { - goto release; - } - int n; - pixman_box32_t *rects = pixman_region32_rectangles(&damage, &n); - for (int i = 0; i < n; ++i) { - pixman_box32_t rect = rects[i]; - if (!wlr_texture_update_shm(surface->texture, format, - rect.x1, rect.y1, - rect.x2 - rect.x1, - rect.y2 - rect.y1, - buffer)) { - break; - } - } - } - -release: - pixman_region32_clear(&surface->current->surface_damage); - pixman_region32_clear(&surface->current->buffer_damage); - - wlr_surface_state_release_buffer(surface->current); -} - static void surface_set_buffer_transform(struct wl_client *client, struct wl_resource *resource, int transform) { struct wlr_surface *surface = wl_resource_get_user_data(resource);