mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-25 22:25:58 +01:00
backend/drm: set "max bpc" to the max
"max bpc" is a maximum value, the driver is free to choose a smaller value depending on the bandwidth available. Some faulty monitors misbehave with higher bpc values. We'll add a workaround if users get hit by these in practice. References: https://gitlab.freedesktop.org/wayland/weston/-/issues/612
This commit is contained in:
parent
1f1c0275be
commit
1d581656c7
5 changed files with 43 additions and 0 deletions
|
@ -284,6 +284,9 @@ static bool atomic_crtc_commit(struct wlr_drm_connector *conn,
|
||||||
atomic_add(&atom, conn->id, conn->props.content_type,
|
atomic_add(&atom, conn->id, conn->props.content_type,
|
||||||
DRM_MODE_CONTENT_TYPE_GRAPHICS);
|
DRM_MODE_CONTENT_TYPE_GRAPHICS);
|
||||||
}
|
}
|
||||||
|
if (active && conn->props.max_bpc != 0 && conn->max_bpc > 0) {
|
||||||
|
atomic_add(&atom, conn->id, conn->props.max_bpc, conn->max_bpc);
|
||||||
|
}
|
||||||
atomic_add(&atom, crtc->id, crtc->props.mode_id, mode_id);
|
atomic_add(&atom, crtc->id, crtc->props.mode_id, mode_id);
|
||||||
atomic_add(&atom, crtc->id, crtc->props.active, active);
|
atomic_add(&atom, crtc->id, crtc->props.active, active);
|
||||||
if (active) {
|
if (active) {
|
||||||
|
|
|
@ -1317,6 +1317,14 @@ void scan_drm_connectors(struct wlr_drm_backend *drm,
|
||||||
wlr_conn->output.non_desktop = non_desktop;
|
wlr_conn->output.non_desktop = non_desktop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlr_conn->max_bpc = 0;
|
||||||
|
if (wlr_conn->props.max_bpc != 0) {
|
||||||
|
if (!introspect_drm_prop_range(drm->fd, wlr_conn->props.max_bpc,
|
||||||
|
NULL, &wlr_conn->max_bpc)) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to introspect 'max bpc' property");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t edid_len = 0;
|
size_t edid_len = 0;
|
||||||
uint8_t *edid = get_drm_prop_blob(drm->fd,
|
uint8_t *edid = get_drm_prop_blob(drm->fd,
|
||||||
wlr_conn->id, wlr_conn->props.edid, &edid_len);
|
wlr_conn->id, wlr_conn->props.edid, &edid_len);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -26,6 +27,7 @@ static const struct prop_info connector_info[] = {
|
||||||
{ "PATH", INDEX(path) },
|
{ "PATH", INDEX(path) },
|
||||||
{ "content type", INDEX(content_type) },
|
{ "content type", INDEX(content_type) },
|
||||||
{ "link-status", INDEX(link_status) },
|
{ "link-status", INDEX(link_status) },
|
||||||
|
{ "max bpc", INDEX(max_bpc) },
|
||||||
{ "non-desktop", INDEX(non_desktop) },
|
{ "non-desktop", INDEX(non_desktop) },
|
||||||
{ "panel orientation", INDEX(panel_orientation) },
|
{ "panel orientation", INDEX(panel_orientation) },
|
||||||
{ "subconnector", INDEX(subconnector) },
|
{ "subconnector", INDEX(subconnector) },
|
||||||
|
@ -181,3 +183,28 @@ char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop_id) {
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool introspect_drm_prop_range(int fd, uint32_t prop_id,
|
||||||
|
uint64_t *min, uint64_t *max) {
|
||||||
|
drmModePropertyRes *prop = drmModeGetProperty(fd, prop_id);
|
||||||
|
if (!prop) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drmModeGetPropertyType(prop) != DRM_MODE_PROP_RANGE) {
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(prop->count_values == 2);
|
||||||
|
|
||||||
|
if (min != NULL) {
|
||||||
|
*min = prop->values[0];
|
||||||
|
}
|
||||||
|
if (max != NULL) {
|
||||||
|
*max = prop->values[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreeProperty(prop);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ struct wlr_drm_connector {
|
||||||
enum wlr_drm_connector_status status;
|
enum wlr_drm_connector_status status;
|
||||||
bool desired_enabled;
|
bool desired_enabled;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
uint64_t max_bpc;
|
||||||
struct wlr_drm_lease *lease;
|
struct wlr_drm_lease *lease;
|
||||||
|
|
||||||
struct wlr_drm_crtc *crtc;
|
struct wlr_drm_crtc *crtc;
|
||||||
|
|
|
@ -21,6 +21,7 @@ union wlr_drm_connector_props {
|
||||||
uint32_t non_desktop;
|
uint32_t non_desktop;
|
||||||
uint32_t panel_orientation; // not guaranteed to exist
|
uint32_t panel_orientation; // not guaranteed to exist
|
||||||
uint32_t content_type; // not guaranteed to exist
|
uint32_t content_type; // not guaranteed to exist
|
||||||
|
uint32_t max_bpc; // not guaranteed to exist
|
||||||
|
|
||||||
// atomic-modesetting only
|
// atomic-modesetting only
|
||||||
|
|
||||||
|
@ -76,4 +77,7 @@ bool get_drm_prop(int fd, uint32_t obj, uint32_t prop, uint64_t *ret);
|
||||||
void *get_drm_prop_blob(int fd, uint32_t obj, uint32_t prop, size_t *ret_len);
|
void *get_drm_prop_blob(int fd, uint32_t obj, uint32_t prop, size_t *ret_len);
|
||||||
char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop);
|
char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop);
|
||||||
|
|
||||||
|
bool introspect_drm_prop_range(int fd, uint32_t prop_id,
|
||||||
|
uint64_t *min, uint64_t *max);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue