[RFC,v4,2/7] drm: Introduce pixel_source DRM plane property

Message ID 20230404-solid-fill-v4-2-f4ec0caa742d@quicinc.com
State New
Headers
Series Support for Solid Fill Planes |

Commit Message

Jessica Zhang June 30, 2023, 12:25 a.m. UTC
  Add support for pixel_source property to drm_plane and related
documentation.

This enum property will allow user to specify a pixel source for the
plane. Possible pixel sources will be defined in the
drm_plane_pixel_source enum.

The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
 drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
 drivers/gpu/drm/drm_blend.c               | 81 +++++++++++++++++++++++++++++++
 include/drm/drm_blend.h                   |  2 +
 include/drm/drm_plane.h                   | 21 ++++++++
 5 files changed, 109 insertions(+)
  

Comments

Pekka Paalanen June 30, 2023, 8:27 a.m. UTC | #1
On Fri, 30 Jun 2023 03:42:28 +0300
Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:

> On 30/06/2023 03:25, Jessica Zhang wrote:
> > Add support for pixel_source property to drm_plane and related
> > documentation.
> > 
> > This enum property will allow user to specify a pixel source for the
> > plane. Possible pixel sources will be defined in the
> > drm_plane_pixel_source enum.
> > 
> > The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
> > DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.  
> 
> I think, this should come before the solid fill property addition. First 
> you tell that there is a possibility to define other pixel sources, then 
> additional sources are defined.

Hi,

that would be logical indeed.

> > 
> > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > ---
> >   drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
> >   drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
> >   drivers/gpu/drm/drm_blend.c               | 81 +++++++++++++++++++++++++++++++
> >   include/drm/drm_blend.h                   |  2 +
> >   include/drm/drm_plane.h                   | 21 ++++++++
> >   5 files changed, 109 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
> > index fe14be2bd2b2..86fb876efbe6 100644
> > --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> > @@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
> >   
> >   	plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
> >   	plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> > +	plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
> >   
> >   	if (plane_state->solid_fill_blob) {
> >   		drm_property_blob_put(plane_state->solid_fill_blob);
> > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> > index a28b4ee79444..6e59c21af66b 100644
> > --- a/drivers/gpu/drm/drm_atomic_uapi.c
> > +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> > @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
> >   		drm_property_blob_put(solid_fill);
> >   
> >   		return ret;
> > +	} else if (property == plane->pixel_source_property) {
> > +		state->pixel_source = val;
> >   	} else if (property == plane->alpha_property) {
> >   		state->alpha = val;
> >   	} else if (property == plane->blend_mode_property) {  
> 
> I think, it was pointed out in the discussion that drm_mode_setplane() 
> (a pre-atomic IOCTL to turn the plane on and off) should also reset 
> pixel_source to FB.
> 
> > @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
> >   	} else if (property == plane->solid_fill_property) {
> >   		*val = state->solid_fill_blob ?
> >   			state->solid_fill_blob->base.id : 0;
> > +	} else if (property == plane->pixel_source_property) {
> > +		*val = state->pixel_source;
> >   	} else if (property == plane->alpha_property) {
> >   		*val = state->alpha;
> >   	} else if (property == plane->blend_mode_property) {
> > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> > index 38c3c5d6453a..8c100a957ee2 100644
> > --- a/drivers/gpu/drm/drm_blend.c
> > +++ b/drivers/gpu/drm/drm_blend.c
> > @@ -189,6 +189,18 @@
> >    *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
> >    *	contains pixel data that drivers can use to fill a plane.
> >    *
> > + * pixel_source:
> > + *	pixel_source is set up with drm_plane_create_pixel_source_property().
> > + *	It is used to toggle the source of pixel data for the plane.

Other sources than the selected one are ignored?

> > + *
> > + *	Possible values:

Wouldn't hurt to explicitly mention here that this is an enum.

> > + *
> > + *	"FB":
> > + *		Framebuffer source
> > + *
> > + *	"COLOR":
> > + *		solid_fill source

I think these two should be more explicit. Framebuffer source is the
usual source from the property "FB_ID". Solid fill source comes from
the property "solid_fill".

Why "COLOR" and not, say, "SOLID_FILL"?

> > + *
> >    * 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).
> > @@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct drm_plane *plane)
> >   	return 0;
> >   }
> >   EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
> > +
> > +/**
> > + * drm_plane_create_pixel_source_property - create a new pixel source property
> > + * @plane: drm plane
> > + * @supported_sources: bitmask of supported pixel_sources for the driver (NOT
> > + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it will be supported
> > + *                     by default).  
> 
> I'd say this is too strong. I'd suggest either renaming this to 
> extra_sources (mentioning that FB is enabled for all the planes) or 
> allowing any source bitmask (mentioning that FB should be enabled by the 
> caller, unless there is a good reason not to do so).

Right. I don't see any problem with having planes of type OVERLAY that
support only solid_fill and no FB. Planes of type PRIMARY and CURSOR I
would expect to always support at least FB.

Atomic userspace is prepared to have an OVERLAY plane fail for any
arbitrary reason. Legacy userspace probably should not ever see a plane
that does not support FB.

> > + *
> > + * This creates a new property describing the current source of pixel data for the
> > + * plane.
> > + *
> > + * The property is exposed to userspace as an enumeration property called
> > + * "pixel_source" and has the following enumeration values:
> > + *
> > + * "FB":
> > + *	Framebuffer pixel source
> > + *
> > + * "COLOR":
> > + *	Solid fill color pixel source
> > + *
> > + * Returns:
> > + * Zero on success, negative errno on failure.
> > + */
> > +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
> > +					   unsigned int supported_sources)
> > +{
> > +	struct drm_device *dev = plane->dev;
> > +	struct drm_property *prop;
> > +	const struct drm_prop_enum_list enum_list[] = {
> > +		{ DRM_PLANE_PIXEL_SOURCE_FB, "FB" },
> > +		{ DRM_PLANE_PIXEL_SOURCE_COLOR, "COLOR" },
> > +	};
> > +	unsigned int valid_source_mask = BIT(DRM_PLANE_PIXEL_SOURCE_FB) |
> > +				       BIT(DRM_PLANE_PIXEL_SOURCE_COLOR);  
> 
> 
> static const?
> 
> > +	int i;
> > +
> > +	/* FB is supported by default */
> > +	supported_sources |= BIT(DRM_PLANE_PIXEL_SOURCE_FB);
> > +
> > +	if (WARN_ON(supported_sources & ~valid_source_mask))
> > +		return -EINVAL;
> > +
> > +	prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "pixel_source",

Shouldn't this be an atomic prop?


> > +			hweight32(supported_sources));
> > +
> > +	if (!prop)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(enum_list); i++) {
> > +		int ret;
> > +
> > +		if (!(BIT(enum_list[i].type) & supported_sources))  
> 
> test_bit?
> 
> > +			continue;
> > +
> > +		ret = drm_property_add_enum(prop, enum_list[i].type, enum_list[i].name);
> > +  
> 
> No need for an empty line in such cases. Please drop it.
> 
> > +		if (ret) {
> > +			drm_property_destroy(dev, prop);
> > +
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	drm_object_attach_property(&plane->base, prop, DRM_PLANE_PIXEL_SOURCE_FB);
> > +	plane->pixel_source_property = prop;
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(drm_plane_create_pixel_source_property);
> > diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> > index 0338a860b9c8..31af7cfa5b1b 100644
> > --- a/include/drm/drm_blend.h
> > +++ b/include/drm/drm_blend.h
> > @@ -59,4 +59,6 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
> >   int drm_plane_create_blend_mode_property(struct drm_plane *plane,
> >   					 unsigned int supported_modes);
> >   int drm_plane_create_solid_fill_property(struct drm_plane *plane);
> > +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
> > +					   unsigned int supported_sources);
> >   #endif
> > diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> > index f6ab313cb83e..73fb6cf8a5d9 100644
> > --- a/include/drm/drm_plane.h
> > +++ b/include/drm/drm_plane.h
> > @@ -59,6 +59,12 @@ struct drm_solid_fill {
> >   	uint32_t b;
> >   };
> >   
> > +enum drm_plane_pixel_source {
> > +	DRM_PLANE_PIXEL_SOURCE_FB,
> > +	DRM_PLANE_PIXEL_SOURCE_COLOR,
> > +	DRM_PLANE_PIXEL_SOURCE_MAX
> > +};

Just to be very clear that I'm not confusing you with my comment about
UAPI headers in the previous patch, this enum is already in a good
place. It does not belong in a UAPI header, because userspace
recognises enum values by the name string.


Thanks,
pq

> > +
> >   /**
> >    * struct drm_plane_state - mutable plane state
> >    *
> > @@ -152,6 +158,14 @@ struct drm_plane_state {
> >   	 */
> >   	struct drm_solid_fill solid_fill;
> >   
> > +	/*
> > +	 * @pixel_source:
> > +	 *
> > +	 * Source of pixel information for the plane. See
> > +	 * drm_plane_create_pixel_source_property() for more details.
> > +	 */
> > +	enum drm_plane_pixel_source pixel_source;
> > +
> >   	/**
> >   	 * @alpha:
> >   	 * Opacity of the plane with 0 as completely transparent and 0xffff as
> > @@ -742,6 +756,13 @@ struct drm_plane {
> >   	 */
> >   	struct drm_property *solid_fill_property;
> >   
> > +	/*
> > +	 * @pixel_source_property:
> > +	 * Optional pixel_source property for this plane. See
> > +	 * drm_plane_create_pixel_source_property().
> > +	 */
> > +	struct drm_property *pixel_source_property;
> > +
> >   	/**
> >   	 * @alpha_property:
> >   	 * Optional alpha property for this plane. See
> >   
>
  
Sebastian Wick June 30, 2023, 2:43 p.m. UTC | #2
On Fri, Jun 30, 2023 at 2:26 AM Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>
> Add support for pixel_source property to drm_plane and related
> documentation.
>
> This enum property will allow user to specify a pixel source for the
> plane. Possible pixel sources will be defined in the
> drm_plane_pixel_source enum.
>
> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
>
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>  drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
>  drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
>  drivers/gpu/drm/drm_blend.c               | 81 +++++++++++++++++++++++++++++++
>  include/drm/drm_blend.h                   |  2 +
>  include/drm/drm_plane.h                   | 21 ++++++++
>  5 files changed, 109 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
> index fe14be2bd2b2..86fb876efbe6 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
>
>         plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>         plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> +       plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
>
>         if (plane_state->solid_fill_blob) {
>                 drm_property_blob_put(plane_state->solid_fill_blob);
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index a28b4ee79444..6e59c21af66b 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
>                 drm_property_blob_put(solid_fill);
>
>                 return ret;
> +       } else if (property == plane->pixel_source_property) {
> +               state->pixel_source = val;
>         } else if (property == plane->alpha_property) {
>                 state->alpha = val;
>         } else if (property == plane->blend_mode_property) {
> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>         } else if (property == plane->solid_fill_property) {
>                 *val = state->solid_fill_blob ?
>                         state->solid_fill_blob->base.id : 0;
> +       } else if (property == plane->pixel_source_property) {
> +               *val = state->pixel_source;
>         } else if (property == plane->alpha_property) {
>                 *val = state->alpha;
>         } else if (property == plane->blend_mode_property) {
> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> index 38c3c5d6453a..8c100a957ee2 100644
> --- a/drivers/gpu/drm/drm_blend.c
> +++ b/drivers/gpu/drm/drm_blend.c
> @@ -189,6 +189,18 @@
>   *     solid_fill is set up with drm_plane_create_solid_fill_property(). It
>   *     contains pixel data that drivers can use to fill a plane.
>   *
> + * pixel_source:
> + *     pixel_source is set up with drm_plane_create_pixel_source_property().
> + *     It is used to toggle the source of pixel data for the plane.
> + *
> + *     Possible values:
> + *
> + *     "FB":
> + *             Framebuffer source
> + *
> + *     "COLOR":
> + *             solid_fill source
> + *
>   * 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).
> @@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct drm_plane *plane)
>         return 0;
>  }
>  EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
> +
> +/**
> + * drm_plane_create_pixel_source_property - create a new pixel source property
> + * @plane: drm plane
> + * @supported_sources: bitmask of supported pixel_sources for the driver (NOT
> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it will be supported
> + *                     by default).
> + *
> + * This creates a new property describing the current source of pixel data for the
> + * plane.
> + *
> + * The property is exposed to userspace as an enumeration property called
> + * "pixel_source" and has the following enumeration values:
> + *
> + * "FB":
> + *     Framebuffer pixel source
> + *
> + * "COLOR":
> + *     Solid fill color pixel source

Can we add a "NONE" value?

I know it has been discussed earlier if we *need*  this and I don't
think we do. I just think it would be better API design to disable
planes this way than having to know that a framebuffer pixel source
with a NULL framebuffer disables the plane. Obviously also keep the
old behavior for backwards compatibility.

> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
> +                                          unsigned int supported_sources)
> +{
> +       struct drm_device *dev = plane->dev;
> +       struct drm_property *prop;
> +       const struct drm_prop_enum_list enum_list[] = {
> +               { DRM_PLANE_PIXEL_SOURCE_FB, "FB" },
> +               { DRM_PLANE_PIXEL_SOURCE_COLOR, "COLOR" },
> +       };
> +       unsigned int valid_source_mask = BIT(DRM_PLANE_PIXEL_SOURCE_FB) |
> +                                      BIT(DRM_PLANE_PIXEL_SOURCE_COLOR);
> +       int i;
> +
> +       /* FB is supported by default */
> +       supported_sources |= BIT(DRM_PLANE_PIXEL_SOURCE_FB);
> +
> +       if (WARN_ON(supported_sources & ~valid_source_mask))
> +               return -EINVAL;
> +
> +       prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "pixel_source",
> +                       hweight32(supported_sources));
> +
> +       if (!prop)
> +               return -ENOMEM;
> +
> +       for (i = 0; i < ARRAY_SIZE(enum_list); i++) {
> +               int ret;
> +
> +               if (!(BIT(enum_list[i].type) & supported_sources))
> +                       continue;
> +
> +               ret = drm_property_add_enum(prop, enum_list[i].type, enum_list[i].name);
> +
> +               if (ret) {
> +                       drm_property_destroy(dev, prop);
> +
> +                       return ret;
> +               }
> +       }
> +
> +       drm_object_attach_property(&plane->base, prop, DRM_PLANE_PIXEL_SOURCE_FB);
> +       plane->pixel_source_property = prop;
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(drm_plane_create_pixel_source_property);
> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> index 0338a860b9c8..31af7cfa5b1b 100644
> --- a/include/drm/drm_blend.h
> +++ b/include/drm/drm_blend.h
> @@ -59,4 +59,6 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>  int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>                                          unsigned int supported_modes);
>  int drm_plane_create_solid_fill_property(struct drm_plane *plane);
> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
> +                                          unsigned int supported_sources);
>  #endif
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index f6ab313cb83e..73fb6cf8a5d9 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -59,6 +59,12 @@ struct drm_solid_fill {
>         uint32_t b;
>  };
>
> +enum drm_plane_pixel_source {
> +       DRM_PLANE_PIXEL_SOURCE_FB,
> +       DRM_PLANE_PIXEL_SOURCE_COLOR,
> +       DRM_PLANE_PIXEL_SOURCE_MAX
> +};
> +
>  /**
>   * struct drm_plane_state - mutable plane state
>   *
> @@ -152,6 +158,14 @@ struct drm_plane_state {
>          */
>         struct drm_solid_fill solid_fill;
>
> +       /*
> +        * @pixel_source:
> +        *
> +        * Source of pixel information for the plane. See
> +        * drm_plane_create_pixel_source_property() for more details.
> +        */
> +       enum drm_plane_pixel_source pixel_source;
> +
>         /**
>          * @alpha:
>          * Opacity of the plane with 0 as completely transparent and 0xffff as
> @@ -742,6 +756,13 @@ struct drm_plane {
>          */
>         struct drm_property *solid_fill_property;
>
> +       /*
> +        * @pixel_source_property:
> +        * Optional pixel_source property for this plane. See
> +        * drm_plane_create_pixel_source_property().
> +        */
> +       struct drm_property *pixel_source_property;
> +
>         /**
>          * @alpha_property:
>          * Optional alpha property for this plane. See
>
> --
> 2.41.0
>
  
Jessica Zhang June 30, 2023, 9:27 p.m. UTC | #3
On 6/30/2023 7:43 AM, Sebastian Wick wrote:
> On Fri, Jun 30, 2023 at 2:26 AM Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>>
>> Add support for pixel_source property to drm_plane and related
>> documentation.
>>
>> This enum property will allow user to specify a pixel source for the
>> plane. Possible pixel sources will be defined in the
>> drm_plane_pixel_source enum.
>>
>> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
>> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
>>   drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
>>   drivers/gpu/drm/drm_blend.c               | 81 +++++++++++++++++++++++++++++++
>>   include/drm/drm_blend.h                   |  2 +
>>   include/drm/drm_plane.h                   | 21 ++++++++
>>   5 files changed, 109 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
>> index fe14be2bd2b2..86fb876efbe6 100644
>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>> @@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
>>
>>          plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>>          plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
>> +       plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
>>
>>          if (plane_state->solid_fill_blob) {
>>                  drm_property_blob_put(plane_state->solid_fill_blob);
>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
>> index a28b4ee79444..6e59c21af66b 100644
>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>> @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
>>                  drm_property_blob_put(solid_fill);
>>
>>                  return ret;
>> +       } else if (property == plane->pixel_source_property) {
>> +               state->pixel_source = val;
>>          } else if (property == plane->alpha_property) {
>>                  state->alpha = val;
>>          } else if (property == plane->blend_mode_property) {
>> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>>          } else if (property == plane->solid_fill_property) {
>>                  *val = state->solid_fill_blob ?
>>                          state->solid_fill_blob->base.id : 0;
>> +       } else if (property == plane->pixel_source_property) {
>> +               *val = state->pixel_source;
>>          } else if (property == plane->alpha_property) {
>>                  *val = state->alpha;
>>          } else if (property == plane->blend_mode_property) {
>> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
>> index 38c3c5d6453a..8c100a957ee2 100644
>> --- a/drivers/gpu/drm/drm_blend.c
>> +++ b/drivers/gpu/drm/drm_blend.c
>> @@ -189,6 +189,18 @@
>>    *     solid_fill is set up with drm_plane_create_solid_fill_property(). It
>>    *     contains pixel data that drivers can use to fill a plane.
>>    *
>> + * pixel_source:
>> + *     pixel_source is set up with drm_plane_create_pixel_source_property().
>> + *     It is used to toggle the source of pixel data for the plane.
>> + *
>> + *     Possible values:
>> + *
>> + *     "FB":
>> + *             Framebuffer source
>> + *
>> + *     "COLOR":
>> + *             solid_fill source
>> + *
>>    * 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).
>> @@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct drm_plane *plane)
>>          return 0;
>>   }
>>   EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
>> +
>> +/**
>> + * drm_plane_create_pixel_source_property - create a new pixel source property
>> + * @plane: drm plane
>> + * @supported_sources: bitmask of supported pixel_sources for the driver (NOT
>> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it will be supported
>> + *                     by default).
>> + *
>> + * This creates a new property describing the current source of pixel data for the
>> + * plane.
>> + *
>> + * The property is exposed to userspace as an enumeration property called
>> + * "pixel_source" and has the following enumeration values:
>> + *
>> + * "FB":
>> + *     Framebuffer pixel source
>> + *
>> + * "COLOR":
>> + *     Solid fill color pixel source
> 
> Can we add a "NONE" value?
> 
> I know it has been discussed earlier if we *need*  this and I don't
> think we do. I just think it would be better API design to disable
> planes this way than having to know that a framebuffer pixel source
> with a NULL framebuffer disables the plane. Obviously also keep the
> old behavior for backwards compatibility.

Hi Sebastian,

Sounds good.

So if pixel_source == NONE disables the planes, would that mean cases 
where pixel_source == COLOR && solid_fill_blob == NULL, the atomic 
commit should throw an error?

Thanks,

Jessica Zhang

> 
>> + *
>> + * Returns:
>> + * Zero on success, negative errno on failure.
>> + */
>> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
>> +                                          unsigned int supported_sources)
>> +{
>> +       struct drm_device *dev = plane->dev;
>> +       struct drm_property *prop;
>> +       const struct drm_prop_enum_list enum_list[] = {
>> +               { DRM_PLANE_PIXEL_SOURCE_FB, "FB" },
>> +               { DRM_PLANE_PIXEL_SOURCE_COLOR, "COLOR" },
>> +       };
>> +       unsigned int valid_source_mask = BIT(DRM_PLANE_PIXEL_SOURCE_FB) |
>> +                                      BIT(DRM_PLANE_PIXEL_SOURCE_COLOR);
>> +       int i;
>> +
>> +       /* FB is supported by default */
>> +       supported_sources |= BIT(DRM_PLANE_PIXEL_SOURCE_FB);
>> +
>> +       if (WARN_ON(supported_sources & ~valid_source_mask))
>> +               return -EINVAL;
>> +
>> +       prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "pixel_source",
>> +                       hweight32(supported_sources));
>> +
>> +       if (!prop)
>> +               return -ENOMEM;
>> +
>> +       for (i = 0; i < ARRAY_SIZE(enum_list); i++) {
>> +               int ret;
>> +
>> +               if (!(BIT(enum_list[i].type) & supported_sources))
>> +                       continue;
>> +
>> +               ret = drm_property_add_enum(prop, enum_list[i].type, enum_list[i].name);
>> +
>> +               if (ret) {
>> +                       drm_property_destroy(dev, prop);
>> +
>> +                       return ret;
>> +               }
>> +       }
>> +
>> +       drm_object_attach_property(&plane->base, prop, DRM_PLANE_PIXEL_SOURCE_FB);
>> +       plane->pixel_source_property = prop;
>> +
>> +       return 0;
>> +}
>> +EXPORT_SYMBOL(drm_plane_create_pixel_source_property);
>> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
>> index 0338a860b9c8..31af7cfa5b1b 100644
>> --- a/include/drm/drm_blend.h
>> +++ b/include/drm/drm_blend.h
>> @@ -59,4 +59,6 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>>   int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>>                                           unsigned int supported_modes);
>>   int drm_plane_create_solid_fill_property(struct drm_plane *plane);
>> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
>> +                                          unsigned int supported_sources);
>>   #endif
>> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
>> index f6ab313cb83e..73fb6cf8a5d9 100644
>> --- a/include/drm/drm_plane.h
>> +++ b/include/drm/drm_plane.h
>> @@ -59,6 +59,12 @@ struct drm_solid_fill {
>>          uint32_t b;
>>   };
>>
>> +enum drm_plane_pixel_source {
>> +       DRM_PLANE_PIXEL_SOURCE_FB,
>> +       DRM_PLANE_PIXEL_SOURCE_COLOR,
>> +       DRM_PLANE_PIXEL_SOURCE_MAX
>> +};
>> +
>>   /**
>>    * struct drm_plane_state - mutable plane state
>>    *
>> @@ -152,6 +158,14 @@ struct drm_plane_state {
>>           */
>>          struct drm_solid_fill solid_fill;
>>
>> +       /*
>> +        * @pixel_source:
>> +        *
>> +        * Source of pixel information for the plane. See
>> +        * drm_plane_create_pixel_source_property() for more details.
>> +        */
>> +       enum drm_plane_pixel_source pixel_source;
>> +
>>          /**
>>           * @alpha:
>>           * Opacity of the plane with 0 as completely transparent and 0xffff as
>> @@ -742,6 +756,13 @@ struct drm_plane {
>>           */
>>          struct drm_property *solid_fill_property;
>>
>> +       /*
>> +        * @pixel_source_property:
>> +        * Optional pixel_source property for this plane. See
>> +        * drm_plane_create_pixel_source_property().
>> +        */
>> +       struct drm_property *pixel_source_property;
>> +
>>          /**
>>           * @alpha_property:
>>           * Optional alpha property for this plane. See
>>
>> --
>> 2.41.0
>>
>
  
Sebastian Wick July 3, 2023, 11:49 a.m. UTC | #4
On Fri, Jun 30, 2023 at 11:27 PM Jessica Zhang
<quic_jesszhan@quicinc.com> wrote:
>
>
>
> On 6/30/2023 7:43 AM, Sebastian Wick wrote:
> > On Fri, Jun 30, 2023 at 2:26 AM Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> >>
> >> Add support for pixel_source property to drm_plane and related
> >> documentation.
> >>
> >> This enum property will allow user to specify a pixel source for the
> >> plane. Possible pixel sources will be defined in the
> >> drm_plane_pixel_source enum.
> >>
> >> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
> >> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
> >>
> >> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> >> ---
> >>   drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
> >>   drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
> >>   drivers/gpu/drm/drm_blend.c               | 81 +++++++++++++++++++++++++++++++
> >>   include/drm/drm_blend.h                   |  2 +
> >>   include/drm/drm_plane.h                   | 21 ++++++++
> >>   5 files changed, 109 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
> >> index fe14be2bd2b2..86fb876efbe6 100644
> >> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> >> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> >> @@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
> >>
> >>          plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
> >>          plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> >> +       plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
> >>
> >>          if (plane_state->solid_fill_blob) {
> >>                  drm_property_blob_put(plane_state->solid_fill_blob);
> >> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> >> index a28b4ee79444..6e59c21af66b 100644
> >> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> >> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> >> @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
> >>                  drm_property_blob_put(solid_fill);
> >>
> >>                  return ret;
> >> +       } else if (property == plane->pixel_source_property) {
> >> +               state->pixel_source = val;
> >>          } else if (property == plane->alpha_property) {
> >>                  state->alpha = val;
> >>          } else if (property == plane->blend_mode_property) {
> >> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
> >>          } else if (property == plane->solid_fill_property) {
> >>                  *val = state->solid_fill_blob ?
> >>                          state->solid_fill_blob->base.id : 0;
> >> +       } else if (property == plane->pixel_source_property) {
> >> +               *val = state->pixel_source;
> >>          } else if (property == plane->alpha_property) {
> >>                  *val = state->alpha;
> >>          } else if (property == plane->blend_mode_property) {
> >> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> >> index 38c3c5d6453a..8c100a957ee2 100644
> >> --- a/drivers/gpu/drm/drm_blend.c
> >> +++ b/drivers/gpu/drm/drm_blend.c
> >> @@ -189,6 +189,18 @@
> >>    *     solid_fill is set up with drm_plane_create_solid_fill_property(). It
> >>    *     contains pixel data that drivers can use to fill a plane.
> >>    *
> >> + * pixel_source:
> >> + *     pixel_source is set up with drm_plane_create_pixel_source_property().
> >> + *     It is used to toggle the source of pixel data for the plane.
> >> + *
> >> + *     Possible values:
> >> + *
> >> + *     "FB":
> >> + *             Framebuffer source
> >> + *
> >> + *     "COLOR":
> >> + *             solid_fill source
> >> + *
> >>    * 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).
> >> @@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct drm_plane *plane)
> >>          return 0;
> >>   }
> >>   EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
> >> +
> >> +/**
> >> + * drm_plane_create_pixel_source_property - create a new pixel source property
> >> + * @plane: drm plane
> >> + * @supported_sources: bitmask of supported pixel_sources for the driver (NOT
> >> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it will be supported
> >> + *                     by default).
> >> + *
> >> + * This creates a new property describing the current source of pixel data for the
> >> + * plane.
> >> + *
> >> + * The property is exposed to userspace as an enumeration property called
> >> + * "pixel_source" and has the following enumeration values:
> >> + *
> >> + * "FB":
> >> + *     Framebuffer pixel source
> >> + *
> >> + * "COLOR":
> >> + *     Solid fill color pixel source
> >
> > Can we add a "NONE" value?
> >
> > I know it has been discussed earlier if we *need*  this and I don't
> > think we do. I just think it would be better API design to disable
> > planes this way than having to know that a framebuffer pixel source
> > with a NULL framebuffer disables the plane. Obviously also keep the
> > old behavior for backwards compatibility.
>
> Hi Sebastian,
>
> Sounds good.
>
> So if pixel_source == NONE disables the planes, would that mean cases
> where pixel_source == COLOR && solid_fill_blob == NULL, the atomic
> commit should throw an error?

I would say so, yes.

> Thanks,
>
> Jessica Zhang
>
> >
> >> + *
> >> + * Returns:
> >> + * Zero on success, negative errno on failure.
> >> + */
> >> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
> >> +                                          unsigned int supported_sources)
> >> +{
> >> +       struct drm_device *dev = plane->dev;
> >> +       struct drm_property *prop;
> >> +       const struct drm_prop_enum_list enum_list[] = {
> >> +               { DRM_PLANE_PIXEL_SOURCE_FB, "FB" },
> >> +               { DRM_PLANE_PIXEL_SOURCE_COLOR, "COLOR" },
> >> +       };
> >> +       unsigned int valid_source_mask = BIT(DRM_PLANE_PIXEL_SOURCE_FB) |
> >> +                                      BIT(DRM_PLANE_PIXEL_SOURCE_COLOR);
> >> +       int i;
> >> +
> >> +       /* FB is supported by default */
> >> +       supported_sources |= BIT(DRM_PLANE_PIXEL_SOURCE_FB);
> >> +
> >> +       if (WARN_ON(supported_sources & ~valid_source_mask))
> >> +               return -EINVAL;
> >> +
> >> +       prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "pixel_source",
> >> +                       hweight32(supported_sources));
> >> +
> >> +       if (!prop)
> >> +               return -ENOMEM;
> >> +
> >> +       for (i = 0; i < ARRAY_SIZE(enum_list); i++) {
> >> +               int ret;
> >> +
> >> +               if (!(BIT(enum_list[i].type) & supported_sources))
> >> +                       continue;
> >> +
> >> +               ret = drm_property_add_enum(prop, enum_list[i].type, enum_list[i].name);
> >> +
> >> +               if (ret) {
> >> +                       drm_property_destroy(dev, prop);
> >> +
> >> +                       return ret;
> >> +               }
> >> +       }
> >> +
> >> +       drm_object_attach_property(&plane->base, prop, DRM_PLANE_PIXEL_SOURCE_FB);
> >> +       plane->pixel_source_property = prop;
> >> +
> >> +       return 0;
> >> +}
> >> +EXPORT_SYMBOL(drm_plane_create_pixel_source_property);
> >> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> >> index 0338a860b9c8..31af7cfa5b1b 100644
> >> --- a/include/drm/drm_blend.h
> >> +++ b/include/drm/drm_blend.h
> >> @@ -59,4 +59,6 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
> >>   int drm_plane_create_blend_mode_property(struct drm_plane *plane,
> >>                                           unsigned int supported_modes);
> >>   int drm_plane_create_solid_fill_property(struct drm_plane *plane);
> >> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
> >> +                                          unsigned int supported_sources);
> >>   #endif
> >> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> >> index f6ab313cb83e..73fb6cf8a5d9 100644
> >> --- a/include/drm/drm_plane.h
> >> +++ b/include/drm/drm_plane.h
> >> @@ -59,6 +59,12 @@ struct drm_solid_fill {
> >>          uint32_t b;
> >>   };
> >>
> >> +enum drm_plane_pixel_source {
> >> +       DRM_PLANE_PIXEL_SOURCE_FB,
> >> +       DRM_PLANE_PIXEL_SOURCE_COLOR,
> >> +       DRM_PLANE_PIXEL_SOURCE_MAX
> >> +};
> >> +
> >>   /**
> >>    * struct drm_plane_state - mutable plane state
> >>    *
> >> @@ -152,6 +158,14 @@ struct drm_plane_state {
> >>           */
> >>          struct drm_solid_fill solid_fill;
> >>
> >> +       /*
> >> +        * @pixel_source:
> >> +        *
> >> +        * Source of pixel information for the plane. See
> >> +        * drm_plane_create_pixel_source_property() for more details.
> >> +        */
> >> +       enum drm_plane_pixel_source pixel_source;
> >> +
> >>          /**
> >>           * @alpha:
> >>           * Opacity of the plane with 0 as completely transparent and 0xffff as
> >> @@ -742,6 +756,13 @@ struct drm_plane {
> >>           */
> >>          struct drm_property *solid_fill_property;
> >>
> >> +       /*
> >> +        * @pixel_source_property:
> >> +        * Optional pixel_source property for this plane. See
> >> +        * drm_plane_create_pixel_source_property().
> >> +        */
> >> +       struct drm_property *pixel_source_property;
> >> +
> >>          /**
> >>           * @alpha_property:
> >>           * Optional alpha property for this plane. See
> >>
> >> --
> >> 2.41.0
> >>
> >
>
  
Jessica Zhang July 10, 2023, 7:51 p.m. UTC | #5
On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
> On Fri, 30 Jun 2023 03:42:28 +0300
> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
> 
>> On 30/06/2023 03:25, Jessica Zhang wrote:
>>> Add support for pixel_source property to drm_plane and related
>>> documentation.
>>>
>>> This enum property will allow user to specify a pixel source for the
>>> plane. Possible pixel sources will be defined in the
>>> drm_plane_pixel_source enum.
>>>
>>> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
>>> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
>>
>> I think, this should come before the solid fill property addition. First
>> you tell that there is a possibility to define other pixel sources, then
>> additional sources are defined.
> 
> Hi,
> 
> that would be logical indeed.

Hi Dmitry and Pekka,

Sorry for the delay in response, was out of office last week.

Acked.

> 
>>>
>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>> ---
>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
>>>    drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
>>>    drivers/gpu/drm/drm_blend.c               | 81 +++++++++++++++++++++++++++++++
>>>    include/drm/drm_blend.h                   |  2 +
>>>    include/drm/drm_plane.h                   | 21 ++++++++
>>>    5 files changed, 109 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
>>> index fe14be2bd2b2..86fb876efbe6 100644
>>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>>> @@ -252,6 +252,7 @@ void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
>>>    
>>>    	plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>>>    	plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
>>> +	plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
>>>    
>>>    	if (plane_state->solid_fill_blob) {
>>>    		drm_property_blob_put(plane_state->solid_fill_blob);
>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
>>> index a28b4ee79444..6e59c21af66b 100644
>>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>>> @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
>>>    		drm_property_blob_put(solid_fill);
>>>    
>>>    		return ret;
>>> +	} else if (property == plane->pixel_source_property) {
>>> +		state->pixel_source = val;
>>>    	} else if (property == plane->alpha_property) {
>>>    		state->alpha = val;
>>>    	} else if (property == plane->blend_mode_property) {
>>
>> I think, it was pointed out in the discussion that drm_mode_setplane()
>> (a pre-atomic IOCTL to turn the plane on and off) should also reset
>> pixel_source to FB.

I don't remember drm_mode_setplane() being mentioned in the pixel_source 
discussion... can you share where it was mentioned?

I'd prefer to avoid having driver change the pixel_source directly as it 
could cause some unexpected side effects. In general, I would like 
userspace to assign the value of pixel_source without driver doing 
anything "under the hood".

>>
>>> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>>>    	} else if (property == plane->solid_fill_property) {
>>>    		*val = state->solid_fill_blob ?
>>>    			state->solid_fill_blob->base.id : 0;
>>> +	} else if (property == plane->pixel_source_property) {
>>> +		*val = state->pixel_source;
>>>    	} else if (property == plane->alpha_property) {
>>>    		*val = state->alpha;
>>>    	} else if (property == plane->blend_mode_property) {
>>> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
>>> index 38c3c5d6453a..8c100a957ee2 100644
>>> --- a/drivers/gpu/drm/drm_blend.c
>>> +++ b/drivers/gpu/drm/drm_blend.c
>>> @@ -189,6 +189,18 @@
>>>     *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
>>>     *	contains pixel data that drivers can use to fill a plane.
>>>     *
>>> + * pixel_source:
>>> + *	pixel_source is set up with drm_plane_create_pixel_source_property().
>>> + *	It is used to toggle the source of pixel data for the plane.
> 
> Other sources than the selected one are ignored?

Yep, the plane will only display the data from the set pixel_source.

So if pixel_source == FB and solid_fill_blob is non-NULL, 
solid_fill_blob will be ignored and the plane will display the FB that 
is set.

Will add a note about this in the comment docs.

> 
>>> + *
>>> + *	Possible values:
> 
> Wouldn't hurt to explicitly mention here that this is an enum.

Acked.

> 
>>> + *
>>> + *	"FB":
>>> + *		Framebuffer source
>>> + *
>>> + *	"COLOR":
>>> + *		solid_fill source
> 
> I think these two should be more explicit. Framebuffer source is the
> usual source from the property "FB_ID". Solid fill source comes from
> the property "solid_fill".

Acked.

> 
> Why "COLOR" and not, say, "SOLID_FILL"?

Ah, that would make more sense :)

I'll change this to "SOLID_FILL".

> 
>>> + *
>>>     * 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).
>>> @@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct drm_plane *plane)
>>>    	return 0;
>>>    }
>>>    EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
>>> +
>>> +/**
>>> + * drm_plane_create_pixel_source_property - create a new pixel source property
>>> + * @plane: drm plane
>>> + * @supported_sources: bitmask of supported pixel_sources for the driver (NOT
>>> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it will be supported
>>> + *                     by default).
>>
>> I'd say this is too strong. I'd suggest either renaming this to
>> extra_sources (mentioning that FB is enabled for all the planes) or
>> allowing any source bitmask (mentioning that FB should be enabled by the
>> caller, unless there is a good reason not to do so).
> 
> Right. I don't see any problem with having planes of type OVERLAY that
> support only solid_fill and no FB. Planes of type PRIMARY and CURSOR I
> would expect to always support at least FB.
> 
> Atomic userspace is prepared to have an OVERLAY plane fail for any
> arbitrary reason. Legacy userspace probably should not ever see a plane
> that does not support FB.

Got it... If we allow the possibility of FB sources not being supported, 
then should the default pixel_source per plane be decided by the driver too?

I'd forced FB support so that I could set pixel_source to FB in 
__drm_atomic_helper_plane_state_reset(). If we allow more flexibility in 
the default pixel_source value, I guess we can also store a 
default_pixel_source value in the plane_state.

> 
>>> + *
>>> + * This creates a new property describing the current source of pixel data for the
>>> + * plane.
>>> + *
>>> + * The property is exposed to userspace as an enumeration property called
>>> + * "pixel_source" and has the following enumeration values:
>>> + *
>>> + * "FB":
>>> + *	Framebuffer pixel source
>>> + *
>>> + * "COLOR":
>>> + *	Solid fill color pixel source
>>> + *
>>> + * Returns:
>>> + * Zero on success, negative errno on failure.
>>> + */
>>> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
>>> +					   unsigned int supported_sources)
>>> +{
>>> +	struct drm_device *dev = plane->dev;
>>> +	struct drm_property *prop;
>>> +	const struct drm_prop_enum_list enum_list[] = {
>>> +		{ DRM_PLANE_PIXEL_SOURCE_FB, "FB" },
>>> +		{ DRM_PLANE_PIXEL_SOURCE_COLOR, "COLOR" },
>>> +	};
>>> +	unsigned int valid_source_mask = BIT(DRM_PLANE_PIXEL_SOURCE_FB) |
>>> +				       BIT(DRM_PLANE_PIXEL_SOURCE_COLOR);
>>
>>
>> static const?

Acked.

>>
>>> +	int i;
>>> +
>>> +	/* FB is supported by default */
>>> +	supported_sources |= BIT(DRM_PLANE_PIXEL_SOURCE_FB);
>>> +
>>> +	if (WARN_ON(supported_sources & ~valid_source_mask))
>>> +		return -EINVAL;
>>> +
>>> +	prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "pixel_source",
> 
> Shouldn't this be an atomic prop?

Acked.

> 
> 
>>> +			hweight32(supported_sources));
>>> +
>>> +	if (!prop)
>>> +		return -ENOMEM;
>>> +
>>> +	for (i = 0; i < ARRAY_SIZE(enum_list); i++) {
>>> +		int ret;
>>> +
>>> +		if (!(BIT(enum_list[i].type) & supported_sources))
>>
>> test_bit?

Acked.

>>
>>> +			continue;
>>> +
>>> +		ret = drm_property_add_enum(prop, enum_list[i].type, enum_list[i].name);
>>> +
>>
>> No need for an empty line in such cases. Please drop it.

Acked.

>>
>>> +		if (ret) {
>>> +			drm_property_destroy(dev, prop);
>>> +
>>> +			return ret;
>>> +		}
>>> +	}
>>> +
>>> +	drm_object_attach_property(&plane->base, prop, DRM_PLANE_PIXEL_SOURCE_FB);
>>> +	plane->pixel_source_property = prop;
>>> +
>>> +	return 0;
>>> +}
>>> +EXPORT_SYMBOL(drm_plane_create_pixel_source_property);
>>> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
>>> index 0338a860b9c8..31af7cfa5b1b 100644
>>> --- a/include/drm/drm_blend.h
>>> +++ b/include/drm/drm_blend.h
>>> @@ -59,4 +59,6 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>>>    int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>>>    					 unsigned int supported_modes);
>>>    int drm_plane_create_solid_fill_property(struct drm_plane *plane);
>>> +int drm_plane_create_pixel_source_property(struct drm_plane *plane,
>>> +					   unsigned int supported_sources);
>>>    #endif
>>> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
>>> index f6ab313cb83e..73fb6cf8a5d9 100644
>>> --- a/include/drm/drm_plane.h
>>> +++ b/include/drm/drm_plane.h
>>> @@ -59,6 +59,12 @@ struct drm_solid_fill {
>>>    	uint32_t b;
>>>    };
>>>    
>>> +enum drm_plane_pixel_source {
>>> +	DRM_PLANE_PIXEL_SOURCE_FB,
>>> +	DRM_PLANE_PIXEL_SOURCE_COLOR,
>>> +	DRM_PLANE_PIXEL_SOURCE_MAX
>>> +};
> 
> Just to be very clear that I'm not confusing you with my comment about
> UAPI headers in the previous patch, this enum is already in a good
> place. It does not belong in a UAPI header, because userspace
> recognises enum values by the name string.

Got it.

Thanks,

Jessica Zhang

> 
> 
> Thanks,
> pq
> 
>>> +
>>>    /**
>>>     * struct drm_plane_state - mutable plane state
>>>     *
>>> @@ -152,6 +158,14 @@ struct drm_plane_state {
>>>    	 */
>>>    	struct drm_solid_fill solid_fill;
>>>    
>>> +	/*
>>> +	 * @pixel_source:
>>> +	 *
>>> +	 * Source of pixel information for the plane. See
>>> +	 * drm_plane_create_pixel_source_property() for more details.
>>> +	 */
>>> +	enum drm_plane_pixel_source pixel_source;
>>> +
>>>    	/**
>>>    	 * @alpha:
>>>    	 * Opacity of the plane with 0 as completely transparent and 0xffff as
>>> @@ -742,6 +756,13 @@ struct drm_plane {
>>>    	 */
>>>    	struct drm_property *solid_fill_property;
>>>    
>>> +	/*
>>> +	 * @pixel_source_property:
>>> +	 * Optional pixel_source property for this plane. See
>>> +	 * drm_plane_create_pixel_source_property().
>>> +	 */
>>> +	struct drm_property *pixel_source_property;
>>> +
>>>    	/**
>>>    	 * @alpha_property:
>>>    	 * Optional alpha property for this plane. See
>>>    
>>
>
  
Dmitry Baryshkov July 10, 2023, 8:11 p.m. UTC | #6
On 10/07/2023 22:51, Jessica Zhang wrote:
> 
> 
> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
>> On Fri, 30 Jun 2023 03:42:28 +0300
>> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
>>
>>> On 30/06/2023 03:25, Jessica Zhang wrote:
>>>> Add support for pixel_source property to drm_plane and related
>>>> documentation.
>>>>
>>>> This enum property will allow user to specify a pixel source for the
>>>> plane. Possible pixel sources will be defined in the
>>>> drm_plane_pixel_source enum.
>>>>
>>>> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
>>>> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
>>>
>>> I think, this should come before the solid fill property addition. First
>>> you tell that there is a possibility to define other pixel sources, then
>>> additional sources are defined.
>>
>> Hi,
>>
>> that would be logical indeed.
> 
> Hi Dmitry and Pekka,
> 
> Sorry for the delay in response, was out of office last week.
> 
> Acked.
> 
>>
>>>>
>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>> ---
>>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
>>>>    drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
>>>>    drivers/gpu/drm/drm_blend.c               | 81 
>>>> +++++++++++++++++++++++++++++++
>>>>    include/drm/drm_blend.h                   |  2 +
>>>>    include/drm/drm_plane.h                   | 21 ++++++++
>>>>    5 files changed, 109 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
>>>> b/drivers/gpu/drm/drm_atomic_state_helper.c
>>>> index fe14be2bd2b2..86fb876efbe6 100644
>>>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>>>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>>>> @@ -252,6 +252,7 @@ void 
>>>> __drm_atomic_helper_plane_state_reset(struct drm_plane_state 
>>>> *plane_state,
>>>>        plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>>>>        plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
>>>> +    plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
>>>>        if (plane_state->solid_fill_blob) {
>>>>            drm_property_blob_put(plane_state->solid_fill_blob);
>>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
>>>> b/drivers/gpu/drm/drm_atomic_uapi.c
>>>> index a28b4ee79444..6e59c21af66b 100644
>>>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>>>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>>>> @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct 
>>>> drm_plane *plane,
>>>>            drm_property_blob_put(solid_fill);
>>>>            return ret;
>>>> +    } else if (property == plane->pixel_source_property) {
>>>> +        state->pixel_source = val;
>>>>        } else if (property == plane->alpha_property) {
>>>>            state->alpha = val;
>>>>        } else if (property == plane->blend_mode_property) {
>>>
>>> I think, it was pointed out in the discussion that drm_mode_setplane()
>>> (a pre-atomic IOCTL to turn the plane on and off) should also reset
>>> pixel_source to FB.
> 
> I don't remember drm_mode_setplane() being mentioned in the pixel_source 
> discussion... can you share where it was mentioned?

https://lore.kernel.org/dri-devel/20230627105849.004050b3@eldfell/

Let me quote it here:
"Legacy non-atomic UAPI wrappers can do whatever they want, and program
any (new) properties they want in order to implement the legacy
expectations, so that does not seem to be a problem."


> 
> I'd prefer to avoid having driver change the pixel_source directly as it 
> could cause some unexpected side effects. In general, I would like 
> userspace to assign the value of pixel_source without driver doing 
> anything "under the hood".

s/driver/drm core/

We have to remain compatible with old userspace, especially with the 
non-atomic one. If the userspace calls ioctl(DRM_IOCTL_MODE_SETPLANE), 
we have to display the specified FB, no matter what was the value of 
PIXEL_SOURCE before this ioctl.


> 
>>>
>>>> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane 
>>>> *plane,
>>>>        } else if (property == plane->solid_fill_property) {
>>>>            *val = state->solid_fill_blob ?
>>>>                state->solid_fill_blob->base.id : 0;
>>>> +    } else if (property == plane->pixel_source_property) {
>>>> +        *val = state->pixel_source;
>>>>        } else if (property == plane->alpha_property) {
>>>>            *val = state->alpha;
>>>>        } else if (property == plane->blend_mode_property) {
>>>> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
>>>> index 38c3c5d6453a..8c100a957ee2 100644
>>>> --- a/drivers/gpu/drm/drm_blend.c
>>>> +++ b/drivers/gpu/drm/drm_blend.c
>>>> @@ -189,6 +189,18 @@
>>>>     *    solid_fill is set up with 
>>>> drm_plane_create_solid_fill_property(). It
>>>>     *    contains pixel data that drivers can use to fill a plane.
>>>>     *
>>>> + * pixel_source:
>>>> + *    pixel_source is set up with 
>>>> drm_plane_create_pixel_source_property().
>>>> + *    It is used to toggle the source of pixel data for the plane.
>>
>> Other sources than the selected one are ignored?
> 
> Yep, the plane will only display the data from the set pixel_source.
> 
> So if pixel_source == FB and solid_fill_blob is non-NULL, 
> solid_fill_blob will be ignored and the plane will display the FB that 
> is set.

correct.

> 
> Will add a note about this in the comment docs.
> 
>>
>>>> + *
>>>> + *    Possible values:
>>
>> Wouldn't hurt to explicitly mention here that this is an enum.
> 
> Acked.
> 
>>
>>>> + *
>>>> + *    "FB":
>>>> + *        Framebuffer source
>>>> + *
>>>> + *    "COLOR":
>>>> + *        solid_fill source
>>
>> I think these two should be more explicit. Framebuffer source is the
>> usual source from the property "FB_ID". Solid fill source comes from
>> the property "solid_fill".
> 
> Acked.
> 
>>
>> Why "COLOR" and not, say, "SOLID_FILL"?
> 
> Ah, that would make more sense :)
> 
> I'll change this to "SOLID_FILL".
> 
>>
>>>> + *
>>>>     * 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).
>>>> @@ -648,3 +660,72 @@ int drm_plane_create_solid_fill_property(struct 
>>>> drm_plane *plane)
>>>>        return 0;
>>>>    }
>>>>    EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
>>>> +
>>>> +/**
>>>> + * drm_plane_create_pixel_source_property - create a new pixel 
>>>> source property
>>>> + * @plane: drm plane
>>>> + * @supported_sources: bitmask of supported pixel_sources for the 
>>>> driver (NOT
>>>> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it 
>>>> will be supported
>>>> + *                     by default).
>>>
>>> I'd say this is too strong. I'd suggest either renaming this to
>>> extra_sources (mentioning that FB is enabled for all the planes) or
>>> allowing any source bitmask (mentioning that FB should be enabled by the
>>> caller, unless there is a good reason not to do so).
>>
>> Right. I don't see any problem with having planes of type OVERLAY that
>> support only solid_fill and no FB. Planes of type PRIMARY and CURSOR I
>> would expect to always support at least FB.
>>
>> Atomic userspace is prepared to have an OVERLAY plane fail for any
>> arbitrary reason. Legacy userspace probably should not ever see a plane
>> that does not support FB.
> 
> Got it... If we allow the possibility of FB sources not being supported, 
> then should the default pixel_source per plane be decided by the driver 
> too?
> 
> I'd forced FB support so that I could set pixel_source to FB in 
> __drm_atomic_helper_plane_state_reset(). If we allow more flexibility in 
> the default pixel_source value, I guess we can also store a 
> default_pixel_source value in the plane_state.

I'd say, the FB is a sane default. It the driver has other needs, it can 
override the value in drm_plane_funcs::reset().

> 

[skipped the rest]
  
Jessica Zhang July 11, 2023, 10:07 p.m. UTC | #7
On 7/10/2023 1:11 PM, Dmitry Baryshkov wrote:
> On 10/07/2023 22:51, Jessica Zhang wrote:
>>
>>
>> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
>>> On Fri, 30 Jun 2023 03:42:28 +0300
>>> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
>>>
>>>> On 30/06/2023 03:25, Jessica Zhang wrote:
>>>>> Add support for pixel_source property to drm_plane and related
>>>>> documentation.
>>>>>
>>>>> This enum property will allow user to specify a pixel source for the
>>>>> plane. Possible pixel sources will be defined in the
>>>>> drm_plane_pixel_source enum.
>>>>>
>>>>> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
>>>>> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
>>>>
>>>> I think, this should come before the solid fill property addition. 
>>>> First
>>>> you tell that there is a possibility to define other pixel sources, 
>>>> then
>>>> additional sources are defined.
>>>
>>> Hi,
>>>
>>> that would be logical indeed.
>>
>> Hi Dmitry and Pekka,
>>
>> Sorry for the delay in response, was out of office last week.
>>
>> Acked.
>>
>>>
>>>>>
>>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>>> ---
>>>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
>>>>>    drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
>>>>>    drivers/gpu/drm/drm_blend.c               | 81 
>>>>> +++++++++++++++++++++++++++++++
>>>>>    include/drm/drm_blend.h                  |  2 +
>>>>>    include/drm/drm_plane.h                  | 21 ++++++++
>>>>>    5 files changed, 109 insertions(+)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
>>>>> b/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>> index fe14be2bd2b2..86fb876efbe6 100644
>>>>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>> @@ -252,6 +252,7 @@ void 
>>>>> __drm_atomic_helper_plane_state_reset(struct drm_plane_state 
>>>>> *plane_state,
>>>>>        plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>>>>>        plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
>>>>> +    plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
>>>>>        if (plane_state->solid_fill_blob) {
>>>>>            drm_property_blob_put(plane_state->solid_fill_blob);
>>>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
>>>>> b/drivers/gpu/drm/drm_atomic_uapi.c
>>>>> index a28b4ee79444..6e59c21af66b 100644
>>>>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>>>>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>>>>> @@ -596,6 +596,8 @@ static int drm_atomic_plane_set_property(struct 
>>>>> drm_plane *plane,
>>>>>            drm_property_blob_put(solid_fill);
>>>>>            return ret;
>>>>> +    } else if (property == plane->pixel_source_property) {
>>>>> +        state->pixel_source = val;
>>>>>        } else if (property == plane->alpha_property) {
>>>>>            state->alpha = val;
>>>>>        } else if (property == plane->blend_mode_property) {
>>>>
>>>> I think, it was pointed out in the discussion that drm_mode_setplane()
>>>> (a pre-atomic IOCTL to turn the plane on and off) should also reset
>>>> pixel_source to FB.
>>
>> I don't remember drm_mode_setplane() being mentioned in the 
>> pixel_source discussion... can you share where it was mentioned?
> 
> https://lore.kernel.org/dri-devel/20230627105849.004050b3@eldfell/
> 
> Let me quote it here:
> "Legacy non-atomic UAPI wrappers can do whatever they want, and program
> any (new) properties they want in order to implement the legacy
> expectations, so that does not seem to be a problem."
> 
> 
>>
>> I'd prefer to avoid having driver change the pixel_source directly as 
>> it could cause some unexpected side effects. In general, I would like 
>> userspace to assign the value of pixel_source without driver doing 
>> anything "under the hood".
> 
> s/driver/drm core/
> 
> We have to remain compatible with old userspace, especially with the 
> non-atomic one. If the userspace calls ioctl(DRM_IOCTL_MODE_SETPLANE), 
> we have to display the specified FB, no matter what was the value of 
> PIXEL_SOURCE before this ioctl.


Got it, thanks the clarification -- I see your point.

I'm already setting plane_state->pixel_source to FB in 
__drm_atomic_helper_plane_reset() and it seems to me that all drivers 
are calling that within their respective plane_funcs->reset().

Since (as far as I know) reset() is being called for both the atomic and 
non-atomic paths, shouldn't that be enough to default pixel_source to FB 
for old userspace?

Thanks,

Jessica Zhang

> 
> 
>>
>>>>
>>>>> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane 
>>>>> *plane,
>>>>>        } else if (property == plane->solid_fill_property) {
>>>>>            *val =state->solid_fill_blob ?
>>>>>                state->solid_fill_blob->base.id : 0;
>>>>> +    } else if (property == plane->pixel_source_property) {
>>>>> +        *val = state->pixel_source;
>>>>>        } else if (property == plane->alpha_property) {
>>>>>            *val =state->alpha;
>>>>>        } else if (property == plane->blend_mode_property) {
>>>>> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
>>>>> index 38c3c5d6453a..8c100a957ee2 100644
>>>>> --- a/drivers/gpu/drm/drm_blend.c
>>>>> +++ b/drivers/gpu/drm/drm_blend.c
>>>>> @@ -189,6 +189,18 @@
>>>>>     *    solid_fill is set up with 
>>>>> drm_plane_create_solid_fill_property(). It
>>>>>     *    contains pixel data that drivers can use to fill a plane.
>>>>>     *
>>>>> + * pixel_source:
>>>>> + *    pixel_source is set up with 
>>>>> drm_plane_create_pixel_source_property().
>>>>> + *    It is used to toggle the source of pixel data for the plane.
>>>
>>> Other sources than the selected one are ignored?
>>
>> Yep, the plane will only display the data from the set pixel_source.
>>
>> So if pixel_source == FB and solid_fill_blob is non-NULL, 
>> solid_fill_blob will be ignored and the plane will display the FB that 
>> is set.
> 
> correct.
> 
>>
>> Will add a note about this in the comment docs.
>>
>>>
>>>>> + *
>>>>> + *    Possible values:
>>>
>>> Wouldn't hurt to explicitly mention here that this is an enum.
>>
>> Acked.
>>
>>>
>>>>> + *
>>>>> + *    "FB":
>>>>> + *        Framebuffer source
>>>>> + *
>>>>> + *    "COLOR":
>>>>> + *        solid_fill source
>>>
>>> I think these two should be more explicit. Framebuffer source is the
>>> usual source from the property "FB_ID". Solid fill source comes from
>>> the property "solid_fill".
>>
>> Acked.
>>
>>>
>>> Why "COLOR" and not, say, "SOLID_FILL"?
>>
>> Ah, that would make more sense :)
>>
>> I'll change this to "SOLID_FILL".
>>
>>>
>>>>> + *
>>>>>     * 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).
>>>>> @@ -648,3 +660,72 @@ int 
>>>>> drm_plane_create_solid_fill_property(struct drm_plane *plane)
>>>>>        return 0;
>>>>>    }
>>>>>    EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
>>>>> +
>>>>> +/**
>>>>> + * drm_plane_create_pixel_source_property - create a new pixel 
>>>>> source property
>>>>> + * @plane: drm plane
>>>>> + * @supported_sources: bitmask of supported pixel_sources for the 
>>>>> driver (NOT
>>>>> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it 
>>>>> will be supported
>>>>> + *                     by default).
>>>>
>>>> I'd say this is too strong. I'd suggest either renaming this to
>>>> extra_sources (mentioning that FB is enabled for all the planes) or
>>>> allowing any source bitmask (mentioning that FB should be enabled by 
>>>> the
>>>> caller, unless there is a good reason not to do so).
>>>
>>> Right. I don't see any problem with having planes of type OVERLAY that
>>> support only solid_fill and no FB. Planes of type PRIMARY and CURSOR I
>>> would expect to always support at least FB.
>>>
>>> Atomic userspace is prepared to have an OVERLAY plane fail for any
>>> arbitrary reason. Legacy userspace probably should not ever see a plane
>>> that does not support FB.
>>
>> Got it... If we allow the possibility of FB sources not being 
>> supported, then should the default pixel_source per plane be decided 
>> by the driver too?
>>
>> I'd forced FB support so that I could set pixel_source to FB in 
>> __drm_atomic_helper_plane_state_reset(). If we allow more flexibility 
>> in the default pixel_source value, I guess we can also store a 
>> default_pixel_source value in the plane_state.
> 
> I'd say, the FB is a sane default. It the driver has other needs, it can 
> override the value in drm_plane_funcs::reset().
> 
>>
> 
> [skipped the rest]
> 
> -- 
> With best wishes
> Dmitry
>
  
Dmitry Baryshkov July 11, 2023, 10:19 p.m. UTC | #8
On 12/07/2023 01:07, Jessica Zhang wrote:
> 
> 
> On 7/10/2023 1:11 PM, Dmitry Baryshkov wrote:
>> On 10/07/2023 22:51, Jessica Zhang wrote:
>>>
>>>
>>> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
>>>> On Fri, 30 Jun 2023 03:42:28 +0300
>>>> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
>>>>
>>>>> On 30/06/2023 03:25, Jessica Zhang wrote:
>>>>>> Add support for pixel_source property to drm_plane and related
>>>>>> documentation.
>>>>>>
>>>>>> This enum property will allow user to specify a pixel source for the
>>>>>> plane. Possible pixel sources will be defined in the
>>>>>> drm_plane_pixel_source enum.
>>>>>>
>>>>>> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
>>>>>> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
>>>>>
>>>>> I think, this should come before the solid fill property addition. 
>>>>> First
>>>>> you tell that there is a possibility to define other pixel sources, 
>>>>> then
>>>>> additional sources are defined.
>>>>
>>>> Hi,
>>>>
>>>> that would be logical indeed.
>>>
>>> Hi Dmitry and Pekka,
>>>
>>> Sorry for the delay in response, was out of office last week.
>>>
>>> Acked.
>>>
>>>>
>>>>>>
>>>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>>>> ---
>>>>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
>>>>>>    drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
>>>>>>    drivers/gpu/drm/drm_blend.c               | 81 
>>>>>> +++++++++++++++++++++++++++++++
>>>>>>    include/drm/drm_blend.h                  |  2 +
>>>>>>    include/drm/drm_plane.h                  | 21 ++++++++
>>>>>>    5 files changed, 109 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
>>>>>> b/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>>> index fe14be2bd2b2..86fb876efbe6 100644
>>>>>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>>> @@ -252,6 +252,7 @@ void 
>>>>>> __drm_atomic_helper_plane_state_reset(struct drm_plane_state 
>>>>>> *plane_state,
>>>>>>        plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>>>>>>        plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
>>>>>> +    plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
>>>>>>        if (plane_state->solid_fill_blob) {
>>>>>>            drm_property_blob_put(plane_state->solid_fill_blob);
>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
>>>>>> b/drivers/gpu/drm/drm_atomic_uapi.c
>>>>>> index a28b4ee79444..6e59c21af66b 100644
>>>>>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>>>>>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>>>>>> @@ -596,6 +596,8 @@ static int 
>>>>>> drm_atomic_plane_set_property(struct drm_plane *plane,
>>>>>>            drm_property_blob_put(solid_fill);
>>>>>>            return ret;
>>>>>> +    } else if (property == plane->pixel_source_property) {
>>>>>> +        state->pixel_source = val;
>>>>>>        } else if (property == plane->alpha_property) {
>>>>>>            state->alpha = val;
>>>>>>        } else if (property == plane->blend_mode_property) {
>>>>>
>>>>> I think, it was pointed out in the discussion that drm_mode_setplane()
>>>>> (a pre-atomic IOCTL to turn the plane on and off) should also reset
>>>>> pixel_source to FB.
>>>
>>> I don't remember drm_mode_setplane() being mentioned in the 
>>> pixel_source discussion... can you share where it was mentioned?
>>
>> https://lore.kernel.org/dri-devel/20230627105849.004050b3@eldfell/
>>
>> Let me quote it here:
>> "Legacy non-atomic UAPI wrappers can do whatever they want, and program
>> any (new) properties they want in order to implement the legacy
>> expectations, so that does not seem to be a problem."
>>
>>
>>>
>>> I'd prefer to avoid having driver change the pixel_source directly as 
>>> it could cause some unexpected side effects. In general, I would like 
>>> userspace to assign the value of pixel_source without driver doing 
>>> anything "under the hood".
>>
>> s/driver/drm core/
>>
>> We have to remain compatible with old userspace, especially with the 
>> non-atomic one. If the userspace calls ioctl(DRM_IOCTL_MODE_SETPLANE), 
>> we have to display the specified FB, no matter what was the value of 
>> PIXEL_SOURCE before this ioctl.
> 
> 
> Got it, thanks the clarification -- I see your point.
> 
> I'm already setting plane_state->pixel_source to FB in 
> __drm_atomic_helper_plane_reset() and it seems to me that all drivers 
> are calling that within their respective plane_funcs->reset().
> 
> Since (as far as I know) reset() is being called for both the atomic and 
> non-atomic paths, shouldn't that be enough to default pixel_source to FB 
> for old userspace?

No, this will not clean up the state between userspace apps. Currently 
the rule is simple: call DRM_IOCTL_MODE_SETPLANE, get the image from FB 
displayed. We should keep it so.

>>>
>>>>>
>>>>>> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct drm_plane 
>>>>>> *plane,
>>>>>>        } else if (property == plane->solid_fill_property) {
>>>>>>            *val =state->solid_fill_blob ?
>>>>>>                state->solid_fill_blob->base.id : 0;
>>>>>> +    } else if (property == plane->pixel_source_property) {
>>>>>> +        *val = state->pixel_source;
>>>>>>        } else if (property == plane->alpha_property) {
>>>>>>            *val =state->alpha;
>>>>>>        } else if (property == plane->blend_mode_property) {
>>>>>> diff --git a/drivers/gpu/drm/drm_blend.c 
>>>>>> b/drivers/gpu/drm/drm_blend.c
>>>>>> index 38c3c5d6453a..8c100a957ee2 100644
>>>>>> --- a/drivers/gpu/drm/drm_blend.c
>>>>>> +++ b/drivers/gpu/drm/drm_blend.c
>>>>>> @@ -189,6 +189,18 @@
>>>>>>     *    solid_fill is set up with 
>>>>>> drm_plane_create_solid_fill_property(). It
>>>>>>     *    contains pixel data that drivers can use to fill a plane.
>>>>>>     *
>>>>>> + * pixel_source:
>>>>>> + *    pixel_source is set up with 
>>>>>> drm_plane_create_pixel_source_property().
>>>>>> + *    It is used to toggle the source of pixel data for the plane.
>>>>
>>>> Other sources than the selected one are ignored?
>>>
>>> Yep, the plane will only display the data from the set pixel_source.
>>>
>>> So if pixel_source == FB and solid_fill_blob is non-NULL, 
>>> solid_fill_blob will be ignored and the plane will display the FB 
>>> that is set.
>>
>> correct.
>>
>>>
>>> Will add a note about this in the comment docs.
>>>
>>>>
>>>>>> + *
>>>>>> + *    Possible values:
>>>>
>>>> Wouldn't hurt to explicitly mention here that this is an enum.
>>>
>>> Acked.
>>>
>>>>
>>>>>> + *
>>>>>> + *    "FB":
>>>>>> + *        Framebuffer source
>>>>>> + *
>>>>>> + *    "COLOR":
>>>>>> + *        solid_fill source
>>>>
>>>> I think these two should be more explicit. Framebuffer source is the
>>>> usual source from the property "FB_ID". Solid fill source comes from
>>>> the property "solid_fill".
>>>
>>> Acked.
>>>
>>>>
>>>> Why "COLOR" and not, say, "SOLID_FILL"?
>>>
>>> Ah, that would make more sense :)
>>>
>>> I'll change this to "SOLID_FILL".
>>>
>>>>
>>>>>> + *
>>>>>>     * 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).
>>>>>> @@ -648,3 +660,72 @@ int 
>>>>>> drm_plane_create_solid_fill_property(struct drm_plane *plane)
>>>>>>        return 0;
>>>>>>    }
>>>>>>    EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
>>>>>> +
>>>>>> +/**
>>>>>> + * drm_plane_create_pixel_source_property - create a new pixel 
>>>>>> source property
>>>>>> + * @plane: drm plane
>>>>>> + * @supported_sources: bitmask of supported pixel_sources for the 
>>>>>> driver (NOT
>>>>>> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it 
>>>>>> will be supported
>>>>>> + *                     by default).
>>>>>
>>>>> I'd say this is too strong. I'd suggest either renaming this to
>>>>> extra_sources (mentioning that FB is enabled for all the planes) or
>>>>> allowing any source bitmask (mentioning that FB should be enabled 
>>>>> by the
>>>>> caller, unless there is a good reason not to do so).
>>>>
>>>> Right. I don't see any problem with having planes of type OVERLAY that
>>>> support only solid_fill and no FB. Planes of type PRIMARY and CURSOR I
>>>> would expect to always support at least FB.
>>>>
>>>> Atomic userspace is prepared to have an OVERLAY plane fail for any
>>>> arbitrary reason. Legacy userspace probably should not ever see a plane
>>>> that does not support FB.
>>>
>>> Got it... If we allow the possibility of FB sources not being 
>>> supported, then should the default pixel_source per plane be decided 
>>> by the driver too?
>>>
>>> I'd forced FB support so that I could set pixel_source to FB in 
>>> __drm_atomic_helper_plane_state_reset(). If we allow more flexibility 
>>> in the default pixel_source value, I guess we can also store a 
>>> default_pixel_source value in the plane_state.
>>
>> I'd say, the FB is a sane default. It the driver has other needs, it 
>> can override the value in drm_plane_funcs::reset().
>>
>>>
>>
>> [skipped the rest]
>>
>> -- 
>> With best wishes
>> Dmitry
>>
  
Abhinav Kumar July 11, 2023, 10:42 p.m. UTC | #9
On 7/11/2023 3:19 PM, Dmitry Baryshkov wrote:
> On 12/07/2023 01:07, Jessica Zhang wrote:
>>
>>
>> On 7/10/2023 1:11 PM, Dmitry Baryshkov wrote:
>>> On 10/07/2023 22:51, Jessica Zhang wrote:
>>>>
>>>>
>>>> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
>>>>> On Fri, 30 Jun 2023 03:42:28 +0300
>>>>> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
>>>>>
>>>>>> On 30/06/2023 03:25, Jessica Zhang wrote:
>>>>>>> Add support for pixel_source property to drm_plane and related
>>>>>>> documentation.
>>>>>>>
>>>>>>> This enum property will allow user to specify a pixel source for the
>>>>>>> plane. Possible pixel sources will be defined in the
>>>>>>> drm_plane_pixel_source enum.
>>>>>>>
>>>>>>> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
>>>>>>> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
>>>>>>
>>>>>> I think, this should come before the solid fill property addition. 
>>>>>> First
>>>>>> you tell that there is a possibility to define other pixel 
>>>>>> sources, then
>>>>>> additional sources are defined.
>>>>>
>>>>> Hi,
>>>>>
>>>>> that would be logical indeed.
>>>>
>>>> Hi Dmitry and Pekka,
>>>>
>>>> Sorry for the delay in response, was out of office last week.
>>>>
>>>> Acked.
>>>>
>>>>>
>>>>>>>
>>>>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>>>>> ---
>>>>>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
>>>>>>>    drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
>>>>>>>    drivers/gpu/drm/drm_blend.c               | 81 
>>>>>>> +++++++++++++++++++++++++++++++
>>>>>>>    include/drm/drm_blend.h                  |  2 +
>>>>>>>    include/drm/drm_plane.h                  | 21 ++++++++
>>>>>>>    5 files changed, 109 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
>>>>>>> b/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>>>> index fe14be2bd2b2..86fb876efbe6 100644
>>>>>>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>>>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>>>>>>> @@ -252,6 +252,7 @@ void 
>>>>>>> __drm_atomic_helper_plane_state_reset(struct drm_plane_state 
>>>>>>> *plane_state,
>>>>>>>        plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
>>>>>>>        plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
>>>>>>> +    plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
>>>>>>>        if (plane_state->solid_fill_blob) {
>>>>>>>            drm_property_blob_put(plane_state->solid_fill_blob);
>>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
>>>>>>> b/drivers/gpu/drm/drm_atomic_uapi.c
>>>>>>> index a28b4ee79444..6e59c21af66b 100644
>>>>>>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>>>>>>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>>>>>>> @@ -596,6 +596,8 @@ static int 
>>>>>>> drm_atomic_plane_set_property(struct drm_plane *plane,
>>>>>>>            drm_property_blob_put(solid_fill);
>>>>>>>            return ret;
>>>>>>> +    } else if (property == plane->pixel_source_property) {
>>>>>>> +        state->pixel_source = val;
>>>>>>>        } else if (property == plane->alpha_property) {
>>>>>>>            state->alpha = val;
>>>>>>>        } else if (property == plane->blend_mode_property) {
>>>>>>
>>>>>> I think, it was pointed out in the discussion that 
>>>>>> drm_mode_setplane()
>>>>>> (a pre-atomic IOCTL to turn the plane on and off) should also reset
>>>>>> pixel_source to FB.
>>>>
>>>> I don't remember drm_mode_setplane() being mentioned in the 
>>>> pixel_source discussion... can you share where it was mentioned?
>>>
>>> https://lore.kernel.org/dri-devel/20230627105849.004050b3@eldfell/
>>>
>>> Let me quote it here:
>>> "Legacy non-atomic UAPI wrappers can do whatever they want, and program
>>> any (new) properties they want in order to implement the legacy
>>> expectations, so that does not seem to be a problem."
>>>
>>>
>>>>
>>>> I'd prefer to avoid having driver change the pixel_source directly 
>>>> as it could cause some unexpected side effects. In general, I would 
>>>> like userspace to assign the value of pixel_source without driver 
>>>> doing anything "under the hood".
>>>
>>> s/driver/drm core/
>>>
>>> We have to remain compatible with old userspace, especially with the 
>>> non-atomic one. If the userspace calls 
>>> ioctl(DRM_IOCTL_MODE_SETPLANE), we have to display the specified FB, 
>>> no matter what was the value of PIXEL_SOURCE before this ioctl.
>>
>>
>> Got it, thanks the clarification -- I see your point.
>>
>> I'm already setting plane_state->pixel_source to FB in 
>> __drm_atomic_helper_plane_reset() and it seems to me that all drivers 
>> are calling that within their respective plane_funcs->reset().
>>
>> Since (as far as I know) reset() is being called for both the atomic 
>> and non-atomic paths, shouldn't that be enough to default pixel_source 
>> to FB for old userspace?
> 
> No, this will not clean up the state between userspace apps. Currently 
> the rule is simple: call DRM_IOCTL_MODE_SETPLANE, get the image from FB 
> displayed. We should keep it so.
> 

Ok, so you are considering a use-case where we bootup with a userspace 
(which is aware of pixel_source), that one uses the pixel_source to 
switch the property to solid_color and then we kill this userspace and 
bootup one which is unaware of this property and uses 
DRM_IOCTL_MODE_SETPLANE, then we should default back to FB.

>>>>
>>>>>>
>>>>>>> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct 
>>>>>>> drm_plane *plane,
>>>>>>>        } else if (property == plane->solid_fill_property) {
>>>>>>>            *val =state->solid_fill_blob ?
>>>>>>>                state->solid_fill_blob->base.id : 0;
>>>>>>> +    } else if (property == plane->pixel_source_property) {
>>>>>>> +        *val = state->pixel_source;
>>>>>>>        } else if (property == plane->alpha_property) {
>>>>>>>            *val =state->alpha;
>>>>>>>        } else if (property == plane->blend_mode_property) {
>>>>>>> diff --git a/drivers/gpu/drm/drm_blend.c 
>>>>>>> b/drivers/gpu/drm/drm_blend.c
>>>>>>> index 38c3c5d6453a..8c100a957ee2 100644
>>>>>>> --- a/drivers/gpu/drm/drm_blend.c
>>>>>>> +++ b/drivers/gpu/drm/drm_blend.c
>>>>>>> @@ -189,6 +189,18 @@
>>>>>>>     *    solid_fill is set up with 
>>>>>>> drm_plane_create_solid_fill_property(). It
>>>>>>>     *    contains pixel data that drivers can use to fill a plane.
>>>>>>>     *
>>>>>>> + * pixel_source:
>>>>>>> + *    pixel_source is set up with 
>>>>>>> drm_plane_create_pixel_source_property().
>>>>>>> + *    It is used to toggle the source of pixel data for the plane.
>>>>>
>>>>> Other sources than the selected one are ignored?
>>>>
>>>> Yep, the plane will only display the data from the set pixel_source.
>>>>
>>>> So if pixel_source == FB and solid_fill_blob is non-NULL, 
>>>> solid_fill_blob will be ignored and the plane will display the FB 
>>>> that is set.
>>>
>>> correct.
>>>
>>>>
>>>> Will add a note about this in the comment docs.
>>>>
>>>>>
>>>>>>> + *
>>>>>>> + *    Possible values:
>>>>>
>>>>> Wouldn't hurt to explicitly mention here that this is an enum.
>>>>
>>>> Acked.
>>>>
>>>>>
>>>>>>> + *
>>>>>>> + *    "FB":
>>>>>>> + *        Framebuffer source
>>>>>>> + *
>>>>>>> + *    "COLOR":
>>>>>>> + *        solid_fill source
>>>>>
>>>>> I think these two should be more explicit. Framebuffer source is the
>>>>> usual source from the property "FB_ID". Solid fill source comes from
>>>>> the property "solid_fill".
>>>>
>>>> Acked.
>>>>
>>>>>
>>>>> Why "COLOR" and not, say, "SOLID_FILL"?
>>>>
>>>> Ah, that would make more sense :)
>>>>
>>>> I'll change this to "SOLID_FILL".
>>>>
>>>>>
>>>>>>> + *
>>>>>>>     * 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).
>>>>>>> @@ -648,3 +660,72 @@ int 
>>>>>>> drm_plane_create_solid_fill_property(struct drm_plane *plane)
>>>>>>>        return 0;
>>>>>>>    }
>>>>>>>    EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
>>>>>>> +
>>>>>>> +/**
>>>>>>> + * drm_plane_create_pixel_source_property - create a new pixel 
>>>>>>> source property
>>>>>>> + * @plane: drm plane
>>>>>>> + * @supported_sources: bitmask of supported pixel_sources for 
>>>>>>> the driver (NOT
>>>>>>> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as 
>>>>>>> it will be supported
>>>>>>> + *                     by default).
>>>>>>
>>>>>> I'd say this is too strong. I'd suggest either renaming this to
>>>>>> extra_sources (mentioning that FB is enabled for all the planes) or
>>>>>> allowing any source bitmask (mentioning that FB should be enabled 
>>>>>> by the
>>>>>> caller, unless there is a good reason not to do so).
>>>>>
>>>>> Right. I don't see any problem with having planes of type OVERLAY that
>>>>> support only solid_fill and no FB. Planes of type PRIMARY and CURSOR I
>>>>> would expect to always support at least FB.
>>>>>
>>>>> Atomic userspace is prepared to have an OVERLAY plane fail for any
>>>>> arbitrary reason. Legacy userspace probably should not ever see a 
>>>>> plane
>>>>> that does not support FB.
>>>>
>>>> Got it... If we allow the possibility of FB sources not being 
>>>> supported, then should the default pixel_source per plane be decided 
>>>> by the driver too?
>>>>
>>>> I'd forced FB support so that I could set pixel_source to FB in 
>>>> __drm_atomic_helper_plane_state_reset(). If we allow more 
>>>> flexibility in the default pixel_source value, I guess we can also 
>>>> store a default_pixel_source value in the plane_state.
>>>
>>> I'd say, the FB is a sane default. It the driver has other needs, it 
>>> can override the value in drm_plane_funcs::reset().
>>>
>>>>
>>>
>>> [skipped the rest]
>>>
>>> -- 
>>> With best wishes
>>> Dmitry
>>>
>
  
Dmitry Baryshkov July 11, 2023, 11 p.m. UTC | #10
On Wed, 12 Jul 2023 at 01:42, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 7/11/2023 3:19 PM, Dmitry Baryshkov wrote:
> > On 12/07/2023 01:07, Jessica Zhang wrote:
> >>
> >>
> >> On 7/10/2023 1:11 PM, Dmitry Baryshkov wrote:
> >>> On 10/07/2023 22:51, Jessica Zhang wrote:
> >>>>
> >>>>
> >>>> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
> >>>>> On Fri, 30 Jun 2023 03:42:28 +0300
> >>>>> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
> >>>>>
> >>>>>> On 30/06/2023 03:25, Jessica Zhang wrote:
> >>>>>>> Add support for pixel_source property to drm_plane and related
> >>>>>>> documentation.
> >>>>>>>
> >>>>>>> This enum property will allow user to specify a pixel source for the
> >>>>>>> plane. Possible pixel sources will be defined in the
> >>>>>>> drm_plane_pixel_source enum.
> >>>>>>>
> >>>>>>> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
> >>>>>>> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.
> >>>>>>
> >>>>>> I think, this should come before the solid fill property addition.
> >>>>>> First
> >>>>>> you tell that there is a possibility to define other pixel
> >>>>>> sources, then
> >>>>>> additional sources are defined.
> >>>>>
> >>>>> Hi,
> >>>>>
> >>>>> that would be logical indeed.
> >>>>
> >>>> Hi Dmitry and Pekka,
> >>>>
> >>>> Sorry for the delay in response, was out of office last week.
> >>>>
> >>>> Acked.
> >>>>
> >>>>>
> >>>>>>>
> >>>>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> >>>>>>> ---
> >>>>>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
> >>>>>>>    drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
> >>>>>>>    drivers/gpu/drm/drm_blend.c               | 81
> >>>>>>> +++++++++++++++++++++++++++++++
> >>>>>>>    include/drm/drm_blend.h                  |  2 +
> >>>>>>>    include/drm/drm_plane.h                  | 21 ++++++++
> >>>>>>>    5 files changed, 109 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c
> >>>>>>> b/drivers/gpu/drm/drm_atomic_state_helper.c
> >>>>>>> index fe14be2bd2b2..86fb876efbe6 100644
> >>>>>>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> >>>>>>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> >>>>>>> @@ -252,6 +252,7 @@ void
> >>>>>>> __drm_atomic_helper_plane_state_reset(struct drm_plane_state
> >>>>>>> *plane_state,
> >>>>>>>        plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
> >>>>>>>        plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> >>>>>>> +    plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
> >>>>>>>        if (plane_state->solid_fill_blob) {
> >>>>>>>            drm_property_blob_put(plane_state->solid_fill_blob);
> >>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c
> >>>>>>> b/drivers/gpu/drm/drm_atomic_uapi.c
> >>>>>>> index a28b4ee79444..6e59c21af66b 100644
> >>>>>>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> >>>>>>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> >>>>>>> @@ -596,6 +596,8 @@ static int
> >>>>>>> drm_atomic_plane_set_property(struct drm_plane *plane,
> >>>>>>>            drm_property_blob_put(solid_fill);
> >>>>>>>            return ret;
> >>>>>>> +    } else if (property == plane->pixel_source_property) {
> >>>>>>> +        state->pixel_source = val;
> >>>>>>>        } else if (property == plane->alpha_property) {
> >>>>>>>            state->alpha = val;
> >>>>>>>        } else if (property == plane->blend_mode_property) {
> >>>>>>
> >>>>>> I think, it was pointed out in the discussion that
> >>>>>> drm_mode_setplane()
> >>>>>> (a pre-atomic IOCTL to turn the plane on and off) should also reset
> >>>>>> pixel_source to FB.
> >>>>
> >>>> I don't remember drm_mode_setplane() being mentioned in the
> >>>> pixel_source discussion... can you share where it was mentioned?
> >>>
> >>> https://lore.kernel.org/dri-devel/20230627105849.004050b3@eldfell/
> >>>
> >>> Let me quote it here:
> >>> "Legacy non-atomic UAPI wrappers can do whatever they want, and program
> >>> any (new) properties they want in order to implement the legacy
> >>> expectations, so that does not seem to be a problem."
> >>>
> >>>
> >>>>
> >>>> I'd prefer to avoid having driver change the pixel_source directly
> >>>> as it could cause some unexpected side effects. In general, I would
> >>>> like userspace to assign the value of pixel_source without driver
> >>>> doing anything "under the hood".
> >>>
> >>> s/driver/drm core/
> >>>
> >>> We have to remain compatible with old userspace, especially with the
> >>> non-atomic one. If the userspace calls
> >>> ioctl(DRM_IOCTL_MODE_SETPLANE), we have to display the specified FB,
> >>> no matter what was the value of PIXEL_SOURCE before this ioctl.
> >>
> >>
> >> Got it, thanks the clarification -- I see your point.
> >>
> >> I'm already setting plane_state->pixel_source to FB in
> >> __drm_atomic_helper_plane_reset() and it seems to me that all drivers
> >> are calling that within their respective plane_funcs->reset().
> >>
> >> Since (as far as I know) reset() is being called for both the atomic
> >> and non-atomic paths, shouldn't that be enough to default pixel_source
> >> to FB for old userspace?
> >
> > No, this will not clean up the state between userspace apps. Currently
> > the rule is simple: call DRM_IOCTL_MODE_SETPLANE, get the image from FB
> > displayed. We should keep it so.
> >
>
> Ok, so you are considering a use-case where we bootup with a userspace
> (which is aware of pixel_source), that one uses the pixel_source to
> switch the property to solid_color and then we kill this userspace and
> bootup one which is unaware of this property and uses
> DRM_IOCTL_MODE_SETPLANE, then we should default back to FB.

Not necessarily _that_ complex, but yes, that was the idea. We are not
limited to a single composer.

>
> >>>>
> >>>>>>
> >>>>>>> @@ -671,6 +673,8 @@ drm_atomic_plane_get_property(struct
> >>>>>>> drm_plane *plane,
> >>>>>>>        } else if (property == plane->solid_fill_property) {
> >>>>>>>            *val =state->solid_fill_blob ?
> >>>>>>>                state->solid_fill_blob->base.id : 0;
> >>>>>>> +    } else if (property == plane->pixel_source_property) {
> >>>>>>> +        *val = state->pixel_source;
> >>>>>>>        } else if (property == plane->alpha_property) {
> >>>>>>>            *val =state->alpha;
> >>>>>>>        } else if (property == plane->blend_mode_property) {
> >>>>>>> diff --git a/drivers/gpu/drm/drm_blend.c
> >>>>>>> b/drivers/gpu/drm/drm_blend.c
> >>>>>>> index 38c3c5d6453a..8c100a957ee2 100644
> >>>>>>> --- a/drivers/gpu/drm/drm_blend.c
> >>>>>>> +++ b/drivers/gpu/drm/drm_blend.c
> >>>>>>> @@ -189,6 +189,18 @@
> >>>>>>>     *    solid_fill is set up with
> >>>>>>> drm_plane_create_solid_fill_property(). It
> >>>>>>>     *    contains pixel data that drivers can use to fill a plane.
> >>>>>>>     *
> >>>>>>> + * pixel_source:
> >>>>>>> + *    pixel_source is set up with
> >>>>>>> drm_plane_create_pixel_source_property().
> >>>>>>> + *    It is used to toggle the source of pixel data for the plane.
> >>>>>
> >>>>> Other sources than the selected one are ignored?
> >>>>
> >>>> Yep, the plane will only display the data from the set pixel_source.
> >>>>
> >>>> So if pixel_source == FB and solid_fill_blob is non-NULL,
> >>>> solid_fill_blob will be ignored and the plane will display the FB
> >>>> that is set.
> >>>
> >>> correct.
> >>>
> >>>>
> >>>> Will add a note about this in the comment docs.
> >>>>
> >>>>>
> >>>>>>> + *
> >>>>>>> + *    Possible values:
> >>>>>
> >>>>> Wouldn't hurt to explicitly mention here that this is an enum.
> >>>>
> >>>> Acked.
> >>>>
> >>>>>
> >>>>>>> + *
> >>>>>>> + *    "FB":
> >>>>>>> + *        Framebuffer source
> >>>>>>> + *
> >>>>>>> + *    "COLOR":
> >>>>>>> + *        solid_fill source
> >>>>>
> >>>>> I think these two should be more explicit. Framebuffer source is the
> >>>>> usual source from the property "FB_ID". Solid fill source comes from
> >>>>> the property "solid_fill".
> >>>>
> >>>> Acked.
> >>>>
> >>>>>
> >>>>> Why "COLOR" and not, say, "SOLID_FILL"?
> >>>>
> >>>> Ah, that would make more sense :)
> >>>>
> >>>> I'll change this to "SOLID_FILL".
> >>>>
> >>>>>
> >>>>>>> + *
> >>>>>>>     * 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).
> >>>>>>> @@ -648,3 +660,72 @@ int
> >>>>>>> drm_plane_create_solid_fill_property(struct drm_plane *plane)
> >>>>>>>        return 0;
> >>>>>>>    }
> >>>>>>>    EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
> >>>>>>> +
> >>>>>>> +/**
> >>>>>>> + * drm_plane_create_pixel_source_property - create a new pixel
> >>>>>>> source property
> >>>>>>> + * @plane: drm plane
> >>>>>>> + * @supported_sources: bitmask of supported pixel_sources for
> >>>>>>> the driver (NOT
> >>>>>>> + *                     including DRM_PLANE_PIXEL_SOURCE_FB, as
> >>>>>>> it will be supported
> >>>>>>> + *                     by default).
> >>>>>>
> >>>>>> I'd say this is too strong. I'd suggest either renaming this to
> >>>>>> extra_sources (mentioning that FB is enabled for all the planes) or
> >>>>>> allowing any source bitmask (mentioning that FB should be enabled
> >>>>>> by the
> >>>>>> caller, unless there is a good reason not to do so).
> >>>>>
> >>>>> Right. I don't see any problem with having planes of type OVERLAY that
> >>>>> support only solid_fill and no FB. Planes of type PRIMARY and CURSOR I
> >>>>> would expect to always support at least FB.
> >>>>>
> >>>>> Atomic userspace is prepared to have an OVERLAY plane fail for any
> >>>>> arbitrary reason. Legacy userspace probably should not ever see a
> >>>>> plane
> >>>>> that does not support FB.
> >>>>
> >>>> Got it... If we allow the possibility of FB sources not being
> >>>> supported, then should the default pixel_source per plane be decided
> >>>> by the driver too?
> >>>>
> >>>> I'd forced FB support so that I could set pixel_source to FB in
> >>>> __drm_atomic_helper_plane_state_reset(). If we allow more
> >>>> flexibility in the default pixel_source value, I guess we can also
> >>>> store a default_pixel_source value in the plane_state.
> >>>
> >>> I'd say, the FB is a sane default. It the driver has other needs, it
> >>> can override the value in drm_plane_funcs::reset().
> >>>
> >>>>
> >>>
> >>> [skipped the rest]
> >>>
> >>> --
> >>> With best wishes
> >>> Dmitry
> >>>
> >
  
Pekka Paalanen July 12, 2023, 7:35 a.m. UTC | #11
On Tue, 11 Jul 2023 15:42:28 -0700
Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:

> On 7/11/2023 3:19 PM, Dmitry Baryshkov wrote:
> > On 12/07/2023 01:07, Jessica Zhang wrote:  
> >>
> >>
> >> On 7/10/2023 1:11 PM, Dmitry Baryshkov wrote:  
> >>> On 10/07/2023 22:51, Jessica Zhang wrote:  
> >>>>
> >>>>
> >>>> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:  
> >>>>> On Fri, 30 Jun 2023 03:42:28 +0300
> >>>>> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
> >>>>>  
> >>>>>> On 30/06/2023 03:25, Jessica Zhang wrote:  
> >>>>>>> Add support for pixel_source property to drm_plane and related
> >>>>>>> documentation.
> >>>>>>>
> >>>>>>> This enum property will allow user to specify a pixel source for the
> >>>>>>> plane. Possible pixel sources will be defined in the
> >>>>>>> drm_plane_pixel_source enum.
> >>>>>>>
> >>>>>>> The current possible pixel sources are DRM_PLANE_PIXEL_SOURCE_FB and
> >>>>>>> DRM_PLANE_PIXEL_SOURCE_COLOR. The default value is *_SOURCE_FB.  
> >>>>>>
> >>>>>> I think, this should come before the solid fill property addition. 
> >>>>>> First
> >>>>>> you tell that there is a possibility to define other pixel 
> >>>>>> sources, then
> >>>>>> additional sources are defined.  
> >>>>>
> >>>>> Hi,
> >>>>>
> >>>>> that would be logical indeed.  
> >>>>
> >>>> Hi Dmitry and Pekka,
> >>>>
> >>>> Sorry for the delay in response, was out of office last week.
> >>>>
> >>>> Acked.
> >>>>  
> >>>>>  
> >>>>>>>
> >>>>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> >>>>>>> ---
> >>>>>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
> >>>>>>>    drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
> >>>>>>>    drivers/gpu/drm/drm_blend.c               | 81 
> >>>>>>> +++++++++++++++++++++++++++++++
> >>>>>>>    include/drm/drm_blend.h                  |  2 +
> >>>>>>>    include/drm/drm_plane.h                  | 21 ++++++++
> >>>>>>>    5 files changed, 109 insertions(+)
> >>>>>>>
> >>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c 
> >>>>>>> b/drivers/gpu/drm/drm_atomic_state_helper.c
> >>>>>>> index fe14be2bd2b2..86fb876efbe6 100644
> >>>>>>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> >>>>>>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> >>>>>>> @@ -252,6 +252,7 @@ void 
> >>>>>>> __drm_atomic_helper_plane_state_reset(struct drm_plane_state 
> >>>>>>> *plane_state,
> >>>>>>>        plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
> >>>>>>>        plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
> >>>>>>> +    plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
> >>>>>>>        if (plane_state->solid_fill_blob) {
> >>>>>>>            drm_property_blob_put(plane_state->solid_fill_blob);
> >>>>>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
> >>>>>>> b/drivers/gpu/drm/drm_atomic_uapi.c
> >>>>>>> index a28b4ee79444..6e59c21af66b 100644
> >>>>>>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> >>>>>>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> >>>>>>> @@ -596,6 +596,8 @@ static int 
> >>>>>>> drm_atomic_plane_set_property(struct drm_plane *plane,
> >>>>>>>            drm_property_blob_put(solid_fill);
> >>>>>>>            return ret;
> >>>>>>> +    } else if (property == plane->pixel_source_property) {
> >>>>>>> +        state->pixel_source = val;
> >>>>>>>        } else if (property == plane->alpha_property) {
> >>>>>>>            state->alpha = val;
> >>>>>>>        } else if (property == plane->blend_mode_property) {  
> >>>>>>
> >>>>>> I think, it was pointed out in the discussion that 
> >>>>>> drm_mode_setplane()
> >>>>>> (a pre-atomic IOCTL to turn the plane on and off) should also reset
> >>>>>> pixel_source to FB.  
> >>>>
> >>>> I don't remember drm_mode_setplane() being mentioned in the 
> >>>> pixel_source discussion... can you share where it was mentioned?  
> >>>
> >>> https://lore.kernel.org/dri-devel/20230627105849.004050b3@eldfell/
> >>>
> >>> Let me quote it here:
> >>> "Legacy non-atomic UAPI wrappers can do whatever they want, and program
> >>> any (new) properties they want in order to implement the legacy
> >>> expectations, so that does not seem to be a problem."
> >>>
> >>>  
> >>>>
> >>>> I'd prefer to avoid having driver change the pixel_source directly 
> >>>> as it could cause some unexpected side effects. In general, I would 
> >>>> like userspace to assign the value of pixel_source without driver 
> >>>> doing anything "under the hood".  
> >>>
> >>> s/driver/drm core/
> >>>
> >>> We have to remain compatible with old userspace, especially with the 
> >>> non-atomic one. If the userspace calls 
> >>> ioctl(DRM_IOCTL_MODE_SETPLANE), we have to display the specified FB, 
> >>> no matter what was the value of PIXEL_SOURCE before this ioctl.  
> >>
> >>
> >> Got it, thanks the clarification -- I see your point.
> >>
> >> I'm already setting plane_state->pixel_source to FB in 
> >> __drm_atomic_helper_plane_reset() and it seems to me that all drivers 
> >> are calling that within their respective plane_funcs->reset().
> >>
> >> Since (as far as I know) reset() is being called for both the atomic 
> >> and non-atomic paths, shouldn't that be enough to default pixel_source 
> >> to FB for old userspace?  
> > 
> > No, this will not clean up the state between userspace apps. Currently 
> > the rule is simple: call DRM_IOCTL_MODE_SETPLANE, get the image from FB 
> > displayed. We should keep it so.
> >   
> 
> Ok, so you are considering a use-case where we bootup with a userspace 
> (which is aware of pixel_source), that one uses the pixel_source to 
> switch the property to solid_color and then we kill this userspace and 
> bootup one which is unaware of this property and uses 
> DRM_IOCTL_MODE_SETPLANE, then we should default back to FB.

Not even that complex. There is no need to reboot and no need to kill
anything to hit this. A simple VT-switch can switch between two
different KMS clients, one could be using atomic with solid_fill, and
the other is an old legacy UAPI user. If the atomic client leaves stuff
up in KMS state, it would be nice if the legacy app still worked.

Or, maybe it's not a VT-switch but switching from, say, a graphical
login manager to a desktop or back. The same thing, different KMS
clients. But in this case it is more likely that userspace follows
common play rules, so it's less likely to have problematic left-over
KMS state.

Or, maybe you simply quit the atomic KMS client and expect fbcon to
successfully take over. I don't know what APIs fbcon uses inside the
kernel, but it definitely should clean up any mess left over by an
atomic (or legacy) KMS client to make sure it shows itself.
Traditionally it has failed to do that though, I don't know if things
are better nowadays (GAMMA_LUT, HDR_OUTPUT_METADATA, probably more).

Switching between two KMS clients is fundamentally problematic. If both
old and new KMS client are atomic, the kernel cannot simply go
resetting any KMS state automatically, because the kernel does not
know which part of state is good to reset and which would just cause
unwanted flicker and delays. That means that it is up to the two atomic
KMS clients to agree on common play rules and not leave funny state up.
IOW, not the kernel's problem, by what I have understood from kernel
developer opinions.

However, legacy KMS clients are different. As legacy clients, they may
not even have access to the properties they might need to clean up
after a previous atomic KMS client. The legacy UAPI is expected to
be slow and glitchy, but also Just Work(TM), so the kernel can reset
everything a legacy KMS client would not have access to when a legacy
KMS client issues drmModeSetPlane or drmModeSetCrtc (pardon for using
libdrm API functions for the ioctls whose names I never memorised).


Thanks,
pq
  

Patch

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index fe14be2bd2b2..86fb876efbe6 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -252,6 +252,7 @@  void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
 
 	plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
 	plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
+	plane_state->pixel_source = DRM_PLANE_PIXEL_SOURCE_FB;
 
 	if (plane_state->solid_fill_blob) {
 		drm_property_blob_put(plane_state->solid_fill_blob);
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index a28b4ee79444..6e59c21af66b 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -596,6 +596,8 @@  static int drm_atomic_plane_set_property(struct drm_plane *plane,
 		drm_property_blob_put(solid_fill);
 
 		return ret;
+	} else if (property == plane->pixel_source_property) {
+		state->pixel_source = val;
 	} else if (property == plane->alpha_property) {
 		state->alpha = val;
 	} else if (property == plane->blend_mode_property) {
@@ -671,6 +673,8 @@  drm_atomic_plane_get_property(struct drm_plane *plane,
 	} else if (property == plane->solid_fill_property) {
 		*val = state->solid_fill_blob ?
 			state->solid_fill_blob->base.id : 0;
+	} else if (property == plane->pixel_source_property) {
+		*val = state->pixel_source;
 	} else if (property == plane->alpha_property) {
 		*val = state->alpha;
 	} else if (property == plane->blend_mode_property) {
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 38c3c5d6453a..8c100a957ee2 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -189,6 +189,18 @@ 
  *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
  *	contains pixel data that drivers can use to fill a plane.
  *
+ * pixel_source:
+ *	pixel_source is set up with drm_plane_create_pixel_source_property().
+ *	It is used to toggle the source of pixel data for the plane.
+ *
+ *	Possible values:
+ *
+ *	"FB":
+ *		Framebuffer source
+ *
+ *	"COLOR":
+ *		solid_fill source
+ *
  * 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).
@@ -648,3 +660,72 @@  int drm_plane_create_solid_fill_property(struct drm_plane *plane)
 	return 0;
 }
 EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
+
+/**
+ * drm_plane_create_pixel_source_property - create a new pixel source property
+ * @plane: drm plane
+ * @supported_sources: bitmask of supported pixel_sources for the driver (NOT
+ *                     including DRM_PLANE_PIXEL_SOURCE_FB, as it will be supported
+ *                     by default).
+ *
+ * This creates a new property describing the current source of pixel data for the
+ * plane.
+ *
+ * The property is exposed to userspace as an enumeration property called
+ * "pixel_source" and has the following enumeration values:
+ *
+ * "FB":
+ *	Framebuffer pixel source
+ *
+ * "COLOR":
+ *	Solid fill color pixel source
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_plane_create_pixel_source_property(struct drm_plane *plane,
+					   unsigned int supported_sources)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_property *prop;
+	const struct drm_prop_enum_list enum_list[] = {
+		{ DRM_PLANE_PIXEL_SOURCE_FB, "FB" },
+		{ DRM_PLANE_PIXEL_SOURCE_COLOR, "COLOR" },
+	};
+	unsigned int valid_source_mask = BIT(DRM_PLANE_PIXEL_SOURCE_FB) |
+				       BIT(DRM_PLANE_PIXEL_SOURCE_COLOR);
+	int i;
+
+	/* FB is supported by default */
+	supported_sources |= BIT(DRM_PLANE_PIXEL_SOURCE_FB);
+
+	if (WARN_ON(supported_sources & ~valid_source_mask))
+		return -EINVAL;
+
+	prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, "pixel_source",
+			hweight32(supported_sources));
+
+	if (!prop)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(enum_list); i++) {
+		int ret;
+
+		if (!(BIT(enum_list[i].type) & supported_sources))
+			continue;
+
+		ret = drm_property_add_enum(prop, enum_list[i].type, enum_list[i].name);
+
+		if (ret) {
+			drm_property_destroy(dev, prop);
+
+			return ret;
+		}
+	}
+
+	drm_object_attach_property(&plane->base, prop, DRM_PLANE_PIXEL_SOURCE_FB);
+	plane->pixel_source_property = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_plane_create_pixel_source_property);
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index 0338a860b9c8..31af7cfa5b1b 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -59,4 +59,6 @@  int drm_atomic_normalize_zpos(struct drm_device *dev,
 int drm_plane_create_blend_mode_property(struct drm_plane *plane,
 					 unsigned int supported_modes);
 int drm_plane_create_solid_fill_property(struct drm_plane *plane);
+int drm_plane_create_pixel_source_property(struct drm_plane *plane,
+					   unsigned int supported_sources);
 #endif
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index f6ab313cb83e..73fb6cf8a5d9 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -59,6 +59,12 @@  struct drm_solid_fill {
 	uint32_t b;
 };
 
+enum drm_plane_pixel_source {
+	DRM_PLANE_PIXEL_SOURCE_FB,
+	DRM_PLANE_PIXEL_SOURCE_COLOR,
+	DRM_PLANE_PIXEL_SOURCE_MAX
+};
+
 /**
  * struct drm_plane_state - mutable plane state
  *
@@ -152,6 +158,14 @@  struct drm_plane_state {
 	 */
 	struct drm_solid_fill solid_fill;
 
+	/*
+	 * @pixel_source:
+	 *
+	 * Source of pixel information for the plane. See
+	 * drm_plane_create_pixel_source_property() for more details.
+	 */
+	enum drm_plane_pixel_source pixel_source;
+
 	/**
 	 * @alpha:
 	 * Opacity of the plane with 0 as completely transparent and 0xffff as
@@ -742,6 +756,13 @@  struct drm_plane {
 	 */
 	struct drm_property *solid_fill_property;
 
+	/*
+	 * @pixel_source_property:
+	 * Optional pixel_source property for this plane. See
+	 * drm_plane_create_pixel_source_property().
+	 */
+	struct drm_property *pixel_source_property;
+
 	/**
 	 * @alpha_property:
 	 * Optional alpha property for this plane. See