From 6936e163b514fd4f43a9319f53090527fc411156 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 1 Jun 2022 21:31:54 +0200 Subject: [PATCH] backend/drm: short-circuit no-op commits Some output commits (changing e.g. the output scale or transform) don't require any change in the KMS state. Instead of going through a KMS commit, return early. Blocking KMS commits can be expensive. --- backend/drm/drm.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 2caa0ef01..97e473b6d 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -31,13 +31,16 @@ #include "render/wlr_renderer.h" #include "util/signal.h" -static const uint32_t SUPPORTED_OUTPUT_STATE = - WLR_OUTPUT_STATE_BACKEND_OPTIONAL | +// Output state which needs a KMS commit to be applied +static const uint32_t COMMIT_OUTPUT_STATE = WLR_OUTPUT_STATE_BUFFER | WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_ENABLED | WLR_OUTPUT_STATE_GAMMA_LUT; +static const uint32_t SUPPORTED_OUTPUT_STATE = + WLR_OUTPUT_STATE_BACKEND_OPTIONAL | COMMIT_OUTPUT_STATE; + bool check_drm_features(struct wlr_drm_backend *drm) { if (drmGetCap(drm->fd, DRM_CAP_CURSOR_WIDTH, &drm->cursor_width)) { drm->cursor_width = 64; @@ -474,6 +477,11 @@ static bool drm_connector_test(struct wlr_output *output, return false; } + if ((state->committed & ~COMMIT_OUTPUT_STATE) == 0) { + // This commit doesn't change the KMS state + return true; + } + if ((state->committed & WLR_OUTPUT_STATE_ENABLED) && state->enabled) { if (output->current_mode == NULL && !(state->committed & WLR_OUTPUT_STATE_MODE)) { @@ -560,6 +568,11 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn, return false; } + if ((base->committed & ~COMMIT_OUTPUT_STATE) == 0) { + // This commit doesn't change the KMS state + return true; + } + struct wlr_drm_connector_state pending = {0}; drm_connector_state_init(&pending, conn, base);