mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-12 16:35:58 +01:00
render/swapchain: add support for buffer age
This commit is contained in:
parent
ef846a8839
commit
c11c6c4568
2 changed files with 52 additions and 7 deletions
|
@ -10,6 +10,7 @@
|
|||
struct wlr_swapchain_slot {
|
||||
struct wlr_buffer *buffer;
|
||||
bool acquired; // waiting for release
|
||||
int age;
|
||||
|
||||
struct wl_listener release;
|
||||
};
|
||||
|
@ -35,7 +36,15 @@ void wlr_swapchain_destroy(struct wlr_swapchain *swapchain);
|
|||
* The returned buffer is locked. When the caller is done with it, they must
|
||||
* unlock it by calling wlr_buffer_unlock.
|
||||
*/
|
||||
struct wlr_buffer *wlr_swapchain_acquire(
|
||||
struct wlr_swapchain *swapchain);
|
||||
struct wlr_buffer *wlr_swapchain_acquire(struct wlr_swapchain *swapchain,
|
||||
int *age);
|
||||
/**
|
||||
* Mark the buffer as submitted for presentation. This needs to be called by
|
||||
* swap chain users on frame boundaries.
|
||||
*
|
||||
* If the buffer hasn't been created via the swap chain, the call is ignored.
|
||||
*/
|
||||
void wlr_swapchain_set_buffer_submitted(struct wlr_swapchain *swapchain,
|
||||
struct wlr_buffer *buffer);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue