diff --git a/include/wlr/types/wlr_buffer.h b/include/wlr/types/wlr_buffer.h index b4be3226..4d9640d8 100644 --- a/include/wlr/types/wlr_buffer.h +++ b/include/wlr/types/wlr_buffer.h @@ -186,7 +186,7 @@ bool wlr_resource_is_buffer(struct wl_resource *resource); * isn't mutable. */ struct wlr_client_buffer *wlr_client_buffer_apply_damage( - struct wlr_client_buffer *buffer, struct wl_resource *resource, + struct wlr_client_buffer *buffer, struct wlr_buffer *next, pixman_region32_t *damage); #endif diff --git a/types/wlr_buffer.c b/types/wlr_buffer.c index 21c274c0..86b138d9 100644 --- a/types/wlr_buffer.c +++ b/types/wlr_buffer.c @@ -272,42 +272,37 @@ struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer, } struct wlr_client_buffer *wlr_client_buffer_apply_damage( - struct wlr_client_buffer *client_buffer, struct wl_resource *resource, + struct wlr_client_buffer *client_buffer, struct wlr_buffer *next, pixman_region32_t *damage) { - assert(wlr_resource_is_buffer(resource)); - if (client_buffer->base.n_locks > 1) { // Someone else still has a reference to the buffer return NULL; } - struct wl_shm_buffer *shm_buf = wl_shm_buffer_get(resource); - if (shm_buf == NULL || - client_buffer->shm_source_format == DRM_FORMAT_INVALID) { + if ((uint32_t)next->width != client_buffer->texture->width || + (uint32_t)next->height != client_buffer->texture->height) { + return NULL; + } + + if (client_buffer->shm_source_format == DRM_FORMAT_INVALID) { // Uploading only damaged regions only works for wl_shm buffers and // mutable textures (created from wl_shm buffer) return NULL; } - enum wl_shm_format new_shm_fmt = wl_shm_buffer_get_format(shm_buf); - if (convert_wl_shm_format_to_drm(new_shm_fmt) != - client_buffer->shm_source_format) { - // Uploading to textures can't change the format + void *data; + uint32_t format; + size_t stride; + if (!buffer_begin_data_ptr_access(next, &data, &format, &stride)) { return NULL; } - int32_t stride = wl_shm_buffer_get_stride(shm_buf); - int32_t width = wl_shm_buffer_get_width(shm_buf); - int32_t height = wl_shm_buffer_get_height(shm_buf); - - if ((uint32_t)width != client_buffer->texture->width || - (uint32_t)height != client_buffer->texture->height) { + if (format != client_buffer->shm_source_format) { + // Uploading to textures can't change the format + buffer_end_data_ptr_access(next); return NULL; } - wl_shm_buffer_begin_access(shm_buf); - void *data = wl_shm_buffer_get_data(shm_buf); - int n; pixman_box32_t *rects = pixman_region32_rectangles(damage, &n); for (int i = 0; i < n; ++i) { @@ -315,12 +310,12 @@ struct wlr_client_buffer *wlr_client_buffer_apply_damage( if (!wlr_texture_write_pixels(client_buffer->texture, stride, r->x2 - r->x1, r->y2 - r->y1, r->x1, r->y1, r->x1, r->y1, data)) { - wl_shm_buffer_end_access(shm_buf); + buffer_end_data_ptr_access(next); return NULL; } } - wl_shm_buffer_end_access(shm_buf); + buffer_end_data_ptr_access(next); return client_buffer; } diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 15001c5c..a82fc5bf 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -365,8 +365,8 @@ static void surface_apply_damage(struct wlr_surface *surface) { if (surface->buffer != NULL) { struct wlr_client_buffer *updated_buffer = - wlr_client_buffer_apply_damage(surface->buffer, resource, - &surface->buffer_damage); + wlr_client_buffer_apply_damage(surface->buffer, + surface->current.buffer, &surface->buffer_damage); if (updated_buffer != NULL) { wlr_buffer_unlock(surface->current.buffer); surface->current.buffer = NULL;