output: introduce wlr_output_test

This commit is contained in:
Simon Ser 2020-04-02 12:41:19 +02:00 committed by Drew DeVault
parent 1fa9e0203b
commit e041158988
7 changed files with 96 additions and 30 deletions

View file

@ -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); 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) { static bool drm_connector_commit_buffer(struct wlr_output *output) {
struct wlr_drm_connector *conn = get_drm_connector_from_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); 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) { static bool drm_connector_commit(struct wlr_output *output) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(output->backend); struct wlr_drm_backend *drm = get_drm_backend_from_backend(output->backend);
if (!drm_connector_test(output)) {
return false;
}
if (!drm->session->active) { if (!drm->session->active) {
return false; return false;
} }
@ -501,7 +509,7 @@ static bool drm_connector_commit(struct wlr_output *output) {
static void fill_empty_gamma_table(size_t size, static void fill_empty_gamma_table(size_t size,
uint16_t *r, uint16_t *g, uint16_t *b) { 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) { for (uint32_t i = 0; i < size; ++i) {
uint16_t val = (uint64_t)0xffff * i / (size - 1); uint16_t val = (uint64_t)0xffff * i / (size - 1);
r[i] = g[i] = b[i] = val; 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, .move_cursor = drm_connector_move_cursor,
.destroy = drm_connector_destroy, .destroy = drm_connector_destroy,
.attach_render = drm_connector_attach_render, .attach_render = drm_connector_attach_render,
.test = drm_connector_test,
.commit = drm_connector_commit, .commit = drm_connector_commit,
.set_gamma = set_drm_connector_gamma, .set_gamma = set_drm_connector_gamma,
.get_gamma_size = drm_connector_get_gamma_size, .get_gamma_size = drm_connector_get_gamma_size,

View file

@ -57,7 +57,7 @@ static bool output_attach_render(struct wlr_output *wlr_output,
buffer_age); 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) { if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
wlr_log(WLR_DEBUG, "Cannot disable a headless output"); wlr_log(WLR_DEBUG, "Cannot disable a headless output");
return false; return false;
@ -65,6 +65,17 @@ static bool output_commit(struct wlr_output *wlr_output) {
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) { if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM); 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, if (!output_set_custom_mode(wlr_output,
wlr_output->pending.custom_mode.width, wlr_output->pending.custom_mode.width,
wlr_output->pending.custom_mode.height, wlr_output->pending.custom_mode.height,

View file

@ -197,10 +197,7 @@ static bool output_attach_buffer(struct wlr_output *wlr_output,
return true; return true;
} }
static bool output_commit(struct wlr_output *wlr_output) { static bool output_test(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) { if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
wlr_log(WLR_DEBUG, "Cannot disable a Wayland output"); wlr_log(WLR_DEBUG, "Cannot disable a Wayland output");
return false; return false;
@ -208,6 +205,20 @@ static bool output_commit(struct wlr_output *wlr_output) {
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) { if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM); 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 (!output_test(wlr_output)) {
return false;
}
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
if (!output_set_custom_mode(wlr_output, if (!output_set_custom_mode(wlr_output,
wlr_output->pending.custom_mode.width, wlr_output->pending.custom_mode.width,
wlr_output->pending.custom_mode.height, wlr_output->pending.custom_mode.height,
@ -419,6 +430,7 @@ static const struct wlr_output_impl output_impl = {
.destroy = output_destroy, .destroy = output_destroy,
.attach_render = output_attach_render, .attach_render = output_attach_render,
.attach_buffer = output_attach_buffer, .attach_buffer = output_attach_buffer,
.test = output_test,
.commit = output_commit, .commit = output_commit,
.set_cursor = output_set_cursor, .set_cursor = output_set_cursor,
.move_cursor = output_move_cursor, .move_cursor = output_move_cursor,

View file

@ -99,10 +99,7 @@ static bool output_attach_render(struct wlr_output *wlr_output,
return wlr_egl_make_current(&x11->egl, output->surf, buffer_age); return wlr_egl_make_current(&x11->egl, output->surf, buffer_age);
} }
static bool output_commit(struct wlr_output *wlr_output) { static bool output_test(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) { if (wlr_output->pending.committed & WLR_OUTPUT_STATE_ENABLED) {
wlr_log(WLR_DEBUG, "Cannot disable an X11 output"); wlr_log(WLR_DEBUG, "Cannot disable an X11 output");
return false; return false;
@ -110,6 +107,20 @@ static bool output_commit(struct wlr_output *wlr_output) {
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) { if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
assert(wlr_output->pending.mode_type == WLR_OUTPUT_STATE_MODE_CUSTOM); 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 (!output_test(wlr_output)) {
return false;
}
if (wlr_output->pending.committed & WLR_OUTPUT_STATE_MODE) {
if (!output_set_custom_mode(wlr_output, if (!output_set_custom_mode(wlr_output,
wlr_output->pending.custom_mode.width, wlr_output->pending.custom_mode.width,
wlr_output->pending.custom_mode.height, 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 = { static const struct wlr_output_impl output_impl = {
.destroy = output_destroy, .destroy = output_destroy,
.attach_render = output_attach_render, .attach_render = output_attach_render,
.test = output_test,
.commit = output_commit, .commit = output_commit,
}; };

View file

@ -21,6 +21,7 @@ struct wlr_output_impl {
bool (*move_cursor)(struct wlr_output *output, int x, int y); bool (*move_cursor)(struct wlr_output *output, int x, int y);
void (*destroy)(struct wlr_output *output); void (*destroy)(struct wlr_output *output);
bool (*attach_render)(struct wlr_output *output, int *buffer_age); bool (*attach_render)(struct wlr_output *output, int *buffer_age);
bool (*test)(struct wlr_output *output);
bool (*commit)(struct wlr_output *output); bool (*commit)(struct wlr_output *output);
bool (*set_gamma)(struct wlr_output *output, size_t size, bool (*set_gamma)(struct wlr_output *output, size_t size,
const uint16_t *r, const uint16_t *g, const uint16_t *b); const uint16_t *r, const uint16_t *g, const uint16_t *b);

View file

@ -337,6 +337,14 @@ bool wlr_output_preferred_read_format(struct wlr_output *output,
*/ */
void wlr_output_set_damage(struct wlr_output *output, void wlr_output_set_damage(struct wlr_output *output,
pixman_region32_t *damage); 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 * 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 * called, the pending frame will be submitted for display and a `frame` event

View file

@ -473,16 +473,11 @@ static void output_state_clear(struct wlr_output_state *state) {
state->committed = 0; state->committed = 0;
} }
bool wlr_output_commit(struct wlr_output *output) { static bool output_basic_test(struct wlr_output *output) {
if (output->pending.committed & WLR_OUTPUT_STATE_BUFFER) { if ((output->pending.committed & WLR_OUTPUT_STATE_BUFFER) &&
if (output->frame_pending) { output->frame_pending) {
wlr_log(WLR_ERROR, "Tried to commit a buffer while a frame is pending"); wlr_log(WLR_DEBUG, "Tried to commit a buffer while a frame is pending");
goto error; return false;
}
if (output->idle_frame != NULL) {
wl_event_source_remove(output->idle_frame);
output->idle_frame = NULL;
}
} }
bool enabled = output->enabled; 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) { if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_BUFFER) {
wlr_log(WLR_ERROR, "Tried to commit a buffer on a disabled output"); wlr_log(WLR_DEBUG, "Tried to commit a buffer on a disabled output");
goto error; return false;
} }
if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_MODE) { if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_MODE) {
wlr_log(WLR_ERROR, "Tried to modeset a disabled output"); wlr_log(WLR_DEBUG, "Tried to modeset a disabled output");
goto error; return false;
} }
if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) { if (!enabled && output->pending.committed & WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED) {
wlr_log(WLR_ERROR, "Tried to enable adaptive sync on a disabled output"); wlr_log(WLR_DEBUG, "Tried to enable adaptive sync on a disabled output");
goto error; 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; struct timespec now;
@ -565,10 +582,6 @@ bool wlr_output_commit(struct wlr_output *output) {
output_state_clear(&output->pending); output_state_clear(&output->pending);
return true; return true;
error:
output_state_clear(&output->pending);
return false;
} }
void wlr_output_rollback(struct wlr_output *output) { void wlr_output_rollback(struct wlr_output *output) {