[PATCH xf86-video-amdgpu 1/7] Cache color property IDs during pre-init

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Leo (Sunpeng) Li" <sunpeng.li@xxxxxxx>

DRM creates property types with unique IDs during kernel driver init.
Cache the color property IDs on DDX init for use later, when we need
to modify these properties.

Since these IDs are the same regardless of the CRTC, they can be
cached within the private drmmode_rec object. We can also use any color-
management-enabled CRTC to initially fetch these IDs.

Also introduce an enumeration of possible color management properties,
to provide a easy and unified way of referring to them.

Signed-off-by: Leo (Sunpeng) Li <sunpeng.li at amd.com>
---
 src/drmmode_display.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/drmmode_display.h | 19 +++++++++++
 2 files changed, 109 insertions(+)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 8a1a201..36b22ad 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -746,6 +746,28 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
 	}
 }
 
+static char *cm_prop_names[] = {
+	"GAMMA_LUT_SIZE",
+	"DEGAMMA_LUT_SIZE",
+	"GAMMA_LUT",
+	"CTM",
+	"DEGAMMA_LUT",
+};
+
+/**
+ * Return the enum of the color management property with the given name.
+ */
+static enum drmmode_cm_prop get_cm_enum_from_str(const char *prop_name)
+{
+	enum drmmode_cm_prop ret;
+
+	for (ret = 0; ret < CM_NUM_PROPS; ret++) {
+		if (!strcmp(prop_name, cm_prop_names[ret]))
+			return ret;
+	}
+	return CM_INVALID_PROP;
+}
+
 static void
 drmmode_crtc_gamma_do_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green,
 			  uint16_t *blue, int size)
@@ -2413,6 +2435,72 @@ drmmode_page_flip_target_relative(AMDGPUEntPtr pAMDGPUEnt,
 				 drm_queue_seq);
 }
 
+/**
+ * Cache DRM color management property type IDs. This should be done during DDX
+ * initialization, as these IDs do not change. They will be used later to
+ * modify color management via DRM, or to determine if there's any CRTC(s) that
+ * support color management.
+ *
+ * If the cache ID's are all 0 after calling this function, then color
+ * management is not supported by any CRTC. For short, checking if the gamma
+ * LUT size property ID == 0 is sufficient.
+ *
+ * @drm_fd: DRM file descriptor
+ * @drmmode: drmmode object, where the cached IDs are stored
+ * @mode_res: The DRM mode resource containing the CRTC ids
+ */
+static void drmmode_cache_cm_prop_ids(int drm_fd,
+				      drmmode_ptr drmmode,
+				      drmModeResPtr mode_res)
+{
+	drmModeObjectPropertiesPtr drm_props;
+	drmModePropertyPtr drm_prop;
+	enum drmmode_cm_prop cm_prop;
+	uint32_t cm_enabled = 0;
+	uint32_t cm_all_enabled = (1 << CM_NUM_PROPS) - 1;
+	int i, j;
+
+	memset(drmmode->cm_prop_ids, 0, sizeof(drmmode->cm_prop_ids));
+
+	/* If even one CRTC supports cm, then we cache the properties.
+	 * Otherwise, set them all to 0.
+	 */
+	for (i = 0; i < drmmode->count_crtcs; i++) {
+
+		drm_props = drmModeObjectGetProperties(drm_fd,
+						       mode_res->crtcs[i],
+						       DRM_MODE_OBJECT_CRTC);
+		if (!drm_props)
+			continue;
+
+		for (j = 0; j < drm_props->count_props; j++) {
+			drm_prop = drmModeGetProperty(drm_fd,
+						      drm_props->props[j]);
+			if (!drm_prop)
+				/* No guarantee that the property we failed to
+				 * get isn't a cm property. Skip to next CRTC.
+				 */
+				break;
+
+			cm_prop = get_cm_enum_from_str(drm_prop->name);
+			if (cm_prop == CM_INVALID_PROP)
+				continue;
+
+			drmmode->cm_prop_ids[cm_prop] = drm_props->props[j];
+			cm_enabled |= 1 << cm_prop;
+
+			drmModeFreeProperty(drm_prop);
+		}
+		drmModeFreeObjectProperties(drm_props);
+
+		if (cm_enabled == cm_all_enabled)
+			break;
+
+		cm_enabled = 0;
+		memset(drmmode->cm_prop_ids, 0, sizeof(drmmode->cm_prop_ids));
+	}
+}
+
 Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 {
 	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
@@ -2459,6 +2547,8 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 	if (pScrn->depth == 30)
 		info->drmmode_crtc_funcs.gamma_set = NULL;
 
+	drmmode_cache_cm_prop_ids(pAMDGPUEnt->fd, drmmode, mode_res);
+
 	for (i = 0; i < mode_res->count_crtcs; i++)
 		if (!xf86IsEntityShared(pScrn->entityList[0]) ||
 		    (crtcs_needed && !(pAMDGPUEnt->assigned_crtcs & (1 << i))))
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index 25ae9f8..bbb5423 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -36,6 +36,22 @@
 #include "amdgpu_probe.h"
 #include "amdgpu.h"
 
+/*
+ * Enum of non-legacy color management properties, according to DRM. The values
+ * should be incremental, starting with 0, as defined by C99 (with the
+ * exception of the INVALID member). There are logics that depend on this fact
+ * (i.e. bitmasks).
+ */
+enum drmmode_cm_prop {
+	CM_GAMMA_LUT_SIZE,
+	CM_DEGAMMA_LUT_SIZE,
+	CM_GAMMA_LUT,
+	CM_CTM,
+	CM_DEGAMMA_LUT,
+	CM_NUM_PROPS,
+	CM_INVALID_PROP = -1,
+};
+
 typedef struct {
 	ScrnInfoPtr scrn;
 #ifdef HAVE_LIBUDEV
@@ -49,6 +65,9 @@ typedef struct {
 
 	Bool dri2_flipping;
 	Bool present_flipping;
+
+	/* Cache for DRM property type IDs for CRTC color management */
+	uint32_t cm_prop_ids[CM_NUM_PROPS];
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
-- 
2.7.4



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux