summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvanfanel <redwindwanderer@gmail.com>2022-09-07 16:34:17 +0100
committerMarius Vlad <marius.vlad@collabora.com>2022-11-21 13:55:20 +0200
commit24ee61445c70b62f73988c6a90aed129ea830c9e (patch)
treed3173fe1a8082eda23e7d49071ee667e5b85596a
parent870db9703cc2ad75194fca16e937e1d18ae72c2f (diff)
downloadweston-24ee61445c70b62f73988c6a90aed129ea830c9e.tar.gz
Don't change the max_bpc connector prop if mode=current.
As things are, even when mode=current is specified on the .ini file, a full modeset is needed (and done), which causes a very noticeable screen blinking. That is because setting the max_bpc on a connector needs full modesetting. The idea here is that if mode=current on the .ini, no modesetting should be done, so the current max_bpc is programmed into the connector. But if a custom max-bpc=... is specified, that will be used instead, even if mode=current on the .ini Fixes: https://gitlab.freedesktop.org/wayland/weston/-/issues/660 Signed-off-by: vanfanel <redwindwanderer@gmail.com> (cherry picked from commit 3240ccc69d1488003c1cfc36d23750145d4f13f7)
-rw-r--r--compositor/main.c14
-rw-r--r--include/libweston/backend-drm.h3
-rw-r--r--libweston/backend-drm/drm-internal.h1
-rw-r--r--libweston/backend-drm/drm.c6
-rw-r--r--libweston/backend-drm/kms.c23
-rw-r--r--man/weston-drm.man2
6 files changed, 36 insertions, 13 deletions
diff --git a/compositor/main.c b/compositor/main.c
index 2eb0a03c..73f70b22 100644
--- a/compositor/main.c
+++ b/compositor/main.c
@@ -2051,7 +2051,8 @@ drm_backend_output_configure(struct weston_output *output,
enum weston_drm_backend_output_mode mode =
WESTON_DRM_BACKEND_OUTPUT_PREFERRED;
uint32_t transform = WL_OUTPUT_TRANSFORM_NORMAL;
- uint32_t max_bpc;
+ uint32_t max_bpc = 0;
+ bool max_bpc_specified = false;
char *s;
char *modeline = NULL;
char *gbm_format = NULL;
@@ -2063,16 +2064,19 @@ drm_backend_output_configure(struct weston_output *output,
return -1;
}
- weston_config_section_get_uint(section, "max-bpc", &max_bpc, 16);
- api->set_max_bpc(output, max_bpc);
-
weston_config_section_get_string(section, "mode", &s, "preferred");
+ if (weston_config_section_get_uint(section, "max-bpc", &max_bpc, 16) == 0)
+ max_bpc_specified = true;
if (strcmp(s, "off") == 0) {
assert(0 && "off was supposed to be pruned");
return -1;
} else if (wet->drm_use_current_mode || strcmp(s, "current") == 0) {
mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT;
+ /* If mode=current and no max-bpc was specfied on the .ini file,
+ use current max_bpc so full modeset is not done. */
+ if (!max_bpc_specified)
+ max_bpc = 0;
} else if (strcmp(s, "preferred") != 0) {
modeline = s;
s = NULL;
@@ -2086,6 +2090,8 @@ drm_backend_output_configure(struct weston_output *output,
}
free(modeline);
+ api->set_max_bpc(output, max_bpc);
+
if (count_remaining_heads(output, NULL) == 1) {
struct weston_head *head = weston_output_get_first_head(output);
transform = weston_head_get_transform(head);
diff --git a/include/libweston/backend-drm.h b/include/libweston/backend-drm.h
index 548940ab..071125fa 100644
--- a/include/libweston/backend-drm.h
+++ b/include/libweston/backend-drm.h
@@ -84,7 +84,8 @@ struct weston_drm_output_api {
* The property is used for working around faulty sink hardware like
* monitors or media converters that mishandle the kernel driver
* chosen bits-per-channel on the physical link. When having trouble,
- * try a lower value like 8.
+ * try a lower value like 8. A value of 0 means that the current max
+ * bpc will be reprogrammed.
*
* The value actually used in KMS is silently clamped to the range the
* KMS driver claims to support. The default value is 16.
diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h
index f6c1617f..1ee1974c 100644
--- a/libweston/backend-drm/drm-internal.h
+++ b/libweston/backend-drm/drm-internal.h
@@ -517,6 +517,7 @@ struct drm_head {
struct backlight *backlight;
drmModeModeInfo inherited_mode; /**< Original mode on the connector */
+ uint32_t inherited_max_bpc; /**< Original max_bpc on the connector */
uint32_t inherited_crtc_id; /**< Original CRTC assignment */
};
diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c
index 962cc284..7d607ca6 100644
--- a/libweston/backend-drm/drm.c
+++ b/libweston/backend-drm/drm.c
@@ -1388,6 +1388,12 @@ drm_head_read_current_setup(struct drm_head *head, struct drm_device *device)
drmModeFreeCrtc(crtc);
}
+ /* Get the current max_bpc that's currently configured to
+ * this connector. */
+ head->inherited_max_bpc = drm_property_get_value(
+ &head->connector.props[WDRM_CONNECTOR_MAX_BPC],
+ head->connector.props_drm, 0);
+
return 0;
}
diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c
index 54010b97..0118efa1 100644
--- a/libweston/backend-drm/kms.c
+++ b/libweston/backend-drm/kms.c
@@ -912,20 +912,29 @@ drm_connector_set_max_bpc(struct drm_connector *connector,
drmModeAtomicReq *req)
{
const struct drm_property_info *info;
+ struct drm_head *head;
+ struct drm_backend *backend = output->device->backend;
uint64_t max_bpc;
uint64_t a, b;
if (!drm_connector_has_prop(connector, WDRM_CONNECTOR_MAX_BPC))
return 0;
- info = &connector->props[WDRM_CONNECTOR_MAX_BPC];
- assert(info->flags & DRM_MODE_PROP_RANGE);
- assert(info->num_range_values == 2);
- a = info->range_values[0];
- b = info->range_values[1];
- assert(a <= b);
+ if (output->max_bpc == 0) {
+ /* A value of 0 means that the current max_bpc must be programmed. */
+ head = drm_head_find_by_connector(backend, connector->connector_id);
+ max_bpc = head->inherited_max_bpc;
+ } else {
+ info = &connector->props[WDRM_CONNECTOR_MAX_BPC];
+ assert(info->flags & DRM_MODE_PROP_RANGE);
+ assert(info->num_range_values == 2);
+ a = info->range_values[0];
+ b = info->range_values[1];
+ assert(a <= b);
+
+ max_bpc = MAX(a, MIN(output->max_bpc, b));
+ }
- max_bpc = MAX(a, MIN(output->max_bpc, b));
return connector_add_prop(req, connector,
WDRM_CONNECTOR_MAX_BPC, max_bpc);
}
diff --git a/man/weston-drm.man b/man/weston-drm.man
index eaaf311c..383715d3 100644
--- a/man/weston-drm.man
+++ b/man/weston-drm.man
@@ -172,7 +172,7 @@ silenty clamped to the hardware driver supported range. This artificially
limits the driver chosen link bits-per-channel which may be useful for working
around sink hardware (e.g. monitor) limitations. The default is 16 which is
practically unlimited. If you need to work around hardware issues, try a lower
-value like 8.
+value like 8. A value of 0 means that the current max bpc will be reprogrammed.
.SS Section remote-output
.TP