From 3652f1e6cfad8faf380fd34700f9694bb81e4a51 Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Sun, 5 Sep 2021 15:05:53 +0000 Subject: [PATCH] buffer: Create a global buffer registry This is used for tracking buffer damage, as opposed to frame damage. --- include/buffer.h | 21 ++++++++++++++++++++- src/buffer.c | 37 ++++++++++++++++++++++++++++++++----- src/main.c | 6 +++--- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/include/buffer.h b/include/buffer.h index 7db900e..eef7fcc 100644 --- a/include/buffer.h +++ b/include/buffer.h @@ -36,9 +36,16 @@ enum wv_buffer_type { #endif }; +enum wv_buffer_domain { + WV_BUFFER_DOMAIN_UNSPEC = 0, + WV_BUFFER_DOMAIN_OUTPUT, + WV_BUFFER_DOMAIN_CURSOR, +}; + struct wv_buffer { enum wv_buffer_type type; TAILQ_ENTRY(wv_buffer) link; + LIST_ENTRY(wv_buffer) registry_link; struct nvnc_fb* nvnc_fb; struct wl_buffer* wl_buffer; @@ -49,10 +56,19 @@ struct wv_buffer { uint32_t format; bool y_inverted; - struct pixman_region16 damage; + enum wv_buffer_domain domain; + + struct pixman_region16 frame_damage; + struct pixman_region16 buffer_damage; /* The following is only applicable to DMABUF */ struct gbm_bo* bo; + + /* The following is only applicable to cursors */ + uint16_t cursor_width; + uint16_t cursor_height; + uint16_t x_hotspot; + uint16_t y_hotspot; }; TAILQ_HEAD(wv_buffer_queue, wv_buffer); @@ -83,3 +99,6 @@ void wv_buffer_pool_resize(struct wv_buffer_pool* pool, enum wv_buffer_type, struct wv_buffer* wv_buffer_pool_acquire(struct wv_buffer_pool* pool); void wv_buffer_pool_release(struct wv_buffer_pool* pool, struct wv_buffer* buffer); + +void wv_buffer_registry_damage_all(struct pixman_region16* region, + enum wv_buffer_domain domain); diff --git a/src/buffer.c b/src/buffer.c index e026510..05c1ea5 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -47,6 +47,10 @@ extern struct wl_shm* wl_shm; extern struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf; extern struct gbm_device* gbm_device; +LIST_HEAD(wv_buffer_list, wv_buffer); + +static struct wv_buffer_list buffer_registry; + enum wv_buffer_type wv_buffer_get_available_types(void) { enum wv_buffer_type type = 0; @@ -108,7 +112,10 @@ struct wv_buffer* wv_buffer_create_shm(int width, nvnc_set_userdata(self->nvnc_fb, self, NULL); - pixman_region_init(&self->damage); + pixman_region_init(&self->frame_damage); + pixman_region_init_rect(&self->buffer_damage, 0, 0, width, height); + + LIST_INSERT_HEAD(&buffer_registry, self, registry_link); close(fd); return self; @@ -249,6 +256,11 @@ static struct wv_buffer* wv_buffer_create_dmabuf(int width, int height, nvnc_set_userdata(self->nvnc_fb, self, NULL); + pixman_region_init(&self->frame_damage); + pixman_region_init_rect(&self->buffer_damage, 0, 0, width, height); + + LIST_INSERT_HEAD(&buffer_registry, self, registry_link); + return self; nvnc_fb_failure: @@ -301,7 +313,9 @@ static void wv_buffer_destroy_dmabuf(struct wv_buffer* self) void wv_buffer_destroy(struct wv_buffer* self) { - pixman_region_fini(&self->damage); + pixman_region_fini(&self->buffer_damage); + pixman_region_fini(&self->frame_damage); + LIST_REMOVE(self, registry_link); switch (self->type) { case WV_BUFFER_SHM: @@ -321,8 +335,8 @@ void wv_buffer_destroy(struct wv_buffer* self) void wv_buffer_damage_rect(struct wv_buffer* self, int x, int y, int width, int height) { - pixman_region_union_rect(&self->damage, &self->damage, x, y, width, - height); + pixman_region_union_rect(&self->frame_damage, &self->frame_damage, x, y, + width, height); } void wv_buffer_damage_whole(struct wv_buffer* self) @@ -332,7 +346,7 @@ void wv_buffer_damage_whole(struct wv_buffer* self) void wv_buffer_damage_clear(struct wv_buffer* self) { - pixman_region_clear(&self->damage); + pixman_region_clear(&self->frame_damage); } struct wv_buffer_pool* wv_buffer_pool_create(enum wv_buffer_type type, @@ -449,3 +463,16 @@ void wv_buffer_pool_release(struct wv_buffer_pool* pool, wv_buffer_destroy(buffer); } } + +void wv_buffer_registry_damage_all(struct pixman_region16* region, + enum wv_buffer_domain domain) +{ + if (domain == WV_BUFFER_DOMAIN_UNSPEC) + return; + + struct wv_buffer *buffer; + LIST_FOREACH(buffer, &buffer_registry, registry_link) + if (buffer->domain == domain) + pixman_region_union(&buffer->buffer_damage, + &buffer->buffer_damage, region); +} diff --git a/src/main.c b/src/main.c index b47d21b..5bb8ebb 100644 --- a/src/main.c +++ b/src/main.c @@ -1086,7 +1086,7 @@ void wayvnc_process_frame(struct wayvnc* self) self->n_frames_captured++; self->damage_area_sum += - calculate_region_area(&buffer->damage); + calculate_region_area(&buffer->frame_damage); struct pixman_region16 damage; pixman_region_init(&damage); @@ -1098,12 +1098,12 @@ void wayvnc_process_frame(struct wayvnc* self) buffer_transform = wv_output_transform_compose(output_transform, WL_OUTPUT_TRANSFORM_FLIPPED_180); - wv_region_transform(&damage, &buffer->damage, + wv_region_transform(&damage, &buffer->frame_damage, WL_OUTPUT_TRANSFORM_FLIPPED_180, buffer->width, buffer->height); } else { buffer_transform = output_transform; - pixman_region_copy(&damage, &buffer->damage); + pixman_region_copy(&damage, &buffer->frame_damage); } nvnc_fb_set_transform(buffer->nvnc_fb,