mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05: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,
 | 
			
		||||
			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.active, 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->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;
 | 
			
		||||
			uint8_t *edid = get_drm_prop_blob(drm->fd,
 | 
			
		||||
				wlr_conn->id, wlr_conn->props.edid, &edid_len);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
#define _POSIX_C_SOURCE 200809L
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +27,7 @@ static const struct prop_info connector_info[] = {
 | 
			
		|||
	{ "PATH", INDEX(path) },
 | 
			
		||||
	{ "content type", INDEX(content_type) },
 | 
			
		||||
	{ "link-status", INDEX(link_status) },
 | 
			
		||||
	{ "max bpc", INDEX(max_bpc) },
 | 
			
		||||
	{ "non-desktop", INDEX(non_desktop) },
 | 
			
		||||
	{ "panel orientation", INDEX(panel_orientation) },
 | 
			
		||||
	{ "subconnector", INDEX(subconnector) },
 | 
			
		||||
| 
						 | 
				
			
			@ -181,3 +183,28 @@ char *get_drm_prop_enum(int fd, uint32_t obj, uint32_t prop_id) {
 | 
			
		|||
 | 
			
		||||
	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;
 | 
			
		||||
	bool desired_enabled;
 | 
			
		||||
	uint32_t id;
 | 
			
		||||
	uint64_t max_bpc;
 | 
			
		||||
	struct wlr_drm_lease *lease;
 | 
			
		||||
 | 
			
		||||
	struct wlr_drm_crtc *crtc;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ union wlr_drm_connector_props {
 | 
			
		|||
		uint32_t non_desktop;
 | 
			
		||||
		uint32_t panel_orientation; // not guaranteed to exist
 | 
			
		||||
		uint32_t content_type; // not guaranteed to exist
 | 
			
		||||
		uint32_t max_bpc; // not guaranteed to exist
 | 
			
		||||
 | 
			
		||||
		// 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);
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue