buffer: allow concurrent data ptr accesses

This commit is contained in:
Simon Ser 2023-11-28 17:14:48 +01:00
parent 7abb227617
commit 361804c727
2 changed files with 32 additions and 9 deletions

View file

@ -51,7 +51,12 @@ struct wlr_buffer {
bool dropped;
size_t n_locks;
bool accessing_data_ptr;
size_t n_data_ptr_accesses;
uint32_t data_ptr_access_flags; // bitfield of wlr_buffer_data_ptr_access_flag
void *data_ptr_access_data;
uint32_t data_ptr_access_format;
size_t data_ptr_access_stride;
struct {
struct wl_signal destroy;

View file

@ -26,7 +26,7 @@ static void buffer_consider_destroy(struct wlr_buffer *buffer) {
return;
}
assert(!buffer->accessing_data_ptr);
assert(buffer->n_data_ptr_accesses == 0);
wl_signal_emit_mutable(&buffer->events.destroy, NULL);
wlr_addon_set_finish(&buffer->addons);
@ -74,21 +74,39 @@ bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer,
bool wlr_buffer_begin_data_ptr_access(struct wlr_buffer *buffer, uint32_t flags,
void **data, uint32_t *format, size_t *stride) {
assert(!buffer->accessing_data_ptr);
if (!buffer->impl->begin_data_ptr_access) {
return false;
}
if (!buffer->impl->begin_data_ptr_access(buffer, flags, data, format, stride)) {
return false;
if (buffer->n_data_ptr_accesses == 0) {
if (!buffer->impl->begin_data_ptr_access(buffer, flags, data, format, stride)) {
return false;
}
buffer->data_ptr_access_flags = flags;
buffer->data_ptr_access_data = *data;
buffer->data_ptr_access_format = *format;
buffer->data_ptr_access_stride = *stride;
} else {
if (buffer->data_ptr_access_flags != flags) {
return false;
}
*data = buffer->data_ptr_access_data;
*format = buffer->data_ptr_access_format;
*stride = buffer->data_ptr_access_stride;
}
buffer->accessing_data_ptr = true;
buffer->n_data_ptr_accesses++;
return true;
}
void wlr_buffer_end_data_ptr_access(struct wlr_buffer *buffer) {
assert(buffer->accessing_data_ptr);
buffer->impl->end_data_ptr_access(buffer);
buffer->accessing_data_ptr = false;
assert(buffer->n_data_ptr_accesses > 0);
buffer->n_data_ptr_accesses--;
if (buffer->n_data_ptr_accesses == 0) {
buffer->impl->end_data_ptr_access(buffer);
buffer->data_ptr_access_flags = 0;
buffer->data_ptr_access_data = NULL;
buffer->data_ptr_access_format = 0;
buffer->data_ptr_access_stride = 0;
}
}
bool wlr_buffer_get_shm(struct wlr_buffer *buffer,