buffer: add a release event

Consumers call wlr_buffer_lock. Once all consumers are done with the
buffer, only the producer should have a reference to the buffer. In this
case, we can release the buffer (and let the producer re-use it).
This commit is contained in:
Simon Ser 2020-02-28 13:25:05 +01:00
parent 1674ca725c
commit 6595db6409
6 changed files with 98 additions and 37 deletions

View file

@ -21,27 +21,49 @@ struct wlr_buffer_impl {
struct wlr_dmabuf_attributes *attribs);
};
/**
* A buffer containing pixel data.
*
* A buffer has a single producer (the party who created the buffer) and
* multiple consumers (parties reading the buffer). When all consumers are done
* with the buffer, it gets released and can be re-used by the producer. When
* the producer and all consumers are done with the buffer, it gets destroyed.
*/
struct wlr_buffer {
const struct wlr_buffer_impl *impl;
size_t n_refs;
bool dropped;
size_t n_locks;
struct {
struct wl_signal destroy;
struct wl_signal release;
} events;
};
/**
* Initialize a buffer. This function should be called by producers. The
* initialized buffer is referenced: once the producer is done with the buffer
* they should call wlr_buffer_drop.
*/
void wlr_buffer_init(struct wlr_buffer *buffer,
const struct wlr_buffer_impl *impl);
/**
* Reference the buffer.
* Unreference the buffer. This function should be called by producers when
* they are done with the buffer.
*/
struct wlr_buffer *wlr_buffer_ref(struct wlr_buffer *buffer);
void wlr_buffer_drop(struct wlr_buffer *buffer);
/**
* Unreference the buffer. After this call, `buffer` may not be accessed
* anymore.
* Lock the buffer. This function should be called by consumers to make
* sure the buffer can be safely read from. Once the consumer is done with the
* buffer, they should call wlr_buffer_unlock.
*/
void wlr_buffer_unref(struct wlr_buffer *buffer);
struct wlr_buffer *wlr_buffer_lock(struct wlr_buffer *buffer);
/**
* Unlock the buffer. This function should be called by consumers once they are
* done with the buffer.
*/
void wlr_buffer_unlock(struct wlr_buffer *buffer);
/**
* Reads the DMA-BUF attributes of the buffer. If this buffer isn't a DMA-BUF,
* returns false.
@ -70,6 +92,7 @@ struct wlr_client_buffer {
struct wlr_texture *texture;
struct wl_listener resource_destroy;
struct wl_listener release;
};
struct wlr_renderer;
@ -84,9 +107,11 @@ bool wlr_resource_is_buffer(struct wl_resource *resource);
bool wlr_resource_get_buffer_size(struct wl_resource *resource,
struct wlr_renderer *renderer, int *width, int *height);
/**
* Upload a buffer to the GPU and reference it.
* Import a client buffer and lock it.
*
* Once the caller is done with the buffer, they must call wlr_buffer_unlock.
*/
struct wlr_client_buffer *wlr_client_buffer_create(
struct wlr_client_buffer *wlr_client_buffer_import(
struct wlr_renderer *renderer, struct wl_resource *resource);
/**
* Try to update the buffer's content. On success, returns the updated buffer