@@ -469,6 +469,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
return -EFAULT;
set_out_fence_for_crtc(state->state, crtc, fence_ptr);
+ } else if (property == config->bgcolor_property) {
+ state->bgcolor = val;
} else if (crtc->funcs->atomic_set_property) {
return crtc->funcs->atomic_set_property(crtc, state, property, val);
} else {
@@ -503,6 +505,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
else if (property == config->prop_out_fence_ptr)
*val = 0;
+ else if (property == config->bgcolor_property)
+ *val = state->bgcolor;
else if (crtc->funcs->atomic_get_property)
return crtc->funcs->atomic_get_property(crtc, state, property, val);
else
@@ -175,9 +175,22 @@
* plane does not expose the "alpha" property, then this is
* assumed to be 1.0
*
- * Note that all the property extensions described here apply either to the
- * plane or the CRTC (e.g. for the background color, which currently is not
- * exposed and assumed to be black).
+ * The property extensions described above all apply to the plane. Drivers
+ * may also expose the following crtc property extension:
+ *
+ * BACKGROUND_COLOR:
+ * Background color is setup with drm_crtc_add_bgcolor_property(). It
+ * controls the ARGB color of a full-screen layer that exists below all
+ * planes. This color will be used for pixels not covered by any plane
+ * and may also be blended with plane contents as allowed by a plane's
+ * alpha values. The background color defaults to black, and is assumed
+ * to be black for drivers that do not expose this property. Although
+ * background color isn't a plane, it is assumed that the color provided
+ * here undergoes the same pipe-level degamma/CSC/gamma transformations
+ * that planes undergo. Note that the color value provided here includes
+ * an alpha channel...non-opaque background color values are allowed,
+ * but are generally only honored in special cases (e.g., when a memory
+ * writeback connector is in use).
*/
/**
@@ -593,3 +606,25 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
return 0;
}
EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
+
+/**
+ * drm_crtc_add_bgcolor_property - add background color property
+ * @crtc: drm crtc
+ *
+ * Adds the background color property to @crtc. The property defaults to
+ * solid black and will accept 64-bit ARGB values in the format generated by
+ * drm_argb(). @crtc's state will also be updated to hold a solid black
+ * background color when this function is called.
+ */
+void drm_crtc_add_bgcolor_property(struct drm_crtc *crtc)
+{
+ u64 initval = drm_argb(16, 0xffff, 0, 0, 0);
+
+ drm_object_attach_property(&crtc->base,
+ crtc->dev->mode_config.bgcolor_property,
+ initval);
+
+ if (crtc->state)
+ crtc->state->bgcolor = initval;
+}
+EXPORT_SYMBOL(drm_crtc_add_bgcolor_property);
@@ -364,6 +364,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
return -ENOMEM;
dev->mode_config.modifiers_property = prop;
+ prop = drm_property_create_range(dev, 0, "BACKGROUND_COLOR",
+ 0, GENMASK_ULL(63, 0));
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.bgcolor_property = prop;
+
return 0;
}
@@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
struct drm_atomic_state *state);
int drm_plane_create_blend_mode_property(struct drm_plane *plane,
unsigned int supported_modes);
+void drm_crtc_add_bgcolor_property(struct drm_crtc *crtc);
#endif
@@ -274,6 +274,18 @@ struct drm_crtc_state {
*/
struct drm_property_blob *gamma_lut;
+ /**
+ * @bgcolor:
+ *
+ * RGB value representing the pipe's background color. The background
+ * color (aka "canvas color") of a pipe is the color that will be used
+ * for pixels not covered by a plane, or covered by transparent pixels
+ * of a plane. The value here should be built via drm_argb();
+ * individual color components can be extracted with desired precision
+ * via the DRM_ARGB_*() macros.
+ */
+ u64 bgcolor;
+
/**
* @target_vblank:
*
@@ -836,6 +836,11 @@ struct drm_mode_config {
*/
struct drm_property *writeback_out_fence_ptr_property;
+ /**
+ * @bgcolor_property: RGB background color for CRTC.
+ */
+ struct drm_property *bgcolor_property;
+
/* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow;
@@ -907,6 +907,34 @@ struct drm_mode_rect {
__s32 y2;
};
+/*
+ * Put ARGB values into a standard 64-bit representation that can be used
+ * for ioctl parameters, inter-driver commmunication, etc. If the component
+ * values being provided contain less than 16 bits of precision, they'll
+ * be shifted into the most significant bits.
+ */
+static inline __u64
+drm_argb(__u8 bpc, __u16 alpha, __u16 red, __u16 green, __u16 blue)
+{
+ int msb_shift = 16 - bpc;
+
+ return (__u64)alpha << msb_shift << 48 |
+ (__u64)red << msb_shift << 32 |
+ (__u64)green << msb_shift << 16 |
+ (__u64)blue << msb_shift;
+}
+
+/*
+ * Extract the specified number of bits of a specific color component from a
+ * standard 64-bit ARGB value.
+ */
+#define DRM_ARGB_COMP(c, shift, numbits) \
+ (__u16)(((c) & 0xFFFFull << (shift)) >> ((shift) + 16 - (numbits)))
+#define DRM_ARGB_BLUE(c, numbits) DRM_ARGB_COMP(c, 0, numbits)
+#define DRM_ARGB_GREEN(c, numbits) DRM_ARGB_COMP(c, 16, numbits)
+#define DRM_ARGB_RED(c, numbits) DRM_ARGB_COMP(c, 32, numbits)
+#define DRM_ARGB_ALPHA(c, numbits) DRM_ARGB_COMP(c, 48, numbits)
+
#if defined(__cplusplus)
}
#endif