mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-17 06:46:39 -04:00
Merge branch 'damage-ring-swapchain-helper' into 'master'
swapchain: Introduce new helper for damage rings See merge request wlroots/wlroots!4854
This commit is contained in:
commit
9ec28b81c9
3 changed files with 69 additions and 13 deletions
|
|
@ -1,12 +1,15 @@
|
||||||
#ifndef WLR_RENDER_SWAPCHAIN_H
|
#ifndef WLR_RENDER_SWAPCHAIN_H
|
||||||
#define WLR_RENDER_SWAPCHAIN_H
|
#define WLR_RENDER_SWAPCHAIN_H
|
||||||
|
|
||||||
|
#include <pixman.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/render/drm_format_set.h>
|
#include <wlr/render/drm_format_set.h>
|
||||||
|
|
||||||
#define WLR_SWAPCHAIN_CAP 4
|
#define WLR_SWAPCHAIN_CAP 4
|
||||||
|
|
||||||
|
struct wlr_damage_ring;
|
||||||
|
|
||||||
struct wlr_swapchain_slot {
|
struct wlr_swapchain_slot {
|
||||||
struct wlr_buffer *buffer;
|
struct wlr_buffer *buffer;
|
||||||
bool acquired; // waiting for release
|
bool acquired; // waiting for release
|
||||||
|
|
@ -33,13 +36,31 @@ struct wlr_swapchain *wlr_swapchain_create(
|
||||||
struct wlr_allocator *alloc, int width, int height,
|
struct wlr_allocator *alloc, int width, int height,
|
||||||
const struct wlr_drm_format *format);
|
const struct wlr_drm_format *format);
|
||||||
void wlr_swapchain_destroy(struct wlr_swapchain *swapchain);
|
void wlr_swapchain_destroy(struct wlr_swapchain *swapchain);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Acquire a buffer from the swap chain.
|
* Acquire a buffer from the swap chain.
|
||||||
*
|
*
|
||||||
|
* Can return NULL if the swapchain failed to acquire a buffer either because
|
||||||
|
* the swapchain is full, or the buffer couldn't be allocated.
|
||||||
|
*
|
||||||
* The returned buffer is locked. When the caller is done with it, they must
|
* The returned buffer is locked. When the caller is done with it, they must
|
||||||
* unlock it by calling wlr_buffer_unlock.
|
* 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire a buffer from the swap chain that is optimal for the damage ring.
|
||||||
|
* Will automatically rotate the swapchain.
|
||||||
|
*
|
||||||
|
* Can return NULL if the swapchain failed to acquire a buffer either because
|
||||||
|
* the swapchain is full, or the buffer couldn't be allocated.
|
||||||
|
*
|
||||||
|
* 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_from_damage_ring(struct wlr_swapchain *swapchain,
|
||||||
|
struct wlr_damage_ring *ring, pixman_region32_t *damage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this buffer has been created by this swapchain, and false
|
* Returns true if this buffer has been created by this swapchain, and false
|
||||||
* otherwise.
|
* otherwise.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/render/swapchain.h>
|
#include <wlr/render/swapchain.h>
|
||||||
#include <wlr/types/wlr_buffer.h>
|
#include <wlr/types/wlr_buffer.h>
|
||||||
|
#include <wlr/types/wlr_damage_ring.h>
|
||||||
#include "render/allocator/allocator.h"
|
#include "render/allocator/allocator.h"
|
||||||
#include "render/drm_format_set.h"
|
#include "render/drm_format_set.h"
|
||||||
|
|
||||||
|
|
@ -108,6 +109,40 @@ struct wlr_buffer *wlr_swapchain_acquire(struct wlr_swapchain *swapchain) {
|
||||||
return slot_acquire(swapchain, free_slot);
|
return slot_acquire(swapchain, free_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_buffer *wlr_swapchain_acquire_from_damage_ring(struct wlr_swapchain *swapchain,
|
||||||
|
struct wlr_damage_ring *ring, pixman_region32_t *damage) {
|
||||||
|
struct wlr_buffer *buffer = NULL;
|
||||||
|
|
||||||
|
struct wlr_damage_ring_buffer *entry;
|
||||||
|
wl_list_for_each(entry, &ring->buffers, link) {
|
||||||
|
for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) {
|
||||||
|
struct wlr_swapchain_slot *slot = &swapchain->slots[i];
|
||||||
|
if (slot->acquired) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slot->buffer == entry->buffer) {
|
||||||
|
buffer = slot_acquire(swapchain, slot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!buffer) {
|
||||||
|
buffer = wlr_swapchain_acquire(swapchain);
|
||||||
|
if (!buffer) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_damage_ring_rotate_buffer(ring, buffer, damage);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
bool wlr_swapchain_has_buffer(struct wlr_swapchain *swapchain,
|
bool wlr_swapchain_has_buffer(struct wlr_swapchain *swapchain,
|
||||||
struct wlr_buffer *buffer) {
|
struct wlr_buffer *buffer) {
|
||||||
for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) {
|
for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) {
|
||||||
|
|
|
||||||
|
|
@ -2103,7 +2103,9 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
swapchain = output->swapchain;
|
swapchain = output->swapchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_buffer *buffer = wlr_swapchain_acquire(swapchain);
|
pixman_region32_init(&render_data.damage);
|
||||||
|
struct wlr_buffer *buffer = wlr_swapchain_acquire_from_damage_ring(swapchain,
|
||||||
|
&scene_output->damage_ring, &render_data.damage);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2128,16 +2130,11 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
.signal_point = scene_output->in_point,
|
.signal_point = scene_output->in_point,
|
||||||
});
|
});
|
||||||
if (render_pass == NULL) {
|
if (render_pass == NULL) {
|
||||||
wlr_buffer_unlock(buffer);
|
goto fail;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render_data.render_pass = render_pass;
|
render_data.render_pass = render_pass;
|
||||||
|
|
||||||
pixman_region32_init(&render_data.damage);
|
|
||||||
wlr_damage_ring_rotate_buffer(&scene_output->damage_ring, buffer,
|
|
||||||
&render_data.damage);
|
|
||||||
|
|
||||||
pixman_region32_t background;
|
pixman_region32_t background;
|
||||||
pixman_region32_init(&background);
|
pixman_region32_init(&background);
|
||||||
pixman_region32_copy(&background, &render_data.damage);
|
pixman_region32_copy(&background, &render_data.damage);
|
||||||
|
|
@ -2219,12 +2216,7 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
pixman_region32_fini(&render_data.damage);
|
pixman_region32_fini(&render_data.damage);
|
||||||
|
|
||||||
if (!wlr_render_pass_submit(render_pass)) {
|
if (!wlr_render_pass_submit(render_pass)) {
|
||||||
wlr_buffer_unlock(buffer);
|
goto fail;
|
||||||
|
|
||||||
// if we failed to render the buffer, it will have undefined contents
|
|
||||||
// Trash the damage ring
|
|
||||||
wlr_damage_ring_add_whole(&scene_output->damage_ring);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_output_state_set_buffer(state, buffer);
|
wlr_output_state_set_buffer(state, buffer);
|
||||||
|
|
@ -2238,6 +2230,14 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
scene_output_state_attempt_gamma(scene_output, state);
|
scene_output_state_attempt_gamma(scene_output, state);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
wlr_buffer_unlock(buffer);
|
||||||
|
|
||||||
|
// if we failed to render the buffer, it will have undefined contents
|
||||||
|
// Trash the damage ring
|
||||||
|
wlr_damage_ring_add_whole(&scene_output->damage_ring);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t wlr_scene_timer_get_duration_ns(struct wlr_scene_timer *timer) {
|
int64_t wlr_scene_timer_get_duration_ns(struct wlr_scene_timer *timer) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue