mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 12:55:58 +01:00
output: refactor frame submission API
This is necessary for direct scan-out and other upcoming features. This patch changes the output API to look like the wl_surface API. Outputs now have some double-buffered state: the frame to be submitted (currently only wlr_renderer frames are supported) and the damaged region. To attach a pending frame, use wlr_output_attach_render. To set the pending damaged region, use wlr_output_set_damage. To submit the pending state, call wlr_output_commit. This will submit the pending frame to the backend. To migrate from the old API to the new one: - Replace wlr_output_make_current calls by wlr_output_attach_render - Replace wlr_output_swap_buffers calls by wlr_output_set_damage and wlr_output_commit
This commit is contained in:
parent
56ceed38bf
commit
23e37e7b1d
12 changed files with 115 additions and 74 deletions
|
@ -89,7 +89,7 @@ static void output_handle_frame(struct wl_listener *listener, void *data) {
|
||||||
int width, height;
|
int width, height;
|
||||||
wlr_output_effective_resolution(output->wlr_output, &width, &height);
|
wlr_output_effective_resolution(output->wlr_output, &width, &height);
|
||||||
|
|
||||||
if (!wlr_output_make_current(output->wlr_output, NULL)) {
|
if (!wlr_output_attach_render(output->wlr_output, NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ static void output_handle_frame(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_renderer_end(renderer);
|
wlr_renderer_end(renderer);
|
||||||
wlr_output_swap_buffers(output->wlr_output, NULL, NULL);
|
wlr_output_commit(output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_set_surface(struct fullscreen_output *output,
|
static void output_set_surface(struct fullscreen_output *output,
|
||||||
|
|
|
@ -94,14 +94,14 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
struct sample_state *sample = output->sample;
|
struct sample_state *sample = output->sample;
|
||||||
struct wlr_output *wlr_output = output->output;
|
struct wlr_output *wlr_output = output->output;
|
||||||
|
|
||||||
wlr_output_make_current(wlr_output, NULL);
|
wlr_output_attach_render(wlr_output, NULL);
|
||||||
|
|
||||||
glClearColor(sample->clear_color[0], sample->clear_color[1],
|
glClearColor(sample->clear_color[0], sample->clear_color[1],
|
||||||
sample->clear_color[2], sample->clear_color[3]);
|
sample->clear_color[2], sample->clear_color[3]);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
wlr_output_render_software_cursors(wlr_output, NULL);
|
wlr_output_render_software_cursors(wlr_output, NULL);
|
||||||
wlr_output_swap_buffers(wlr_output, NULL, NULL);
|
wlr_output_commit(wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
static void handle_cursor_motion(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
@ -115,7 +115,7 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
struct wlr_output *wlr_output = output->output;
|
struct wlr_output *wlr_output = output->output;
|
||||||
|
|
||||||
wlr_output_make_current(wlr_output, NULL);
|
wlr_output_attach_render(wlr_output, NULL);
|
||||||
wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height);
|
wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height);
|
||||||
wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1});
|
wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1});
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_renderer_end(sample->renderer);
|
wlr_renderer_end(sample->renderer);
|
||||||
wlr_output_swap_buffers(wlr_output, NULL, NULL);
|
wlr_output_commit(wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_velocities(struct sample_state *sample,
|
static void update_velocities(struct sample_state *sample,
|
||||||
|
|
|
@ -98,11 +98,11 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
|
struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
|
||||||
assert(renderer);
|
assert(renderer);
|
||||||
|
|
||||||
wlr_output_make_current(wlr_output, NULL);
|
wlr_output_attach_render(wlr_output, NULL);
|
||||||
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
|
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
|
||||||
wlr_renderer_clear(renderer, state->clear_color);
|
wlr_renderer_clear(renderer, state->clear_color);
|
||||||
wlr_output_render_software_cursors(wlr_output, NULL);
|
wlr_output_render_software_cursors(wlr_output, NULL);
|
||||||
wlr_output_swap_buffers(wlr_output, NULL, NULL);
|
wlr_output_commit(wlr_output);
|
||||||
wlr_renderer_end(renderer);
|
wlr_renderer_end(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
wlr_output_effective_resolution(wlr_output, &width, &height);
|
wlr_output_effective_resolution(wlr_output, &width, &height);
|
||||||
|
|
||||||
wlr_output_make_current(wlr_output, NULL);
|
wlr_output_attach_render(wlr_output, NULL);
|
||||||
wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height);
|
wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height);
|
||||||
wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1});
|
wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1});
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_renderer_end(sample->renderer);
|
wlr_renderer_end(sample->renderer);
|
||||||
wlr_output_swap_buffers(wlr_output, NULL, NULL);
|
wlr_output_commit(wlr_output);
|
||||||
|
|
||||||
long ms = (now.tv_sec - sample->last_frame.tv_sec) * 1000 +
|
long ms = (now.tv_sec - sample->last_frame.tv_sec) * 1000 +
|
||||||
(now.tv_nsec - sample->last_frame.tv_nsec) / 1000000;
|
(now.tv_nsec - sample->last_frame.tv_nsec) / 1000000;
|
||||||
|
|
|
@ -56,12 +56,12 @@ void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
sample->dec = inc;
|
sample->dec = inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_output_make_current(sample_output->output, NULL);
|
wlr_output_attach_render(sample_output->output, NULL);
|
||||||
|
|
||||||
glClearColor(sample->color[0], sample->color[1], sample->color[2], 1.0);
|
glClearColor(sample->color[0], sample->color[1], sample->color[2], 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
wlr_output_swap_buffers(sample_output->output, NULL, NULL);
|
wlr_output_commit(sample_output->output);
|
||||||
sample->last_frame = now;
|
sample->last_frame = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
wlr_output_effective_resolution(wlr_output, &width, &height);
|
wlr_output_effective_resolution(wlr_output, &width, &height);
|
||||||
|
|
||||||
wlr_output_make_current(wlr_output, NULL);
|
wlr_output_attach_render(wlr_output, NULL);
|
||||||
wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height);
|
wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height);
|
||||||
wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1});
|
wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1});
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_renderer_end(sample->renderer);
|
wlr_renderer_end(sample->renderer);
|
||||||
wlr_output_swap_buffers(wlr_output, NULL, NULL);
|
wlr_output_commit(wlr_output);
|
||||||
sample->last_frame = now;
|
sample->last_frame = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
wlr_output_effective_resolution(wlr_output, &width, &height);
|
wlr_output_effective_resolution(wlr_output, &width, &height);
|
||||||
|
|
||||||
wlr_output_make_current(wlr_output, NULL);
|
wlr_output_attach_render(wlr_output, NULL);
|
||||||
wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height);
|
wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height);
|
||||||
wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1});
|
wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1});
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_renderer_end(sample->renderer);
|
wlr_renderer_end(sample->renderer);
|
||||||
wlr_output_swap_buffers(wlr_output, NULL, NULL);
|
wlr_output_commit(wlr_output);
|
||||||
sample->last_frame = now;
|
sample->last_frame = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,16 +46,31 @@ struct wlr_output_cursor {
|
||||||
} events;
|
} events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wlr_output_state_field {
|
||||||
|
WLR_OUTPUT_STATE_BUFFER = 1 << 0,
|
||||||
|
WLR_OUTPUT_STATE_DAMAGE = 1 << 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the double-buffered output state.
|
||||||
|
*/
|
||||||
|
struct wlr_output_state {
|
||||||
|
uint32_t committed; // enum wlr_output_state_field
|
||||||
|
pixman_region32_t damage;
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_output_impl;
|
struct wlr_output_impl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A compositor output region. This typically corresponds to a monitor that
|
* A compositor output region. This typically corresponds to a monitor that
|
||||||
* displays part of the compositor space.
|
* displays part of the compositor space.
|
||||||
*
|
*
|
||||||
* Compositors should listen to the `frame` event to render an output. They
|
* The `frame` event will be emitted when it is a good time for the compositor
|
||||||
* should call `wlr_output_make_current`, render and then call
|
* to submit a new frame.
|
||||||
* `wlr_output_swap_buffers`. No rendering should happen outside a `frame` event
|
*
|
||||||
* handler.
|
* To render a new frame, compositors should call `wlr_output_attach_render`,
|
||||||
|
* render and call `wlr_output_commit`. No rendering should happen outside a
|
||||||
|
* `frame` event handler or before `wlr_output_attach_render`.
|
||||||
*/
|
*/
|
||||||
struct wlr_output {
|
struct wlr_output {
|
||||||
const struct wlr_output_impl *impl;
|
const struct wlr_output_impl *impl;
|
||||||
|
@ -88,6 +103,8 @@ struct wlr_output {
|
||||||
bool frame_pending;
|
bool frame_pending;
|
||||||
float transform_matrix[9];
|
float transform_matrix[9];
|
||||||
|
|
||||||
|
struct wlr_output_state pending;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
// Request to render a frame
|
// Request to render a frame
|
||||||
struct wl_signal frame;
|
struct wl_signal frame;
|
||||||
|
@ -189,12 +206,14 @@ void wlr_output_transformed_resolution(struct wlr_output *output,
|
||||||
void wlr_output_effective_resolution(struct wlr_output *output,
|
void wlr_output_effective_resolution(struct wlr_output *output,
|
||||||
int *width, int *height);
|
int *width, int *height);
|
||||||
/**
|
/**
|
||||||
* Makes the output rendering context current.
|
* Attach the renderer's buffer to the output. Compositors must call this
|
||||||
|
* function before rendering. After they are done rendering, they should call
|
||||||
|
* `wlr_output_commit` to submit the new frame.
|
||||||
*
|
*
|
||||||
* `buffer_age` is set to the drawing buffer age in number of frames or -1 if
|
* If non-NULL, `buffer_age` is set to the drawing buffer age in number of
|
||||||
* unknown. This is useful for damage tracking.
|
* frames or -1 if unknown. This is useful for damage tracking.
|
||||||
*/
|
*/
|
||||||
bool wlr_output_make_current(struct wlr_output *output, int *buffer_age);
|
bool wlr_output_attach_render(struct wlr_output *output, int *buffer_age);
|
||||||
/**
|
/**
|
||||||
* Get the preferred format for reading pixels.
|
* Get the preferred format for reading pixels.
|
||||||
* This function might change the current rendering context.
|
* This function might change the current rendering context.
|
||||||
|
@ -202,17 +221,21 @@ bool wlr_output_make_current(struct wlr_output *output, int *buffer_age);
|
||||||
bool wlr_output_preferred_read_format(struct wlr_output *output,
|
bool wlr_output_preferred_read_format(struct wlr_output *output,
|
||||||
enum wl_shm_format *fmt);
|
enum wl_shm_format *fmt);
|
||||||
/**
|
/**
|
||||||
* Swaps the output buffers. If the time of the frame isn't known, set `when` to
|
* Set the damage region for the frame to be submitted.
|
||||||
* NULL. If the compositor doesn't support damage tracking, set `damage` to
|
|
||||||
* NULL.
|
|
||||||
*
|
*
|
||||||
* Damage is given in output-buffer-local coordinates (ie. scaled and
|
* Compositors implementing damage tracking should call this function with the
|
||||||
|
* damaged region in output-buffer-local coordinates (ie. scaled and
|
||||||
* transformed).
|
* transformed).
|
||||||
*
|
|
||||||
* Swapping buffers schedules a `frame` event.
|
|
||||||
*/
|
*/
|
||||||
bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
|
void wlr_output_set_damage(struct wlr_output *output,
|
||||||
pixman_region32_t *damage);
|
pixman_region32_t *damage);
|
||||||
|
/**
|
||||||
|
* Commit the pending output state. If `wlr_output_attach_render` has been
|
||||||
|
* called, the pending frame will be submitted for display.
|
||||||
|
*
|
||||||
|
* This function schedules a `frame` event.
|
||||||
|
*/
|
||||||
|
bool wlr_output_commit(struct wlr_output *output);
|
||||||
/**
|
/**
|
||||||
* Manually schedules a `frame` event. If a `frame` event is already pending,
|
* Manually schedules a `frame` event. If a `frame` event is already pending,
|
||||||
* it is a no-op.
|
* it is a no-op.
|
||||||
|
|
|
@ -591,8 +591,8 @@ static void output_frame(struct wl_listener *listener, void *data) {
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
/* wlr_output_make_current makes the OpenGL context current. */
|
/* wlr_output_attach_render makes the OpenGL context current. */
|
||||||
if (!wlr_output_make_current(output->wlr_output, NULL)) {
|
if (!wlr_output_attach_render(output->wlr_output, NULL)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* The "effective" resolution can change if you rotate your outputs. */
|
/* The "effective" resolution can change if you rotate your outputs. */
|
||||||
|
@ -635,7 +635,7 @@ static void output_frame(struct wl_listener *listener, void *data) {
|
||||||
/* Conclude rendering and swap the buffers, showing the final frame
|
/* Conclude rendering and swap the buffers, showing the final frame
|
||||||
* on-screen. */
|
* on-screen. */
|
||||||
wlr_renderer_end(renderer);
|
wlr_renderer_end(renderer);
|
||||||
wlr_output_swap_buffers(output->wlr_output, NULL, NULL);
|
wlr_output_commit(output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void server_new_output(struct wl_listener *listener, void *data) {
|
static void server_new_output(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
@ -282,6 +282,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
||||||
wl_signal_init(&output->events.transform);
|
wl_signal_init(&output->events.transform);
|
||||||
wl_signal_init(&output->events.destroy);
|
wl_signal_init(&output->events.destroy);
|
||||||
pixman_region32_init(&output->damage);
|
pixman_region32_init(&output->damage);
|
||||||
|
pixman_region32_init(&output->pending.damage);
|
||||||
|
|
||||||
const char *no_hardware_cursors = getenv("WLR_NO_HARDWARE_CURSORS");
|
const char *no_hardware_cursors = getenv("WLR_NO_HARDWARE_CURSORS");
|
||||||
if (no_hardware_cursors != NULL && strcmp(no_hardware_cursors, "1") == 0) {
|
if (no_hardware_cursors != NULL && strcmp(no_hardware_cursors, "1") == 0) {
|
||||||
|
@ -317,6 +318,7 @@ void wlr_output_destroy(struct wlr_output *output) {
|
||||||
wl_event_source_remove(output->idle_frame);
|
wl_event_source_remove(output->idle_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixman_region32_fini(&output->pending.damage);
|
||||||
pixman_region32_fini(&output->damage);
|
pixman_region32_fini(&output->damage);
|
||||||
|
|
||||||
if (output->impl && output->impl->destroy) {
|
if (output->impl && output->impl->destroy) {
|
||||||
|
@ -360,13 +362,18 @@ struct wlr_output_mode *wlr_output_preferred_mode(struct wlr_output *output) {
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_output_make_current(struct wlr_output *output, int *buffer_age) {
|
bool wlr_output_attach_render(struct wlr_output *output, int *buffer_age) {
|
||||||
return output->impl->make_current(output, buffer_age);
|
if (!output->impl->make_current(output, buffer_age)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->pending.committed |= WLR_OUTPUT_STATE_BUFFER;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_output_preferred_read_format(struct wlr_output *output,
|
bool wlr_output_preferred_read_format(struct wlr_output *output,
|
||||||
enum wl_shm_format *fmt) {
|
enum wl_shm_format *fmt) {
|
||||||
if (!wlr_output_make_current(output, NULL)) {
|
if (!output->impl->make_current(output, NULL)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,10 +385,21 @@ bool wlr_output_preferred_read_format(struct wlr_output *output,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
|
void wlr_output_set_damage(struct wlr_output *output,
|
||||||
pixman_region32_t *damage) {
|
pixman_region32_t *damage) {
|
||||||
|
pixman_region32_intersect_rect(&output->pending.damage, damage,
|
||||||
|
0, 0, output->width, output->height);
|
||||||
|
output->pending.committed |= WLR_OUTPUT_STATE_DAMAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void output_state_clear(struct wlr_output_state *state) {
|
||||||
|
state->committed = 0;
|
||||||
|
pixman_region32_clear(&state->damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlr_output_commit(struct wlr_output *output) {
|
||||||
if (output->frame_pending) {
|
if (output->frame_pending) {
|
||||||
wlr_log(WLR_ERROR, "Tried to swap buffers when a frame is pending");
|
wlr_log(WLR_ERROR, "Tried to commit when a frame is pending");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (output->idle_frame != NULL) {
|
if (output->idle_frame != NULL) {
|
||||||
|
@ -389,46 +407,43 @@ bool wlr_output_swap_buffers(struct wlr_output *output, struct timespec *when,
|
||||||
output->idle_frame = NULL;
|
output->idle_frame = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timespec now;
|
if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||||
if (when == NULL) {
|
struct timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
when = &now;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wlr_output_event_swap_buffers event = {
|
pixman_region32_t *damage = NULL;
|
||||||
.output = output,
|
if (output->pending.committed & WLR_OUTPUT_STATE_DAMAGE) {
|
||||||
.when = when,
|
damage = &output->pending.damage;
|
||||||
.damage = damage,
|
}
|
||||||
};
|
|
||||||
wlr_signal_emit_safe(&output->events.swap_buffers, &event);
|
|
||||||
|
|
||||||
pixman_region32_t render_damage;
|
struct wlr_output_event_swap_buffers event = {
|
||||||
pixman_region32_init(&render_damage);
|
.output = output,
|
||||||
pixman_region32_union_rect(&render_damage, &render_damage, 0, 0,
|
.when = &now,
|
||||||
output->width, output->height);
|
.damage = damage,
|
||||||
if (damage != NULL) {
|
};
|
||||||
// Damage tracking supported
|
wlr_signal_emit_safe(&output->events.swap_buffers, &event);
|
||||||
pixman_region32_intersect(&render_damage, &render_damage, damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!output->impl->swap_buffers(output, damage ? &render_damage : NULL)) {
|
if (!output->impl->swap_buffers(output, damage)) {
|
||||||
pixman_region32_fini(&render_damage);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_output_cursor *cursor;
|
||||||
|
wl_list_for_each(cursor, &output->cursors, link) {
|
||||||
|
if (!cursor->enabled || !cursor->visible || cursor->surface == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wlr_surface_send_frame_done(cursor->surface, &now);
|
||||||
|
}
|
||||||
|
|
||||||
|
output->frame_pending = true;
|
||||||
|
output->needs_swap = false;
|
||||||
|
output_state_clear(&output->pending);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_ERROR, "Tried to commit without attaching a buffer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixman_region32_fini(&render_damage);
|
|
||||||
|
|
||||||
struct wlr_output_cursor *cursor;
|
|
||||||
wl_list_for_each(cursor, &output->cursors, link) {
|
|
||||||
if (!cursor->enabled || !cursor->visible || cursor->surface == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
wlr_surface_send_frame_done(cursor->surface, when);
|
|
||||||
}
|
|
||||||
|
|
||||||
output->frame_pending = true;
|
|
||||||
output->needs_swap = false;
|
|
||||||
pixman_region32_clear(&output->damage);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ bool wlr_output_damage_make_current(struct wlr_output_damage *output_damage,
|
||||||
struct wlr_output *output = output_damage->output;
|
struct wlr_output *output = output_damage->output;
|
||||||
|
|
||||||
int buffer_age = -1;
|
int buffer_age = -1;
|
||||||
if (!wlr_output_make_current(output, &buffer_age)) {
|
if (!wlr_output_attach_render(output, &buffer_age)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,10 @@ bool wlr_output_damage_make_current(struct wlr_output_damage *output_damage,
|
||||||
|
|
||||||
bool wlr_output_damage_swap_buffers(struct wlr_output_damage *output_damage,
|
bool wlr_output_damage_swap_buffers(struct wlr_output_damage *output_damage,
|
||||||
struct timespec *when, pixman_region32_t *damage) {
|
struct timespec *when, pixman_region32_t *damage) {
|
||||||
if (!wlr_output_swap_buffers(output_damage->output, when, damage)) {
|
if (damage != NULL) {
|
||||||
|
wlr_output_set_damage(output_damage->output, damage);
|
||||||
|
}
|
||||||
|
if (!wlr_output_commit(output_damage->output)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue