aboutsummaryrefslogtreecommitdiff
path: root/render/swapchain.c
diff options
context:
space:
mode:
Diffstat (limited to 'render/swapchain.c')
-rw-r--r--render/swapchain.c46
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++;
+ }
+ }
}