buffer: stop using source resource in wlr_client_buffer_apply_damage

This is the first step towards dropping wlr_client_buffer.resource.
This commit is contained in:
Simon Ser 2021-07-09 16:55:37 +02:00 committed by Simon Zeni
parent 7b25b0ff88
commit 0abb67c478
2 changed files with 28 additions and 6 deletions

View file

@ -137,7 +137,12 @@ struct wlr_client_buffer {
*/ */
struct wlr_texture *texture; struct wlr_texture *texture;
// private state
struct wl_listener resource_destroy; struct wl_listener resource_destroy;
// If the client buffer has been created from a wl_shm buffer
uint32_t shm_source_format;
}; };
/** /**

View file

@ -1,4 +1,5 @@
#include <assert.h> #include <assert.h>
#include <drm_fourcc.h>
#include <stdlib.h> #include <stdlib.h>
#include <wlr/render/wlr_renderer.h> #include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_buffer.h> #include <wlr/types/wlr_buffer.h>
@ -168,6 +169,10 @@ static void client_buffer_resource_handle_destroy(struct wl_listener *listener,
// which case we'll read garbage. We decide to accept this risk. // which case we'll read garbage. We decide to accept this risk.
} }
static bool buffer_is_shm_client_buffer(struct wlr_buffer *buffer);
static struct wlr_shm_client_buffer *shm_client_buffer_from_buffer(
struct wlr_buffer *buffer);
struct wlr_buffer *wlr_buffer_from_resource(struct wlr_renderer *renderer, struct wlr_buffer *wlr_buffer_from_resource(struct wlr_renderer *renderer,
struct wl_resource *resource) { struct wl_resource *resource) {
assert(resource && wlr_resource_is_buffer(resource)); assert(resource && wlr_resource_is_buffer(resource));
@ -224,6 +229,14 @@ struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer,
wl_resource_add_destroy_listener(resource, &client_buffer->resource_destroy); wl_resource_add_destroy_listener(resource, &client_buffer->resource_destroy);
client_buffer->resource_destroy.notify = client_buffer_resource_handle_destroy; client_buffer->resource_destroy.notify = client_buffer_resource_handle_destroy;
if (buffer_is_shm_client_buffer(buffer)) {
struct wlr_shm_client_buffer *shm_client_buffer =
shm_client_buffer_from_buffer(buffer);
client_buffer->shm_source_format = shm_client_buffer->format;
} else {
client_buffer->shm_source_format = DRM_FORMAT_INVALID;
}
// Ensure the buffer will be released before being destroyed // Ensure the buffer will be released before being destroyed
wlr_buffer_lock(&client_buffer->base); wlr_buffer_lock(&client_buffer->base);
wlr_buffer_drop(&client_buffer->base); wlr_buffer_drop(&client_buffer->base);
@ -242,16 +255,16 @@ struct wlr_client_buffer *wlr_client_buffer_apply_damage(
} }
struct wl_shm_buffer *shm_buf = wl_shm_buffer_get(resource); struct wl_shm_buffer *shm_buf = wl_shm_buffer_get(resource);
struct wl_shm_buffer *old_shm_buf = wl_shm_buffer_get(client_buffer->resource); if (shm_buf == NULL ||
if (shm_buf == NULL || old_shm_buf == NULL) { client_buffer->shm_source_format == DRM_FORMAT_INVALID) {
// Uploading only damaged regions only works for wl_shm buffers and // Uploading only damaged regions only works for wl_shm buffers and
// mutable textures (created from wl_shm buffer) // mutable textures (created from wl_shm buffer)
return NULL; return NULL;
} }
enum wl_shm_format new_fmt = wl_shm_buffer_get_format(shm_buf); enum wl_shm_format new_shm_fmt = wl_shm_buffer_get_format(shm_buf);
enum wl_shm_format old_fmt = wl_shm_buffer_get_format(old_shm_buf); if (convert_wl_shm_format_to_drm(new_shm_fmt) !=
if (new_fmt != old_fmt) { client_buffer->shm_source_format) {
// Uploading to textures can't change the format // Uploading to textures can't change the format
return NULL; return NULL;
} }
@ -292,9 +305,13 @@ struct wlr_client_buffer *wlr_client_buffer_apply_damage(
static const struct wlr_buffer_impl shm_client_buffer_impl; static const struct wlr_buffer_impl shm_client_buffer_impl;
static bool buffer_is_shm_client_buffer(struct wlr_buffer *buffer) {
return buffer->impl == &shm_client_buffer_impl;
}
static struct wlr_shm_client_buffer *shm_client_buffer_from_buffer( static struct wlr_shm_client_buffer *shm_client_buffer_from_buffer(
struct wlr_buffer *buffer) { struct wlr_buffer *buffer) {
assert(buffer->impl == &shm_client_buffer_impl); assert(buffer_is_shm_client_buffer(buffer));
return (struct wlr_shm_client_buffer *)buffer; return (struct wlr_shm_client_buffer *)buffer;
} }