diff options
author | Simon Ser <contact@emersion.fr> | 2021-06-11 18:42:15 +0200 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2021-07-28 22:52:35 +0200 |
commit | 0fb55c76d0058689493207e84976d0f3ec97d28c (patch) | |
tree | 8b7ad4c706c6bfdce3a35b407f32abb3ef93f4e9 | |
parent | 1a5b6722a8fa2b0b8b1167bb58de2f12765e28a1 (diff) |
output: allocate and attach empty buffer on modeset
Some backends need a buffer in order to be able to perform a
modeset.
-rw-r--r-- | types/wlr_output.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/types/wlr_output.c b/types/wlr_output.c index 1b7a4c8f..d8a3fc11 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -654,6 +654,50 @@ static void output_pending_resolution(struct wlr_output *output, int *width, } } +static bool output_attach_empty_buffer(struct wlr_output *output) { + assert(!(output->pending.committed & WLR_OUTPUT_STATE_BUFFER)); + + if (!wlr_output_attach_render(output, NULL)) { + return false; + } + + int width, height; + output_pending_resolution(output, &width, &height); + + struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); + wlr_renderer_begin(renderer, width, height); + wlr_renderer_clear(renderer, (float[]){0, 0, 0, 0}); + wlr_renderer_end(renderer); + + return true; +} + +static bool output_ensure_buffer(struct wlr_output *output) { + // If we're lighting up an output or changing its mode, make sure to + // provide a new buffer + bool needs_new_buffer = false; + if ((output->pending.committed & WLR_OUTPUT_STATE_ENABLED) && + output->pending.enabled) { + needs_new_buffer = true; + } + if (output->pending.committed & WLR_OUTPUT_STATE_MODE) { + needs_new_buffer = true; + } + if (!needs_new_buffer || + (output->pending.committed & WLR_OUTPUT_STATE_BUFFER)) { + return true; + } + + wlr_log(WLR_DEBUG, "Attaching empty buffer to output for modeset"); + + if (!output_attach_empty_buffer(output)) { + output_clear_back_buffer(output); + return false; + } + + return true; +} + static bool output_basic_test(struct wlr_output *output) { if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) { if (output->frame_pending) { @@ -721,6 +765,9 @@ bool wlr_output_test(struct wlr_output *output) { if (!output_basic_test(output)) { return false; } + if (!output_ensure_buffer(output)) { + return false; + } if (!output->impl->test) { return true; } @@ -733,6 +780,10 @@ bool wlr_output_commit(struct wlr_output *output) { return false; } + if (!output_ensure_buffer(output)) { + return false; + } + if ((output->pending.committed & WLR_OUTPUT_STATE_BUFFER) && output->idle_frame != NULL) { wl_event_source_remove(output->idle_frame); |