mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-15 08:22:07 -04:00
wlr_compositor: Introduce wlr_surface_consume
If the compositor is running without a renderer, that means that the compositor must be driven by something external that may or may not be there. So we have two scenarios: 1. This compositor is currently being watched and driven by some external source that is consuming buffers. This is okay, because during the commit handler `surface->current.buffer` and `surface->buffer_damage` will be usable and things will be handled like normal. 2. Things break however if the compositor is not currently driven. This however is commonly temporary. Something may not be interested right now, but later it can be. In this case we have to accumulate state until this external consumer is ready. Here, we have to accumulate the `buffer_damage` and keep the buffer locked until the consumer is ready. `wlr_surface_consume` needs to be called when the state of this surface was consumed so that it is safe to release these resources.
This commit is contained in:
parent
42c395f39c
commit
e20c0290c1
2 changed files with 21 additions and 0 deletions
|
|
@ -538,6 +538,12 @@ void wlr_surface_synced_finish(struct wlr_surface_synced *synced);
|
|||
void *wlr_surface_synced_get_state(struct wlr_surface_synced *synced,
|
||||
const struct wlr_surface_state *state);
|
||||
|
||||
/*
|
||||
* Consumes buffer and damage state of the buffer so that the compositor may
|
||||
* drop references to any of these resources.
|
||||
*/
|
||||
void wlr_surface_consume(struct wlr_surface *surface);
|
||||
|
||||
/**
|
||||
* Get a Pixman region from a wl_region resource.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -419,6 +419,10 @@ static void surface_apply_damage(struct wlr_surface *surface) {
|
|||
return;
|
||||
}
|
||||
|
||||
// lock the buffer during the commit so that everything watching the surface
|
||||
// can have a chance to take a look at the buffer.
|
||||
wlr_buffer_lock(surface->current.buffer);
|
||||
|
||||
wl_signal_add(&surface->current.buffer->events.release,
|
||||
&surface->current_buffer_release);
|
||||
|
||||
|
|
@ -427,6 +431,7 @@ static void surface_apply_damage(struct wlr_surface *surface) {
|
|||
if (surface->buffer != NULL) {
|
||||
if (wlr_client_buffer_apply_damage(surface->buffer,
|
||||
surface->current.buffer, &surface->buffer_damage)) {
|
||||
wlr_surface_consume(surface);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -437,6 +442,7 @@ static void surface_apply_damage(struct wlr_surface *surface) {
|
|||
|
||||
struct wlr_client_buffer *buffer = wlr_client_buffer_create(
|
||||
surface->current.buffer, surface->compositor->renderer);
|
||||
wlr_surface_consume(surface);
|
||||
|
||||
if (buffer == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to upload buffer");
|
||||
|
|
@ -783,6 +789,15 @@ static void surface_handle_current_buffer_release(struct wl_listener *listener,
|
|||
surface_clean_state(surface);
|
||||
}
|
||||
|
||||
void wlr_surface_consume(struct wlr_surface *surface) {
|
||||
if (surface->consumed || !surface->current.buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
surface->consumed = true;
|
||||
wlr_buffer_unlock(surface->current.buffer);
|
||||
}
|
||||
|
||||
static struct wlr_surface *surface_create(struct wl_client *client,
|
||||
uint32_t version, uint32_t id, struct wlr_compositor *compositor) {
|
||||
struct wlr_surface *surface = calloc(1, sizeof(*surface));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue