buffer: Create a global buffer registry

This is used for tracking buffer damage, as opposed to frame damage.
ext-screencopy-v1
Andri Yngvason 2021-09-05 15:05:53 +00:00
parent b292c086fe
commit 3652f1e6cf
3 changed files with 55 additions and 9 deletions

View File

@ -36,9 +36,16 @@ enum wv_buffer_type {
#endif #endif
}; };
enum wv_buffer_domain {
WV_BUFFER_DOMAIN_UNSPEC = 0,
WV_BUFFER_DOMAIN_OUTPUT,
WV_BUFFER_DOMAIN_CURSOR,
};
struct wv_buffer { struct wv_buffer {
enum wv_buffer_type type; enum wv_buffer_type type;
TAILQ_ENTRY(wv_buffer) link; TAILQ_ENTRY(wv_buffer) link;
LIST_ENTRY(wv_buffer) registry_link;
struct nvnc_fb* nvnc_fb; struct nvnc_fb* nvnc_fb;
struct wl_buffer* wl_buffer; struct wl_buffer* wl_buffer;
@ -49,10 +56,19 @@ struct wv_buffer {
uint32_t format; uint32_t format;
bool y_inverted; 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 */ /* The following is only applicable to DMABUF */
struct gbm_bo* bo; 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); 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); struct wv_buffer* wv_buffer_pool_acquire(struct wv_buffer_pool* pool);
void wv_buffer_pool_release(struct wv_buffer_pool* pool, void wv_buffer_pool_release(struct wv_buffer_pool* pool,
struct wv_buffer* buffer); struct wv_buffer* buffer);
void wv_buffer_registry_damage_all(struct pixman_region16* region,
enum wv_buffer_domain domain);

View File

@ -47,6 +47,10 @@ extern struct wl_shm* wl_shm;
extern struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf; extern struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf;
extern struct gbm_device* gbm_device; 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 wv_buffer_get_available_types(void)
{ {
enum wv_buffer_type type = 0; 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); 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); close(fd);
return self; 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); 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; return self;
nvnc_fb_failure: 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) 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) { switch (self->type) {
case WV_BUFFER_SHM: 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, void wv_buffer_damage_rect(struct wv_buffer* self, int x, int y, int width,
int height) int height)
{ {
pixman_region_union_rect(&self->damage, &self->damage, x, y, width, pixman_region_union_rect(&self->frame_damage, &self->frame_damage, x, y,
height); width, height);
} }
void wv_buffer_damage_whole(struct wv_buffer* self) 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) 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, 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); 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);
}

View File

@ -1086,7 +1086,7 @@ void wayvnc_process_frame(struct wayvnc* self)
self->n_frames_captured++; self->n_frames_captured++;
self->damage_area_sum += self->damage_area_sum +=
calculate_region_area(&buffer->damage); calculate_region_area(&buffer->frame_damage);
struct pixman_region16 damage; struct pixman_region16 damage;
pixman_region_init(&damage); pixman_region_init(&damage);
@ -1098,12 +1098,12 @@ void wayvnc_process_frame(struct wayvnc* self)
buffer_transform = wv_output_transform_compose(output_transform, buffer_transform = wv_output_transform_compose(output_transform,
WL_OUTPUT_TRANSFORM_FLIPPED_180); WL_OUTPUT_TRANSFORM_FLIPPED_180);
wv_region_transform(&damage, &buffer->damage, wv_region_transform(&damage, &buffer->frame_damage,
WL_OUTPUT_TRANSFORM_FLIPPED_180, WL_OUTPUT_TRANSFORM_FLIPPED_180,
buffer->width, buffer->height); buffer->width, buffer->height);
} else { } else {
buffer_transform = output_transform; buffer_transform = output_transform;
pixman_region_copy(&damage, &buffer->damage); pixman_region_copy(&damage, &buffer->frame_damage);
} }
nvnc_fb_set_transform(buffer->nvnc_fb, nvnc_fb_set_transform(buffer->nvnc_fb,