aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2021-06-11 18:42:15 +0200
committerSimon Ser <contact@emersion.fr>2021-07-28 22:52:35 +0200
commit0fb55c76d0058689493207e84976d0f3ec97d28c (patch)
tree8b7ad4c706c6bfdce3a35b407f32abb3ef93f4e9
parent1a5b6722a8fa2b0b8b1167bb58de2f12765e28a1 (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.c51
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);