|
|
@ -63,7 +63,8 @@ static void slot_handle_release(struct wl_listener *listener, void *data) {
|
|
|
|
slot->acquired = false;
|
|
|
|
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->acquired);
|
|
|
|
assert(slot->buffer != NULL);
|
|
|
|
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;
|
|
|
|
slot->release.notify = slot_handle_release;
|
|
|
|
wl_signal_add(&slot->buffer->events.release, &slot->release);
|
|
|
|
wl_signal_add(&slot->buffer->events.release, &slot->release);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (age != NULL) {
|
|
|
|
|
|
|
|
*age = slot->age;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return wlr_buffer_lock(slot->buffer);
|
|
|
|
return wlr_buffer_lock(slot->buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_buffer *wlr_swapchain_acquire(
|
|
|
|
struct wlr_buffer *wlr_swapchain_acquire(struct wlr_swapchain *swapchain,
|
|
|
|
struct wlr_swapchain *swapchain) {
|
|
|
|
int *age) {
|
|
|
|
struct wlr_swapchain_slot *free_slot = NULL;
|
|
|
|
struct wlr_swapchain_slot *free_slot = NULL;
|
|
|
|
for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) {
|
|
|
|
for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) {
|
|
|
|
struct wlr_swapchain_slot *slot = &swapchain->slots[i];
|
|
|
|
struct wlr_swapchain_slot *slot = &swapchain->slots[i];
|
|
|
@ -84,7 +89,7 @@ struct wlr_buffer *wlr_swapchain_acquire(
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (slot->buffer != NULL) {
|
|
|
|
if (slot->buffer != NULL) {
|
|
|
|
return slot_acquire(slot);
|
|
|
|
return slot_acquire(swapchain, slot, age);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free_slot = slot;
|
|
|
|
free_slot = slot;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -104,5 +109,36 @@ struct wlr_buffer *wlr_swapchain_acquire(
|
|
|
|
wlr_log(WLR_ERROR, "Failed to allocate buffer");
|
|
|
|
wlr_log(WLR_ERROR, "Failed to allocate buffer");
|
|
|
|
return NULL;
|
|
|
|
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++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|