aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2020-04-02 12:41:19 +0200
committerDrew DeVault <sir@cmpwn.com>2020-04-08 16:31:21 +0200
commite04115898892129977a44e76aa39103a2bdd2144 (patch)
tree3b2616fabb0ac3e8f94587df034e8637661a6f2e
parent1fa9e0203b4192659a36ddd259c174569bc227d5 (diff)
output: introduce wlr_output_test
-rw-r--r--backend/drm/drm.c11
-rw-r--r--backend/headless/output.c13
-rw-r--r--backend/wayland/output.c18
-rw-r--r--backend/x11/output.c18
-rw-r--r--include/wlr/interfaces/wlr_output.h1
-rw-r--r--include/wlr/types/wlr_output.h8
-rw-r--r--types/wlr_output.c53
7 files changed, 94 insertions, 28 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index d845a888..53d49d17 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -334,6 +334,10 @@ static bool drm_connector_attach_render(struct wlr_output *output,
return make_drm_surface_current(&conn->crtc->primary->surf, buffer_age);
}
+static bool drm_connector_test(struct wlr_output *output) {
+ return true;
+}
+
static bool drm_connector_commit_buffer(struct wlr_output *output) {
struct wlr_drm_connector *conn = get_drm_connector_from_output(output);
struct wlr_drm_backend *drm = get_drm_backend_from_backend(output->backend);
@@ -455,6 +459,10 @@ static bool drm_connector_set_custom_mode(struct wlr_output *output,
static bool drm_connector_commit(struct wlr_output *output) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(output->backend);
+ if (!drm_connector_test(output)) {
+ return false;
+ }
+
if (!drm->session->active) {
return false;
}
@@ -501,7 +509,7 @@ static bool drm_connector_commit(struct wlr_output *output) {
static void fill_empty_gamma_table(size_t size,
uint16_t *r, uint16_t *g, uint16_t *b) {
- assert(0xFFFF < UINT64_MAX / (size - 1));
+ assert(0xFFFF < UINT64_MAX / (size - 1));
for (uint32_t i = 0; i < size; ++i) {
uint16_t val = (uint64_t)0xffff * i / (size - 1);
r[i] = g[i] = b[i] = val;
@@ -1068,6 +1076,7 @@ static const struct wlr_output_impl output_impl = {
.move_cursor = drm_connector_move_cursor,
.destroy = drm_connector_destroy,
.attach_render = drm_connector_attach_render,
+ .test = drm_connector_test,
.commit = drm_connector_commit,
.set_gamma = set_drm_connector_gamma,
.get_gamma_size = drm_connector_get_gamma_size,
diff --git a/backend/headless/output.c b/backend/headless/output.c
index a2836159..326c9605 100644
--- a/backend/headless/output.c
+++ b/backend/headless/output.c
@@ -57,7 +57,7 @@ static bool output_attach_render(struct wlr_output *wlr_output,
buffer_age);
}
-static bool output_commit(struct wlr_output *wlr_output) {
+static bool output_test(struct wlr_output *wlr_output) {
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
wlr_log(WLR_DEBUG, "Cannot disable a headless output");
return false;
@@ -65,6 +65,17 @@ static bool output_commit(struct wlr_output *wlr_output) {
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
+ }
+
+ return true;
+}
+
+static bool output_commit(struct wlr_output *wlr_output) {
+ if (!output_test(wlr_output)) {
+ return false;
+ }
+
+ if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
if (!output_set_custom_mode(wlr_output,
wlr_output->pending.custom_mode.width,
wlr_output->pending.custom_mode.height,
diff --git a/backend/wayland/output.c b/backend/wayland/output.c
index 1f00209b..1a1835e1 100644
--- a/backend/wayland/output.c
+++ b/backend/wayland/output.c
@@ -197,17 +197,28 @@ static bool output_attach_buffer(struct wlr_output *wlr_output,
return true;
}
+static bool output_test(struct wlr_output *wlr_output) {
+ if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
+ wlr_log(WLR_DEBUG, "Cannot disable a Wayland output");
+ return false;
+ }
+
+ if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
+ assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
+ }
+
+ return true;
+}
+
static bool output_commit(struct wlr_output *wlr_output) {
struct wlr_wl_output *output =
get_wl_output_from_output(wlr_output);
- if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
- wlr_log(WLR_DEBUG, "Cannot disable a Wayland output");
+ if (!output_test(wlr_output)) {
return false;
}
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
- assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
if (!output_set_custom_mode(wlr_output,
wlr_output->pending.custom_mode.width,
wlr_output->pending.custom_mode.height,
@@ -419,6 +430,7 @@ static const struct wlr_output_impl output_impl = {
.destroy = output_destroy,
.attach_render = output_attach_render,
.attach_buffer = output_attach_buffer,
+ .test = output_test,
.commit = output_commit,
.set_cursor = output_set_cursor,
.move_cursor = output_move_cursor,
diff --git a/backend/x11/output.c b/backend/x11/output.c
index 9d184c48..6546c23e 100644
--- a/backend/x11/output.c
+++ b/backend/x11/output.c
@@ -99,17 +99,28 @@ static bool output_attach_render(struct wlr_output *wlr_output,
return wlr_egl_make_current(&x11->egl, output->surf, buffer_age);
}
+static bool output_test(struct wlr_output *wlr_output) {
+ if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
+ wlr_log(WLR_DEBUG, "Cannot disable an X11 output");
+ return false;
+ }
+
+ if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
+ assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
+ }
+
+ return true;
+}
+
static bool output_commit(struct wlr_output *wlr_output) {
struct wlr_x11_output *output = get_x11_output_from_output(wlr_output);
struct wlr_x11_backend *x11 = output->x11;
- if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
- wlr_log(WLR_DEBUG, "Cannot disable an X11 output");
+ if (!output_test(wlr_output)) {
return false;
}
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
- assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM);
if (!output_set_custom_mode(wlr_output,
wlr_output->pending.custom_mode.width,
wlr_output->pending.custom_mode.height,
@@ -152,6 +163,7 @@ static bool output_commit(struct wlr_output *wlr_output) {
static const struct wlr_output_impl output_impl = {
.destroy = output_destroy,
.attach_render = output_attach_render,
+ .test = output_test,
.commit = output_commit,
};
diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h
index 12980ee5..c99d0c93 100644
--- a/include/wlr/interfaces/wlr_output.h
+++ b/include/wlr/interfaces/wlr_output.h
@@ -21,6 +21,7 @@ struct wlr_output_impl {
bool (*move_cursor)(struct wlr_output *output, int x, int y);
void (*destroy)(struct wlr_output *output);
bool (*attach_render)(struct wlr_output *output, int *buffer_age);
+ bool (*test)(struct wlr_output *output);
bool (*commit)(struct wlr_output *output);
bool (*set_gamma)(struct wlr_output *output, size_t size,
const uint16_t *r, const uint16_t *g, const uint16_t *b);
diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h
index 3b7f7ee3..0e2954b9 100644
--- a/include/wlr/types/wlr_output.h
+++ b/include/wlr/types/wlr_output.h
@@ -338,6 +338,14 @@ bool wlr_output_preferred_read_format(struct wlr_output *output,
void wlr_output_set_damage(struct wlr_output *output,
pixman_region32_t *damage);
/**
+ * Test whether the pending output state would be accepted by the backend. If
+ * this function returns true, `wlr_output_commit` can only fail due to a
+ * runtime error.
+ *
+ * This function doesn't mutate the pending state.
+ */
+bool wlr_output_test(struct wlr_output *output);
+/**
* Commit the pending output state. If `wlr_output_attach_render` has been
* called, the pending frame will be submitted for display and a `frame` event
* will be scheduled.
diff --git a/types/wlr_output.c b/types/wlr_output.c
index 1692a2a0..38df4c9f 100644
--- a/types/wlr_output.c
+++ b/types/wlr_output.c
@@ -473,16 +473,11 @@ static void output_state_clear(struct wlr_output_state *state) {
state->committed = 0;
}
-bool wlr_output_commit(struct wlr_output *output) {
- if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
- if (output->frame_pending) {
- wlr_log(WLR_ERROR, "Tried to commit a buffer while a frame is pending");
- goto error;
- }
- if (output->idle_frame != NULL) {
- wl_event_source_remove(output->idle_frame);
- output->idle_frame = NULL;
- }
+static bool output_basic_test(struct wlr_output *output) {
+ if ((output->pending.committed & WLR_OUTPUT_STATE_BUFFER) &&
+ output->frame_pending) {
+ wlr_log(WLR_DEBUG, "Tried to commit a buffer while a frame is pending");
+ return false;
}
bool enabled = output->enabled;
@@ -491,16 +486,38 @@ bool wlr_output_commit(struct wlr_output *output) {
}
if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
- wlr_log(WLR_ERROR, "Tried to commit a buffer on a disabled output");
- goto error;
+ wlr_log(WLR_DEBUG, "Tried to commit a buffer on a disabled output");
+ return false;
}
if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_MODE) {
- wlr_log(WLR_ERROR, "Tried to modeset a disabled output");
- goto error;
+ wlr_log(WLR_DEBUG, "Tried to modeset a disabled output");
+ return false;
}
if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) {
- wlr_log(WLR_ERROR, "Tried to enable adaptive sync on a disabled output");
- goto error;
+ wlr_log(WLR_DEBUG, "Tried to enable adaptive sync on a disabled output");
+ return false;
+ }
+
+ return true;
+}
+
+bool wlr_output_test(struct wlr_output *output) {
+ if (!output_basic_test(output)) {
+ return false;
+ }
+ return output->impl->test(output);
+}
+
+bool wlr_output_commit(struct wlr_output *output) {
+ if (!output_basic_test(output)) {
+ wlr_log(WLR_ERROR, "Basic output test failed");
+ return false;
+ }
+
+ if ((output->pending.committed & WLR_OUTPUT_STATE_BUFFER) &&
+ output->idle_frame != NULL) {
+ wl_event_source_remove(output->idle_frame);
+ output->idle_frame = NULL;
}
struct timespec now;
@@ -565,10 +582,6 @@ bool wlr_output_commit(struct wlr_output *output) {
output_state_clear(&output->pending);
return true;
-
-error:
- output_state_clear(&output->pending);
- return false;
}
void wlr_output_rollback(struct wlr_output *output) {