[PATCH 1/2] drm: Add infrastructure for CRTC background color property

Matt Roper matthew.d.roper at intel.com
Wed Nov 18 14:55:22 PST 2015


On Wed, Nov 18, 2015 at 01:35:54PM -0800, Bob Paauwe wrote:
> On Thu, 22 Oct 2015 17:25:34 -0700
> Matt Roper <matthew.d.roper at intel.com> wrote:
> 
> > To support CRTC background color, we need a way of communicating RGB
> > color values to the DRM.  However there is often a mismatch between how
> > userspace wants to represent the color value vs how it must be
> > programmed into the hardware; this mismatch can easily lead to
> > non-obvious bugs.  Let's create a property type that standardizes the
> > user<->kernel format and add some macros that allow drivers to extract
> > the bits they care about without having to worry about the internal
> > representation.
> > 
> > These properties are still exposed to userspace as range properties, so
> > the only userspace change we need are some helpers to build RGBA values
> > appropriately.
> > 
> > Cc: dri-devel at lists.freedesktop.org
> > Cc: Chandra Konduru <chandra.konduru at intel.com>
> > Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> > ---
> >  drivers/gpu/drm/drm_atomic.c |  4 ++++
> >  drivers/gpu/drm/drm_crtc.c   | 33 +++++++++++++++++++++++++++++
> >  include/drm/drm_crtc.h       | 49 ++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 86 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> > index 7bb3845..688ca75 100644
> > --- a/drivers/gpu/drm/drm_atomic.c
> > +++ b/drivers/gpu/drm/drm_atomic.c
> > @@ -415,6 +415,8 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  
> >  	if (property == config->prop_active)
> >  		state->active = val;
> > +	else if (property == config->prop_background_color)
> > +		state->background_color.v = val;
> >  	else if (property == config->prop_mode_id) {
> >  		struct drm_property_blob *mode =
> >  			drm_property_lookup_blob(dev, val);
> > @@ -450,6 +452,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
> >  		*val = state->active;
> >  	else if (property == config->prop_mode_id)
> >  		*val = (state->mode_blob) ? state->mode_blob->base.id : 0;
> > +	else if (property == config->prop_background_color)
> > +		*val = state->background_color.v;
> >  	else if (crtc->funcs->atomic_get_property)
> >  		return crtc->funcs->atomic_get_property(crtc, state, property, val);
> >  	else
> > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> > index e54660a..1e0dd09 100644
> > --- a/drivers/gpu/drm/drm_crtc.c
> > +++ b/drivers/gpu/drm/drm_crtc.c
> > @@ -3807,6 +3807,30 @@ struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
> >  EXPORT_SYMBOL(drm_property_create_bool);
> >  
> >  /**
> > + * drm_property_create_rgba - create a new RGBA property type
> > + * @dev: drm device
> > + * @flags: flags specifying the property type
> > + * @name: name of the property
> > + *
> > + * This creates a new generic drm property which can then be attached to a drm
> > + * object with drm_object_attach_property. The returned property object must be
> > + * freed with drm_property_destroy.
> > + *
> > + * Userspace should use the DRM_RGBA() macro to build values with the proper
> > + * bit layout.
> > + *
> > + * Returns:
> > + * A pointer to the newly created property on success, NULL on failure.
> > + */
> > +struct drm_property *drm_property_create_rgba(struct drm_device *dev, int flags,
> > +					      const char *name)
> > +{
> > +	return drm_property_create_range(dev, flags, name,
> > +					 0, GENMASK_ULL(63, 0));
> > +}
> > +EXPORT_SYMBOL(drm_property_create_rgba);
> 
> I'm not sure I understand why drm_property_create_rgba was added.  It's
> not being used.  Maybe if the
> drm_mode_create_background_color_property() below called this instead
> of create_range directly, we could then change the underlying property
> type used for rgba without having to locate all properties that are
> supposed to be of that type.  Was that the intention?

Yeah, I meant to use this for the background_color_property function
below, but I guess I forgot to go back and actually make that change.
This is more just a helper so that drivers that make driver-specific
rgba properties won't have to think about what the internal
representation really is (the same way boolean properties are really
just a helper for range [0,1] properties).

> 
> > +
> > +/**
> >   * drm_property_add_enum - add a possible value to an enumeration property
> >   * @property: enumeration property to change
> >   * @index: index of the new enumeration
> > @@ -5778,6 +5802,15 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
> >  }
> >  EXPORT_SYMBOL(drm_mode_create_rotation_property);
> >  
> > +struct drm_property
> > +*drm_mode_create_background_color_property(struct drm_device *dev)
> > +{
> > +	return drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
> > +					 "background_color",
> > +					 0, GENMASK_ULL(63, 0));
> > +}
> > +EXPORT_SYMBOL(drm_mode_create_background_color_property);
> > +
> >  /**
> >   * DOC: Tile group
> >   *
> > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> > index 3f0c690..64f3e62 100644
> > --- a/include/drm/drm_crtc.h
> > +++ b/include/drm/drm_crtc.h
> > @@ -251,6 +251,45 @@ struct drm_bridge;
> >  struct drm_atomic_state;
> >  
> >  /**
> > + * drm_rgba_t - RGBA property value type
> > + *
> > + * Structure to abstract away the representation of RGBA values with precision
> > + * up to 16 bits per color component.  This is primarily intended for use with
> > + * DRM properties that need to take a color value since we don't want userspace
> > + * to have to worry about the bit layout expected by the underlying hardware.
> > + *
> > + * We wrap the value in a structure here so that the compiler will flag any
> > + * accidental attempts by driver code to directly attempt bitwise operations
> > + * that could potentially misinterpret the value.  Drivers should instead use
> > + * the DRM_RGBA_{RED,GREEN,BLUE,ALPHA}BITS() macros to obtain the component
> > + * bits and then build values in the format their hardware expects.
> > + */
> > +typedef struct {
> > +	uint64_t v;
> > +} drm_rgba_t;
> > +
> > +static inline uint16_t
> > +drm_rgba_bits(drm_rgba_t c, unsigned compshift, unsigned bits) {
> > +	uint64_t val;
> > +
> > +	if (WARN_ON(bits > 16))
> > +		bits = 16;
> > +
> > +	val = c.v & GENMASK_ULL(compshift + 15, compshift);
> > +	return val >> (compshift + 16 - bits);
> > +}
> > +
> > +/*
> > + * Macros to access the individual color components of an RGBA property value.
> > + * If the requested number of bits is less than 16, only the most significant
> > + * bits of the color component will be returned.
> > + */
> > +#define DRM_RGBA_REDBITS(c, bits)   drm_rgba_bits(c, 48, bits)
> > +#define DRM_RGBA_GREENBITS(c, bits) drm_rgba_bits(c, 32, bits)
> > +#define DRM_RGBA_BLUEBITS(c, bits)  drm_rgba_bits(c, 16, bits)
> > +#define DRM_RGBA_ALPHABITS(c, bits) drm_rgba_bits(c, 0, bits)
> 
> Do we also need macros that drivers can use to create a RGBA value?
> I.E. maybe when doing the attach?
> 

Yeah, makes sense; the macro I have in libdrm should also be available
in the kernel.  I'll add that in the next version.


Matt


> > +
> > +/**
> >   * struct drm_crtc_state - mutable CRTC state
> >   * @crtc: backpointer to the CRTC
> >   * @enable: whether the CRTC should be enabled, gates all other state
> > @@ -264,6 +303,7 @@ struct drm_atomic_state;
> >   * 	update to ensure framebuffer cleanup isn't done too early
> >   * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
> >   * @mode: current mode timings
> > + * @background_color: background color of regions not covered by planes
> >   * @event: optional pointer to a DRM event to signal upon completion of the
> >   * 	state update
> >   * @state: backpointer to global drm_atomic_state
> > @@ -304,6 +344,9 @@ struct drm_crtc_state {
> >  	/* blob property to expose current mode to atomic userspace */
> >  	struct drm_property_blob *mode_blob;
> >  
> > +	/* CRTC background color */
> > +	drm_rgba_t background_color;
> > +
> >  	struct drm_pending_vblank_event *event;
> >  
> >  	struct drm_atomic_state *state;
> > @@ -1115,6 +1158,9 @@ struct drm_mode_config {
> >  	struct drm_property *prop_active;
> >  	struct drm_property *prop_mode_id;
> >  
> > +	/* crtc properties */
> > +	struct drm_property *prop_background_color;
> > +
> >  	/* DVI-I properties */
> >  	struct drm_property *dvi_i_subconnector_property;
> >  	struct drm_property *dvi_i_select_subconnector_property;
> > @@ -1365,6 +1411,8 @@ struct drm_property *drm_property_create_object(struct drm_device *dev,
> >  					 int flags, const char *name, uint32_t type);
> >  struct drm_property *drm_property_create_bool(struct drm_device *dev, int flags,
> >  					 const char *name);
> > +struct drm_property *drm_property_create_rgba(struct drm_device *dev,
> > +					      int flags, const char *name);
> >  struct drm_property_blob *drm_property_create_blob(struct drm_device *dev,
> >                                                     size_t length,
> >                                                     const void *data);
> > @@ -1495,6 +1543,7 @@ extern int drm_format_vert_chroma_subsampling(uint32_t format);
> >  extern const char *drm_get_format_name(uint32_t format);
> >  extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev,
> >  							      unsigned int supported_rotations);
> > +extern struct drm_property *drm_mode_create_background_color_property(struct drm_device *dev);
> >  extern unsigned int drm_rotation_simplify(unsigned int rotation,
> >  					  unsigned int supported_rotations);
> >  
> 
> 
> 
> -- 
> --
> Bob Paauwe                  
> Bob.J.Paauwe at intel.com
> IOTG / PED Software Organization
> Intel Corp.  Folsom, CA
> (916) 356-6193    
> 

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795


More information about the dri-devel mailing list