diff options
Diffstat (limited to 'render')
-rw-r--r-- | render/swapchain.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/render/swapchain.c b/render/swapchain.c index 4145efd2..fd9f8725 100644 --- a/render/swapchain.c +++ b/render/swapchain.c @@ -63,7 +63,8 @@ static void slot_handle_release(struct wl_listener *listener, void *data) { slot->acquired = false; } -static struct wlr_buffer *slot_acquire(struct wlr_swapchain_slot *slot) { +static struct wlr_buffer *slot_acquire(struct wlr_swapchain *swapchain, + struct wlr_swapchain_slot *slot, int *age) { assert(!slot->acquired); assert(slot->buffer != NULL); @@ -72,11 +73,15 @@ static struct wlr_buffer *slot_acquire(struct wlr_swapchain_slot *slot) { slot->release.notify = slot_handle_release; wl_signal_add(&slot->buffer->events.release, &slot->release); + if (age != NULL) { + *age = slot->age; + } + return wlr_buffer_lock(slot->buffer); } -struct wlr_buffer *wlr_swapchain_acquire( - struct wlr_swapchain *swapchain) { +struct wlr_buffer *wlr_swapchain_acquire(struct wlr_swapchain *swapchain, + int *age) { struct wlr_swapchain_slot *free_slot = NULL; for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) { struct wlr_swapchain_slot *slot = &swapchain->slots[i]; @@ -84,7 +89,7 @@ struct wlr_buffer *wlr_swapchain_acquire( continue; } if (slot->buffer != NULL) { - return slot_acquire(slot); + return slot_acquire(swapchain, slot, age); } free_slot = slot; } @@ -104,5 +109,36 @@ struct wlr_buffer *wlr_swapchain_acquire( wlr_log(WLR_ERROR, "Failed to allocate buffer"); return NULL; } - return slot_acquire(free_slot); + return slot_acquire(swapchain, free_slot, age); +} + +static bool swapchain_has_buffer(struct wlr_swapchain *swapchain, + struct wlr_buffer *buffer) { + for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) { + struct wlr_swapchain_slot *slot = &swapchain->slots[i]; + if (slot->buffer == buffer) { + return true; + } + } + return false; +} + +void wlr_swapchain_set_buffer_submitted(struct wlr_swapchain *swapchain, + struct wlr_buffer *buffer) { + assert(buffer != NULL); + + if (!swapchain_has_buffer(swapchain, buffer)) { + return; + } + + // See the algorithm described in: + // https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_buffer_age.txt + for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) { + struct wlr_swapchain_slot *slot = &swapchain->slots[i]; + if (slot->buffer == buffer) { + slot->age = 1; + } else if (slot->age > 0) { + slot->age++; + } + } } |