All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v4 0/7] Support for Solid Fill Planes
@ 2023-06-30  0:24 ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:24 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, Jessica Zhang,
	wayland-devel, freedreno

Some drivers support hardware that have optimizations for solid fill
planes. This series aims to expose these capabilities to userspace as
some compositors have a solid fill flag (ex. SOLID_COLOR in the Android
hardware composer HAL) that can be set by apps like the Android Gears
app.

In order to expose this capability to userspace, this series will:

- Introduce solid_fill and pixel_source properties to allow userspace to
  toggle between FB and solid fill sources
- Loosen NULL FB checks within the DRM atomic commit callstack to allow
  for NULL FB when solid fill is enabled.
- Add NULL FB checks in methods where FB was previously assumed to be
  non-NULL
- Have MSM DPU driver use drm_plane_state.solid_fill instead of
  dpu_plane_state.color_fill

Note: The solid fill planes feature depends on both the solid_fill *and*
pixel_source properties.

To use this feature, userspace can set the solid_fill property to a blob
containing the appropriate version number and solid fill color (in
RGB323232 format) and and setting the pixel_source property to
DRM_PLANE_PIXEL_SOURCE_COLOR. This will disable memory fetch and the
resulting plane will display the color specified by the solid_fill blob.

Currently, there's only one version of the solid_fill blob property.
However if other drivers want to support a similar feature, but require
more than just the solid fill color, they can extend this feature by
creating additional versions of the drm_solid_fill struct.

This 2 property approach was chosen because passing in a special 1x1 FB
with the necessary color information would have unecessary overhead that
does not reflect the behavior of the solid fill feature. In addition,
assigning the solid fill blob to FB_ID would require loosening some core
drm_property checks that might cause unwanted side effects elsewhere.

---
Changes in v4:
- Rebased onto latest kernel
- Reworded cover letter for clarity (Dmitry)
- Reworded commit messages for clarity
- Split existing changes into smaller commits
- Added pixel_source enum property (Dmitry, Pekka, Ville)
- Updated drm-kms comment docs with pixel_source and solid_fill
  properties (Dmitry)
- Inlined drm_atomic_convert_solid_fill_info() (Dmitry)
- Passed in plane state alpha value to _dpu_plane_color_fill_pipe()
- Link to v3: https://lore.kernel.org/r/20230104234036.636-1-quic_jesszhan@quicinc.com

Changes in v3:
- Fixed some logic errors in atomic checks (Dmitry)
- Introduced drm_plane_has_visible_data() and drm_atomic_check_fb() helper
  methods (Dmitry)
- Fixed typo in drm_solid_fill struct documentation
- Created drm_plane_has_visible_data() helper and corrected CRTC and FB
  NULL-check logic (Dmitry)
- Merged `if (fb)` blocks in drm_atomic_plane_check() and abstracted
  them into helper method (Dmitry)
- Inverted `if (solid_fill_enabled) else if (fb)` check order (Dmitry)
- Fixed indentation (Dmitry)

Changes in v2:
- Dropped SOLID_FILL_FORMAT property (Simon)
- Switched to implementing solid_fill property as a blob (Simon, Dmitry)
- Added drm_solid_fill and drm_solid_fill_info structs (Simon)
- Changed to checks for if solid_fill_blob is set (Dmitry)
- Abstracted (plane_state && !solid_fill_blob) checks to helper method
  (Dmitry)
- Removed DPU_PLANE_COLOR_FILL_FLAG
- Fixed whitespace and indentation issues (Dmitry)
- Changed to checks for if solid_fill_blob is set (Dmitry)
- Abstracted (plane_state && !solid_fill_blob) checks to helper method
  (Dmitry)
- Fixed dropped 'const' warning
- Added helper to convert color fill to BGR888 (Rob)
- Fixed indentation issue (Dmitry)
- Added support for solid fill on planes of varying sizes

---
Jessica Zhang (7):
      drm: Introduce solid fill DRM plane property
      drm: Introduce pixel_source DRM plane property
      drm/atomic: Move framebuffer checks to helper
      drm/atomic: Loosen FB atomic checks
      drm/msm/dpu: Add solid fill and pixel source properties
      drm/msm/dpu: Allow NULL FBs in atomic commit
      drm/msm/dpu: Use DRM solid_fill property

 drivers/gpu/drm/drm_atomic.c              | 142 +++++++++++++++++-------------
 drivers/gpu/drm/drm_atomic_helper.c       |  34 ++++---
 drivers/gpu/drm/drm_atomic_state_helper.c |  10 +++
 drivers/gpu/drm/drm_atomic_uapi.c         |  59 +++++++++++++
 drivers/gpu/drm/drm_blend.c               | 114 ++++++++++++++++++++++++
 drivers/gpu/drm/drm_plane.c               |   8 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |   9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c |  68 +++++++++-----
 include/drm/drm_atomic_helper.h           |   4 +-
 include/drm/drm_blend.h                   |   3 +
 include/drm/drm_plane.h                   |  92 +++++++++++++++++++
 11 files changed, 437 insertions(+), 106 deletions(-)
---
base-commit: a0364260213c96f6817f7e85cdce293cb743460f
change-id: 20230404-solid-fill-05016175db36

Best regards,
-- 
Jessica Zhang <quic_jesszhan@quicinc.com>


^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 0/7] Support for Solid Fill Planes
@ 2023-06-30  0:24 ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:24 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel, Jessica Zhang

Some drivers support hardware that have optimizations for solid fill
planes. This series aims to expose these capabilities to userspace as
some compositors have a solid fill flag (ex. SOLID_COLOR in the Android
hardware composer HAL) that can be set by apps like the Android Gears
app.

In order to expose this capability to userspace, this series will:

- Introduce solid_fill and pixel_source properties to allow userspace to
  toggle between FB and solid fill sources
- Loosen NULL FB checks within the DRM atomic commit callstack to allow
  for NULL FB when solid fill is enabled.
- Add NULL FB checks in methods where FB was previously assumed to be
  non-NULL
- Have MSM DPU driver use drm_plane_state.solid_fill instead of
  dpu_plane_state.color_fill

Note: The solid fill planes feature depends on both the solid_fill *and*
pixel_source properties.

To use this feature, userspace can set the solid_fill property to a blob
containing the appropriate version number and solid fill color (in
RGB323232 format) and and setting the pixel_source property to
DRM_PLANE_PIXEL_SOURCE_COLOR. This will disable memory fetch and the
resulting plane will display the color specified by the solid_fill blob.

Currently, there's only one version of the solid_fill blob property.
However if other drivers want to support a similar feature, but require
more than just the solid fill color, they can extend this feature by
creating additional versions of the drm_solid_fill struct.

This 2 property approach was chosen because passing in a special 1x1 FB
with the necessary color information would have unecessary overhead that
does not reflect the behavior of the solid fill feature. In addition,
assigning the solid fill blob to FB_ID would require loosening some core
drm_property checks that might cause unwanted side effects elsewhere.

---
Changes in v4:
- Rebased onto latest kernel
- Reworded cover letter for clarity (Dmitry)
- Reworded commit messages for clarity
- Split existing changes into smaller commits
- Added pixel_source enum property (Dmitry, Pekka, Ville)
- Updated drm-kms comment docs with pixel_source and solid_fill
  properties (Dmitry)
- Inlined drm_atomic_convert_solid_fill_info() (Dmitry)
- Passed in plane state alpha value to _dpu_plane_color_fill_pipe()
- Link to v3: https://lore.kernel.org/r/20230104234036.636-1-quic_jesszhan@quicinc.com

Changes in v3:
- Fixed some logic errors in atomic checks (Dmitry)
- Introduced drm_plane_has_visible_data() and drm_atomic_check_fb() helper
  methods (Dmitry)
- Fixed typo in drm_solid_fill struct documentation
- Created drm_plane_has_visible_data() helper and corrected CRTC and FB
  NULL-check logic (Dmitry)
- Merged `if (fb)` blocks in drm_atomic_plane_check() and abstracted
  them into helper method (Dmitry)
- Inverted `if (solid_fill_enabled) else if (fb)` check order (Dmitry)
- Fixed indentation (Dmitry)

Changes in v2:
- Dropped SOLID_FILL_FORMAT property (Simon)
- Switched to implementing solid_fill property as a blob (Simon, Dmitry)
- Added drm_solid_fill and drm_solid_fill_info structs (Simon)
- Changed to checks for if solid_fill_blob is set (Dmitry)
- Abstracted (plane_state && !solid_fill_blob) checks to helper method
  (Dmitry)
- Removed DPU_PLANE_COLOR_FILL_FLAG
- Fixed whitespace and indentation issues (Dmitry)
- Changed to checks for if solid_fill_blob is set (Dmitry)
- Abstracted (plane_state && !solid_fill_blob) checks to helper method
  (Dmitry)
- Fixed dropped 'const' warning
- Added helper to convert color fill to BGR888 (Rob)
- Fixed indentation issue (Dmitry)
- Added support for solid fill on planes of varying sizes

---
Jessica Zhang (7):
      drm: Introduce solid fill DRM plane property
      drm: Introduce pixel_source DRM plane property
      drm/atomic: Move framebuffer checks to helper
      drm/atomic: Loosen FB atomic checks
      drm/msm/dpu: Add solid fill and pixel source properties
      drm/msm/dpu: Allow NULL FBs in atomic commit
      drm/msm/dpu: Use DRM solid_fill property

 drivers/gpu/drm/drm_atomic.c              | 142 +++++++++++++++++-------------
 drivers/gpu/drm/drm_atomic_helper.c       |  34 ++++---
 drivers/gpu/drm/drm_atomic_state_helper.c |  10 +++
 drivers/gpu/drm/drm_atomic_uapi.c         |  59 +++++++++++++
 drivers/gpu/drm/drm_blend.c               | 114 ++++++++++++++++++++++++
 drivers/gpu/drm/drm_plane.c               |   8 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |   9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c |  68 +++++++++-----
 include/drm/drm_atomic_helper.h           |   4 +-
 include/drm/drm_blend.h                   |   3 +
 include/drm/drm_plane.h                   |  92 +++++++++++++++++++
 11 files changed, 437 insertions(+), 106 deletions(-)
---
base-commit: a0364260213c96f6817f7e85cdce293cb743460f
change-id: 20230404-solid-fill-05016175db36

Best regards,
-- 
Jessica Zhang <quic_jesszhan@quicinc.com>


^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
  2023-06-30  0:24 ` Jessica Zhang
@ 2023-06-30  0:25   ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel, Jessica Zhang

Document and add support for solid_fill property to drm_plane. In
addition, add support for setting and getting the values for solid_fill.

To enable solid fill planes, userspace must assign a property blob to
the "solid_fill" plane property containing the following information:

struct drm_solid_fill_info {
	u8 version;
	u32 r, g, b;
};

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
 drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
 include/drm/drm_blend.h                   |  1 +
 include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
 5 files changed, 141 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 784e63d70a42..fe14be2bd2b2 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -253,6 +253,11 @@ 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;
 
+	if (plane_state->solid_fill_blob) {
+		drm_property_blob_put(plane_state->solid_fill_blob);
+		plane_state->solid_fill_blob = NULL;
+	}
+
 	if (plane->color_encoding_property) {
 		if (!drm_object_property_get_default_value(&plane->base,
 							   plane->color_encoding_property,
@@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 	if (state->fb)
 		drm_framebuffer_get(state->fb);
 
+	if (state->solid_fill_blob)
+		drm_property_blob_get(state->solid_fill_blob);
+
 	state->fence = NULL;
 	state->commit = NULL;
 	state->fb_damage_clips = NULL;
@@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
 		drm_crtc_commit_put(state->commit);
 
 	drm_property_blob_put(state->fb_damage_clips);
+	drm_property_blob_put(state->solid_fill_blob);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
 
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index d867e7f9f2cd..a28b4ee79444 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -316,6 +316,51 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
 }
 EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
 
+static int drm_atomic_set_solid_fill_prop(struct drm_plane_state *state,
+		struct drm_property_blob *blob)
+{
+	int ret = 0;
+	int blob_version;
+
+	if (blob == state->solid_fill_blob)
+		return 0;
+
+	drm_property_blob_put(state->solid_fill_blob);
+	state->solid_fill_blob = NULL;
+
+	memset(&state->solid_fill, 0, sizeof(state->solid_fill));
+
+	if (blob) {
+		struct drm_solid_fill_info *user_info = (struct drm_solid_fill_info *)blob->data;
+
+		if (blob->length != sizeof(struct drm_solid_fill_info)) {
+			drm_dbg_atomic(state->plane->dev,
+				       "[PLANE:%d:%s] bad solid fill blob length: %zu\n",
+				       state->plane->base.id, state->plane->name,
+				       blob->length);
+			return -EINVAL;
+		}
+
+		blob_version = user_info->version;
+
+		/* Add more versions if necessary */
+		if (blob_version == 1) {
+			state->solid_fill.r = user_info->r;
+			state->solid_fill.g = user_info->g;
+			state->solid_fill.b = user_info->b;
+		} else {
+			drm_dbg_atomic(state->plane->dev,
+				       "[PLANE:%d:%s] failed to set solid fill (ret=%d)\n",
+				       state->plane->base.id, state->plane->name,
+				       ret);
+			return -EINVAL;
+		}
+		state->solid_fill_blob = drm_property_blob_get(blob);
+	}
+
+	return ret;
+}
+
 static void set_out_fence_for_crtc(struct drm_atomic_state *state,
 				   struct drm_crtc *crtc, s32 __user *fence_ptr)
 {
@@ -544,6 +589,13 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
 		state->src_w = val;
 	} else if (property == config->prop_src_h) {
 		state->src_h = val;
+	} else if (property == plane->solid_fill_property) {
+		struct drm_property_blob *solid_fill = drm_property_lookup_blob(dev, val);
+
+		ret = drm_atomic_set_solid_fill_prop(state, solid_fill);
+		drm_property_blob_put(solid_fill);
+
+		return ret;
 	} else if (property == plane->alpha_property) {
 		state->alpha = val;
 	} else if (property == plane->blend_mode_property) {
@@ -616,6 +668,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
 		*val = state->src_w;
 	} else if (property == config->prop_src_h) {
 		*val = state->src_h;
+	} else if (property == plane->solid_fill_property) {
+		*val = state->solid_fill_blob ?
+			state->solid_fill_blob->base.id : 0;
 	} 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 6e74de833466..38c3c5d6453a 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -185,6 +185,10 @@
  *		 plane does not expose the "alpha" property, then this is
  *		 assumed to be 1.0
  *
+ * solid_fill:
+ *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
+ *	contains pixel data that drivers can use to fill a plane.
+ *
  * 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).
@@ -615,3 +619,32 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
 	return 0;
 }
 EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
+
+/**
+ * drm_plane_create_solid_fill_property - create a new solid_fill property
+ * @plane: drm plane
+ *
+ * This creates a new property that holds pixel data for solid fill planes. This
+ * property is exposed to userspace as a property blob called "solid_fill".
+ *
+ * For information on what the blob contains, see `drm_solid_fill_info`.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_plane_create_solid_fill_property(struct drm_plane *plane)
+{
+	struct drm_property *prop;
+
+	prop = drm_property_create(plane->dev,
+			DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
+			"solid_fill", 0);
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&plane->base, prop, 0);
+	plane->solid_fill_property = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index 88bdfec3bd88..0338a860b9c8 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
 			      struct drm_atomic_state *state);
 int drm_plane_create_blend_mode_property(struct drm_plane *plane,
 					 unsigned int supported_modes);
+int drm_plane_create_solid_fill_property(struct drm_plane *plane);
 #endif
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 51291983ea44..f6ab313cb83e 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -40,6 +40,25 @@ enum drm_scaling_filter {
 	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
 };
 
+/**
+ * struct drm_solid_fill_info - User info for solid fill planes
+ */
+struct drm_solid_fill_info {
+	__u8 version;
+	__u32 r, g, b;
+};
+
+/**
+ * struct solid_fill_property - RGB values for solid fill plane
+ *
+ * Note: This is the V1 for this feature
+ */
+struct drm_solid_fill {
+	uint32_t r;
+	uint32_t g;
+	uint32_t b;
+};
+
 /**
  * struct drm_plane_state - mutable plane state
  *
@@ -116,6 +135,23 @@ struct drm_plane_state {
 	/** @src_h: height of visible portion of plane (in 16.16) */
 	uint32_t src_h, src_w;
 
+	/**
+	 * @solid_fill_blob:
+	 *
+	 * Blob containing relevant information for a solid fill plane
+	 * including pixel format and data. See
+	 * drm_plane_create_solid_fill_property() for more details.
+	 */
+	struct drm_property_blob *solid_fill_blob;
+
+	/**
+	 * @solid_fill:
+	 *
+	 * Pixel data for solid fill planes. See
+	 * drm_plane_create_solid_fill_property() for more details.
+	 */
+	struct drm_solid_fill solid_fill;
+
 	/**
 	 * @alpha:
 	 * Opacity of the plane with 0 as completely transparent and 0xffff as
@@ -699,6 +735,13 @@ struct drm_plane {
 	 */
 	struct drm_plane_state *state;
 
+	/*
+	 * @solid_fill_property:
+	 * Optional solid_fill property for this plane. See
+	 * drm_plane_create_solid_fill_property().
+	 */
+	struct drm_property *solid_fill_property;
+
 	/**
 	 * @alpha_property:
 	 * Optional alpha property for this plane. See

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
@ 2023-06-30  0:25   ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, Jessica Zhang,
	wayland-devel, freedreno

Document and add support for solid_fill property to drm_plane. In
addition, add support for setting and getting the values for solid_fill.

To enable solid fill planes, userspace must assign a property blob to
the "solid_fill" plane property containing the following information:

struct drm_solid_fill_info {
	u8 version;
	u32 r, g, b;
};

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
 drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
 include/drm/drm_blend.h                   |  1 +
 include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
 5 files changed, 141 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 784e63d70a42..fe14be2bd2b2 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -253,6 +253,11 @@ 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;
 
+	if (plane_state->solid_fill_blob) {
+		drm_property_blob_put(plane_state->solid_fill_blob);
+		plane_state->solid_fill_blob = NULL;
+	}
+
 	if (plane->color_encoding_property) {
 		if (!drm_object_property_get_default_value(&plane->base,
 							   plane->color_encoding_property,
@@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 	if (state->fb)
 		drm_framebuffer_get(state->fb);
 
+	if (state->solid_fill_blob)
+		drm_property_blob_get(state->solid_fill_blob);
+
 	state->fence = NULL;
 	state->commit = NULL;
 	state->fb_damage_clips = NULL;
@@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
 		drm_crtc_commit_put(state->commit);
 
 	drm_property_blob_put(state->fb_damage_clips);
+	drm_property_blob_put(state->solid_fill_blob);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
 
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index d867e7f9f2cd..a28b4ee79444 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -316,6 +316,51 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
 }
 EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
 
+static int drm_atomic_set_solid_fill_prop(struct drm_plane_state *state,
+		struct drm_property_blob *blob)
+{
+	int ret = 0;
+	int blob_version;
+
+	if (blob == state->solid_fill_blob)
+		return 0;
+
+	drm_property_blob_put(state->solid_fill_blob);
+	state->solid_fill_blob = NULL;
+
+	memset(&state->solid_fill, 0, sizeof(state->solid_fill));
+
+	if (blob) {
+		struct drm_solid_fill_info *user_info = (struct drm_solid_fill_info *)blob->data;
+
+		if (blob->length != sizeof(struct drm_solid_fill_info)) {
+			drm_dbg_atomic(state->plane->dev,
+				       "[PLANE:%d:%s] bad solid fill blob length: %zu\n",
+				       state->plane->base.id, state->plane->name,
+				       blob->length);
+			return -EINVAL;
+		}
+
+		blob_version = user_info->version;
+
+		/* Add more versions if necessary */
+		if (blob_version == 1) {
+			state->solid_fill.r = user_info->r;
+			state->solid_fill.g = user_info->g;
+			state->solid_fill.b = user_info->b;
+		} else {
+			drm_dbg_atomic(state->plane->dev,
+				       "[PLANE:%d:%s] failed to set solid fill (ret=%d)\n",
+				       state->plane->base.id, state->plane->name,
+				       ret);
+			return -EINVAL;
+		}
+		state->solid_fill_blob = drm_property_blob_get(blob);
+	}
+
+	return ret;
+}
+
 static void set_out_fence_for_crtc(struct drm_atomic_state *state,
 				   struct drm_crtc *crtc, s32 __user *fence_ptr)
 {
@@ -544,6 +589,13 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
 		state->src_w = val;
 	} else if (property == config->prop_src_h) {
 		state->src_h = val;
+	} else if (property == plane->solid_fill_property) {
+		struct drm_property_blob *solid_fill = drm_property_lookup_blob(dev, val);
+
+		ret = drm_atomic_set_solid_fill_prop(state, solid_fill);
+		drm_property_blob_put(solid_fill);
+
+		return ret;
 	} else if (property == plane->alpha_property) {
 		state->alpha = val;
 	} else if (property == plane->blend_mode_property) {
@@ -616,6 +668,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
 		*val = state->src_w;
 	} else if (property == config->prop_src_h) {
 		*val = state->src_h;
+	} else if (property == plane->solid_fill_property) {
+		*val = state->solid_fill_blob ?
+			state->solid_fill_blob->base.id : 0;
 	} 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 6e74de833466..38c3c5d6453a 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -185,6 +185,10 @@
  *		 plane does not expose the "alpha" property, then this is
  *		 assumed to be 1.0
  *
+ * solid_fill:
+ *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
+ *	contains pixel data that drivers can use to fill a plane.
+ *
  * 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).
@@ -615,3 +619,32 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
 	return 0;
 }
 EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
+
+/**
+ * drm_plane_create_solid_fill_property - create a new solid_fill property
+ * @plane: drm plane
+ *
+ * This creates a new property that holds pixel data for solid fill planes. This
+ * property is exposed to userspace as a property blob called "solid_fill".
+ *
+ * For information on what the blob contains, see `drm_solid_fill_info`.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_plane_create_solid_fill_property(struct drm_plane *plane)
+{
+	struct drm_property *prop;
+
+	prop = drm_property_create(plane->dev,
+			DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
+			"solid_fill", 0);
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&plane->base, prop, 0);
+	plane->solid_fill_property = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index 88bdfec3bd88..0338a860b9c8 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
 			      struct drm_atomic_state *state);
 int drm_plane_create_blend_mode_property(struct drm_plane *plane,
 					 unsigned int supported_modes);
+int drm_plane_create_solid_fill_property(struct drm_plane *plane);
 #endif
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 51291983ea44..f6ab313cb83e 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -40,6 +40,25 @@ enum drm_scaling_filter {
 	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
 };
 
+/**
+ * struct drm_solid_fill_info - User info for solid fill planes
+ */
+struct drm_solid_fill_info {
+	__u8 version;
+	__u32 r, g, b;
+};
+
+/**
+ * struct solid_fill_property - RGB values for solid fill plane
+ *
+ * Note: This is the V1 for this feature
+ */
+struct drm_solid_fill {
+	uint32_t r;
+	uint32_t g;
+	uint32_t b;
+};
+
 /**
  * struct drm_plane_state - mutable plane state
  *
@@ -116,6 +135,23 @@ struct drm_plane_state {
 	/** @src_h: height of visible portion of plane (in 16.16) */
 	uint32_t src_h, src_w;
 
+	/**
+	 * @solid_fill_blob:
+	 *
+	 * Blob containing relevant information for a solid fill plane
+	 * including pixel format and data. See
+	 * drm_plane_create_solid_fill_property() for more details.
+	 */
+	struct drm_property_blob *solid_fill_blob;
+
+	/**
+	 * @solid_fill:
+	 *
+	 * Pixel data for solid fill planes. See
+	 * drm_plane_create_solid_fill_property() for more details.
+	 */
+	struct drm_solid_fill solid_fill;
+
 	/**
 	 * @alpha:
 	 * Opacity of the plane with 0 as completely transparent and 0xffff as
@@ -699,6 +735,13 @@ struct drm_plane {
 	 */
 	struct drm_plane_state *state;
 
+	/*
+	 * @solid_fill_property:
+	 * Optional solid_fill property for this plane. See
+	 * drm_plane_create_solid_fill_property().
+	 */
+	struct drm_property *solid_fill_property;
+
 	/**
 	 * @alpha_property:
 	 * Optional alpha property for this plane. See

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-06-30  0:24 ` Jessica Zhang
@ 2023-06-30  0:25   ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, Jessica Zhang,
	wayland-devel, freedreno

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
+ *
+ * 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


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-06-30  0:25   ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel, Jessica Zhang

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
+ *
+ * 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


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 3/7] drm/atomic: Move framebuffer checks to helper
  2023-06-30  0:24 ` Jessica Zhang
@ 2023-06-30  0:25   ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, Jessica Zhang,
	wayland-devel, freedreno

Currently framebuffer checks happen directly in
drm_atomic_plane_check(). Move these checks into their own helper
method.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/drm_atomic.c | 130 ++++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index b4c6ffc438da..404b984d2d9f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -580,6 +580,76 @@ plane_switching_crtc(const struct drm_plane_state *old_plane_state,
 	return true;
 }
 
+static int drm_atomic_check_fb(const struct drm_plane_state *state)
+{
+	struct drm_plane *plane = state->plane;
+	const struct drm_framebuffer *fb = state->fb;
+	struct drm_mode_rect *clips;
+
+	uint32_t num_clips;
+	unsigned int fb_width, fb_height;
+	int ret;
+
+	/* Check whether this plane supports the fb pixel format. */
+	ret = drm_plane_check_pixel_format(plane, fb->format->format,
+					   fb->modifier);
+
+	if (ret) {
+		drm_dbg_atomic(plane->dev,
+			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
+			       plane->base.id, plane->name,
+			       &fb->format->format, fb->modifier);
+		return ret;
+	}
+
+	fb_width = fb->width << 16;
+	fb_height = fb->height << 16;
+
+	/* Make sure source coordinates are inside the fb. */
+	if (state->src_w > fb_width ||
+	    state->src_x > fb_width - state->src_w ||
+	    state->src_h > fb_height ||
+	    state->src_y > fb_height - state->src_h) {
+		drm_dbg_atomic(plane->dev,
+			       "[PLANE:%d:%s] invalid source coordinates "
+			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
+			       plane->base.id, plane->name,
+			       state->src_w >> 16,
+			       ((state->src_w & 0xffff) * 15625) >> 10,
+			       state->src_h >> 16,
+			       ((state->src_h & 0xffff) * 15625) >> 10,
+			       state->src_x >> 16,
+			       ((state->src_x & 0xffff) * 15625) >> 10,
+			       state->src_y >> 16,
+			       ((state->src_y & 0xffff) * 15625) >> 10,
+			       fb->width, fb->height);
+		return -ENOSPC;
+	}
+
+	clips = __drm_plane_get_damage_clips(state);
+	num_clips = drm_plane_get_damage_clips_count(state);
+
+	/* Make sure damage clips are valid and inside the fb. */
+	while (num_clips > 0) {
+		if (clips->x1 >= clips->x2 ||
+		    clips->y1 >= clips->y2 ||
+		    clips->x1 < 0 ||
+		    clips->y1 < 0 ||
+		    clips->x2 > fb_width ||
+		    clips->y2 > fb_height) {
+			drm_dbg_atomic(plane->dev,
+				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
+				       plane->base.id, plane->name, clips->x1,
+				       clips->y1, clips->x2, clips->y2);
+			return -EINVAL;
+		}
+		clips++;
+		num_clips--;
+	}
+
+	return 0;
+}
+
 /**
  * drm_atomic_plane_check - check plane state
  * @old_plane_state: old plane state to check
@@ -596,9 +666,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 	struct drm_plane *plane = new_plane_state->plane;
 	struct drm_crtc *crtc = new_plane_state->crtc;
 	const struct drm_framebuffer *fb = new_plane_state->fb;
-	unsigned int fb_width, fb_height;
-	struct drm_mode_rect *clips;
-	uint32_t num_clips;
 	int ret;
 
 	/* either *both* CRTC and FB must be set, or neither */
@@ -625,17 +692,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 		return -EINVAL;
 	}
 
-	/* Check whether this plane supports the fb pixel format. */
-	ret = drm_plane_check_pixel_format(plane, fb->format->format,
-					   fb->modifier);
-	if (ret) {
-		drm_dbg_atomic(plane->dev,
-			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
-			       plane->base.id, plane->name,
-			       &fb->format->format, fb->modifier);
-		return ret;
-	}
-
 	/* Give drivers some help against integer overflows */
 	if (new_plane_state->crtc_w > INT_MAX ||
 	    new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
@@ -649,49 +705,11 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 		return -ERANGE;
 	}
 
-	fb_width = fb->width << 16;
-	fb_height = fb->height << 16;
 
-	/* Make sure source coordinates are inside the fb. */
-	if (new_plane_state->src_w > fb_width ||
-	    new_plane_state->src_x > fb_width - new_plane_state->src_w ||
-	    new_plane_state->src_h > fb_height ||
-	    new_plane_state->src_y > fb_height - new_plane_state->src_h) {
-		drm_dbg_atomic(plane->dev,
-			       "[PLANE:%d:%s] invalid source coordinates "
-			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
-			       plane->base.id, plane->name,
-			       new_plane_state->src_w >> 16,
-			       ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
-			       new_plane_state->src_h >> 16,
-			       ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
-			       new_plane_state->src_x >> 16,
-			       ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
-			       new_plane_state->src_y >> 16,
-			       ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
-			       fb->width, fb->height);
-		return -ENOSPC;
-	}
-
-	clips = __drm_plane_get_damage_clips(new_plane_state);
-	num_clips = drm_plane_get_damage_clips_count(new_plane_state);
-
-	/* Make sure damage clips are valid and inside the fb. */
-	while (num_clips > 0) {
-		if (clips->x1 >= clips->x2 ||
-		    clips->y1 >= clips->y2 ||
-		    clips->x1 < 0 ||
-		    clips->y1 < 0 ||
-		    clips->x2 > fb_width ||
-		    clips->y2 > fb_height) {
-			drm_dbg_atomic(plane->dev,
-				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
-				       plane->base.id, plane->name, clips->x1,
-				       clips->y1, clips->x2, clips->y2);
-			return -EINVAL;
-		}
-		clips++;
-		num_clips--;
+	if (fb) {
+		ret = drm_atomic_check_fb(new_plane_state);
+		if (ret)
+			return ret;
 	}
 
 	if (plane_switching_crtc(old_plane_state, new_plane_state)) {

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 3/7] drm/atomic: Move framebuffer checks to helper
@ 2023-06-30  0:25   ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel, Jessica Zhang

Currently framebuffer checks happen directly in
drm_atomic_plane_check(). Move these checks into their own helper
method.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/drm_atomic.c | 130 ++++++++++++++++++++++++-------------------
 1 file changed, 74 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index b4c6ffc438da..404b984d2d9f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -580,6 +580,76 @@ plane_switching_crtc(const struct drm_plane_state *old_plane_state,
 	return true;
 }
 
+static int drm_atomic_check_fb(const struct drm_plane_state *state)
+{
+	struct drm_plane *plane = state->plane;
+	const struct drm_framebuffer *fb = state->fb;
+	struct drm_mode_rect *clips;
+
+	uint32_t num_clips;
+	unsigned int fb_width, fb_height;
+	int ret;
+
+	/* Check whether this plane supports the fb pixel format. */
+	ret = drm_plane_check_pixel_format(plane, fb->format->format,
+					   fb->modifier);
+
+	if (ret) {
+		drm_dbg_atomic(plane->dev,
+			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
+			       plane->base.id, plane->name,
+			       &fb->format->format, fb->modifier);
+		return ret;
+	}
+
+	fb_width = fb->width << 16;
+	fb_height = fb->height << 16;
+
+	/* Make sure source coordinates are inside the fb. */
+	if (state->src_w > fb_width ||
+	    state->src_x > fb_width - state->src_w ||
+	    state->src_h > fb_height ||
+	    state->src_y > fb_height - state->src_h) {
+		drm_dbg_atomic(plane->dev,
+			       "[PLANE:%d:%s] invalid source coordinates "
+			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
+			       plane->base.id, plane->name,
+			       state->src_w >> 16,
+			       ((state->src_w & 0xffff) * 15625) >> 10,
+			       state->src_h >> 16,
+			       ((state->src_h & 0xffff) * 15625) >> 10,
+			       state->src_x >> 16,
+			       ((state->src_x & 0xffff) * 15625) >> 10,
+			       state->src_y >> 16,
+			       ((state->src_y & 0xffff) * 15625) >> 10,
+			       fb->width, fb->height);
+		return -ENOSPC;
+	}
+
+	clips = __drm_plane_get_damage_clips(state);
+	num_clips = drm_plane_get_damage_clips_count(state);
+
+	/* Make sure damage clips are valid and inside the fb. */
+	while (num_clips > 0) {
+		if (clips->x1 >= clips->x2 ||
+		    clips->y1 >= clips->y2 ||
+		    clips->x1 < 0 ||
+		    clips->y1 < 0 ||
+		    clips->x2 > fb_width ||
+		    clips->y2 > fb_height) {
+			drm_dbg_atomic(plane->dev,
+				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
+				       plane->base.id, plane->name, clips->x1,
+				       clips->y1, clips->x2, clips->y2);
+			return -EINVAL;
+		}
+		clips++;
+		num_clips--;
+	}
+
+	return 0;
+}
+
 /**
  * drm_atomic_plane_check - check plane state
  * @old_plane_state: old plane state to check
@@ -596,9 +666,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 	struct drm_plane *plane = new_plane_state->plane;
 	struct drm_crtc *crtc = new_plane_state->crtc;
 	const struct drm_framebuffer *fb = new_plane_state->fb;
-	unsigned int fb_width, fb_height;
-	struct drm_mode_rect *clips;
-	uint32_t num_clips;
 	int ret;
 
 	/* either *both* CRTC and FB must be set, or neither */
@@ -625,17 +692,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 		return -EINVAL;
 	}
 
-	/* Check whether this plane supports the fb pixel format. */
-	ret = drm_plane_check_pixel_format(plane, fb->format->format,
-					   fb->modifier);
-	if (ret) {
-		drm_dbg_atomic(plane->dev,
-			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
-			       plane->base.id, plane->name,
-			       &fb->format->format, fb->modifier);
-		return ret;
-	}
-
 	/* Give drivers some help against integer overflows */
 	if (new_plane_state->crtc_w > INT_MAX ||
 	    new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
@@ -649,49 +705,11 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 		return -ERANGE;
 	}
 
-	fb_width = fb->width << 16;
-	fb_height = fb->height << 16;
 
-	/* Make sure source coordinates are inside the fb. */
-	if (new_plane_state->src_w > fb_width ||
-	    new_plane_state->src_x > fb_width - new_plane_state->src_w ||
-	    new_plane_state->src_h > fb_height ||
-	    new_plane_state->src_y > fb_height - new_plane_state->src_h) {
-		drm_dbg_atomic(plane->dev,
-			       "[PLANE:%d:%s] invalid source coordinates "
-			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
-			       plane->base.id, plane->name,
-			       new_plane_state->src_w >> 16,
-			       ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
-			       new_plane_state->src_h >> 16,
-			       ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
-			       new_plane_state->src_x >> 16,
-			       ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
-			       new_plane_state->src_y >> 16,
-			       ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
-			       fb->width, fb->height);
-		return -ENOSPC;
-	}
-
-	clips = __drm_plane_get_damage_clips(new_plane_state);
-	num_clips = drm_plane_get_damage_clips_count(new_plane_state);
-
-	/* Make sure damage clips are valid and inside the fb. */
-	while (num_clips > 0) {
-		if (clips->x1 >= clips->x2 ||
-		    clips->y1 >= clips->y2 ||
-		    clips->x1 < 0 ||
-		    clips->y1 < 0 ||
-		    clips->x2 > fb_width ||
-		    clips->y2 > fb_height) {
-			drm_dbg_atomic(plane->dev,
-				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
-				       plane->base.id, plane->name, clips->x1,
-				       clips->y1, clips->x2, clips->y2);
-			return -EINVAL;
-		}
-		clips++;
-		num_clips--;
+	if (fb) {
+		ret = drm_atomic_check_fb(new_plane_state);
+		if (ret)
+			return ret;
 	}
 
 	if (plane_switching_crtc(old_plane_state, new_plane_state)) {

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 4/7] drm/atomic: Loosen FB atomic checks
  2023-06-30  0:24 ` Jessica Zhang
@ 2023-06-30  0:25   ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, Jessica Zhang,
	wayland-devel, freedreno

Loosen the requirements for atomic and legacy commit so that, in cases
where solid fill planes is enabled but no FB is set, the commit can
still go through.

This includes adding framebuffer NULL checks in other areas to account
for FB being NULL when solid fill is enabled.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/drm_atomic.c        | 14 +++++++-------
 drivers/gpu/drm/drm_atomic_helper.c | 34 ++++++++++++++++++++--------------
 drivers/gpu/drm/drm_plane.c         |  8 ++++----
 include/drm/drm_atomic_helper.h     |  4 ++--
 include/drm/drm_plane.h             | 28 ++++++++++++++++++++++++++++
 5 files changed, 61 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 404b984d2d9f..ec9681c25366 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -668,14 +668,14 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 	const struct drm_framebuffer *fb = new_plane_state->fb;
 	int ret;
 
-	/* either *both* CRTC and FB must be set, or neither */
-	if (crtc && !fb) {
-		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
+	/* either *both* CRTC and pixel source must be set, or neither */
+	if (crtc && !drm_plane_has_visible_data(new_plane_state)) {
+		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no visible data\n",
 			       plane->base.id, plane->name);
 		return -EINVAL;
-	} else if (fb && !crtc) {
-		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
-			       plane->base.id, plane->name);
+	} else if (drm_plane_has_visible_data(new_plane_state) && !crtc) {
+		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] Source %d has visible data but no CRTC\n",
+			       plane->base.id, plane->name, new_plane_state->pixel_source);
 		return -EINVAL;
 	}
 
@@ -706,7 +706,7 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 	}
 
 
-	if (fb) {
+	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
 		ret = drm_atomic_check_fb(new_plane_state);
 		if (ret)
 			return ret;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 41b8066f61ff..d05ec9ef2b3e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -864,7 +864,7 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
 	*src = drm_plane_state_src(plane_state);
 	*dst = drm_plane_state_dest(plane_state);
 
-	if (!fb) {
+	if (!drm_plane_has_visible_data(plane_state)) {
 		plane_state->visible = false;
 		return 0;
 	}
@@ -881,25 +881,31 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
 		return -EINVAL;
 	}
 
-	drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
+	if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+		drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
 
-	/* Check scaling */
-	hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
-	vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
-	if (hscale < 0 || vscale < 0) {
-		drm_dbg_kms(plane_state->plane->dev,
-			    "Invalid scaling of plane\n");
-		drm_rect_debug_print("src: ", &plane_state->src, true);
-		drm_rect_debug_print("dst: ", &plane_state->dst, false);
-		return -ERANGE;
+		/* Check scaling */
+		hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+		vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
+
+		if (hscale < 0 || vscale < 0) {
+			drm_dbg_kms(plane_state->plane->dev,
+					"Invalid scaling of plane\n");
+			drm_rect_debug_print("src: ", &plane_state->src, true);
+			drm_rect_debug_print("dst: ", &plane_state->dst, false);
+			return -ERANGE;
+		}
 	}
 
 	if (crtc_state->enable)
 		drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
 
-	plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
-
-	drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+	if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+		plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
+		drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+	} else if (drm_plane_solid_fill_enabled(plane_state)) {
+		plane_state->visible = true;
+	}
 
 	if (!plane_state->visible)
 		/*
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 24e7998d1731..5f19a27ba182 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -861,8 +861,8 @@ static int __setplane_internal(struct drm_plane *plane,
 
 	WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
 
-	/* No fb means shut it down */
-	if (!fb) {
+	/* No visible data means shut it down */
+	if (!drm_plane_has_visible_data(plane->state)) {
 		plane->old_fb = plane->fb;
 		ret = plane->funcs->disable_plane(plane, ctx);
 		if (!ret) {
@@ -913,8 +913,8 @@ static int __setplane_atomic(struct drm_plane *plane,
 
 	WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
 
-	/* No fb means shut it down */
-	if (!fb)
+	/* No visible data means shut it down */
+	if (!drm_plane_has_visible_data(plane->state))
 		return plane->funcs->disable_plane(plane, ctx);
 
 	/*
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 536a0b0091c3..6d97f38ac1f6 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -256,8 +256,8 @@ drm_atomic_plane_disabling(struct drm_plane_state *old_plane_state,
 	 * Anything else should be considered a bug in the atomic core, so we
 	 * gently warn about it.
 	 */
-	WARN_ON((new_plane_state->crtc == NULL && new_plane_state->fb != NULL) ||
-		(new_plane_state->crtc != NULL && new_plane_state->fb == NULL));
+	WARN_ON((new_plane_state->crtc == NULL && drm_plane_has_visible_data(new_plane_state)) ||
+		(new_plane_state->crtc != NULL && !drm_plane_has_visible_data(new_plane_state)));
 
 	return old_plane_state->crtc && !new_plane_state->crtc;
 }
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 73fb6cf8a5d9..f893f7a56912 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -998,6 +998,34 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
 #define drm_for_each_plane(plane, dev) \
 	list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
 
+/**
+ * drm_plane_solid_fill_enabled - Check if solid fill is enabled on plane
+ * @state: plane state
+ *
+ * Returns:
+ * Whether the plane has been assigned a solid_fill_blob
+ */
+static inline bool drm_plane_solid_fill_enabled(struct drm_plane_state *state)
+{
+	if (!state)
+		return false;
+	return state->pixel_source == DRM_PLANE_PIXEL_SOURCE_COLOR && state->solid_fill_blob;
+}
+
+static inline bool drm_plane_has_visible_data(const struct drm_plane_state *state)
+{
+	switch (state->pixel_source) {
+	case DRM_PLANE_PIXEL_SOURCE_COLOR:
+		return state->solid_fill_blob != NULL;
+
+	default:
+		return state->fb != NULL;
+	}
+
+	return false;
+}
+
+
 bool drm_any_plane_has_format(struct drm_device *dev,
 			      u32 format, u64 modifier);
 

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 4/7] drm/atomic: Loosen FB atomic checks
@ 2023-06-30  0:25   ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel, Jessica Zhang

Loosen the requirements for atomic and legacy commit so that, in cases
where solid fill planes is enabled but no FB is set, the commit can
still go through.

This includes adding framebuffer NULL checks in other areas to account
for FB being NULL when solid fill is enabled.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/drm_atomic.c        | 14 +++++++-------
 drivers/gpu/drm/drm_atomic_helper.c | 34 ++++++++++++++++++++--------------
 drivers/gpu/drm/drm_plane.c         |  8 ++++----
 include/drm/drm_atomic_helper.h     |  4 ++--
 include/drm/drm_plane.h             | 28 ++++++++++++++++++++++++++++
 5 files changed, 61 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 404b984d2d9f..ec9681c25366 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -668,14 +668,14 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 	const struct drm_framebuffer *fb = new_plane_state->fb;
 	int ret;
 
-	/* either *both* CRTC and FB must be set, or neither */
-	if (crtc && !fb) {
-		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
+	/* either *both* CRTC and pixel source must be set, or neither */
+	if (crtc && !drm_plane_has_visible_data(new_plane_state)) {
+		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no visible data\n",
 			       plane->base.id, plane->name);
 		return -EINVAL;
-	} else if (fb && !crtc) {
-		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
-			       plane->base.id, plane->name);
+	} else if (drm_plane_has_visible_data(new_plane_state) && !crtc) {
+		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] Source %d has visible data but no CRTC\n",
+			       plane->base.id, plane->name, new_plane_state->pixel_source);
 		return -EINVAL;
 	}
 
@@ -706,7 +706,7 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
 	}
 
 
-	if (fb) {
+	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
 		ret = drm_atomic_check_fb(new_plane_state);
 		if (ret)
 			return ret;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 41b8066f61ff..d05ec9ef2b3e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -864,7 +864,7 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
 	*src = drm_plane_state_src(plane_state);
 	*dst = drm_plane_state_dest(plane_state);
 
-	if (!fb) {
+	if (!drm_plane_has_visible_data(plane_state)) {
 		plane_state->visible = false;
 		return 0;
 	}
@@ -881,25 +881,31 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
 		return -EINVAL;
 	}
 
-	drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
+	if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+		drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
 
-	/* Check scaling */
-	hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
-	vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
-	if (hscale < 0 || vscale < 0) {
-		drm_dbg_kms(plane_state->plane->dev,
-			    "Invalid scaling of plane\n");
-		drm_rect_debug_print("src: ", &plane_state->src, true);
-		drm_rect_debug_print("dst: ", &plane_state->dst, false);
-		return -ERANGE;
+		/* Check scaling */
+		hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+		vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
+
+		if (hscale < 0 || vscale < 0) {
+			drm_dbg_kms(plane_state->plane->dev,
+					"Invalid scaling of plane\n");
+			drm_rect_debug_print("src: ", &plane_state->src, true);
+			drm_rect_debug_print("dst: ", &plane_state->dst, false);
+			return -ERANGE;
+		}
 	}
 
 	if (crtc_state->enable)
 		drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
 
-	plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
-
-	drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+	if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+		plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
+		drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+	} else if (drm_plane_solid_fill_enabled(plane_state)) {
+		plane_state->visible = true;
+	}
 
 	if (!plane_state->visible)
 		/*
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 24e7998d1731..5f19a27ba182 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -861,8 +861,8 @@ static int __setplane_internal(struct drm_plane *plane,
 
 	WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
 
-	/* No fb means shut it down */
-	if (!fb) {
+	/* No visible data means shut it down */
+	if (!drm_plane_has_visible_data(plane->state)) {
 		plane->old_fb = plane->fb;
 		ret = plane->funcs->disable_plane(plane, ctx);
 		if (!ret) {
@@ -913,8 +913,8 @@ static int __setplane_atomic(struct drm_plane *plane,
 
 	WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
 
-	/* No fb means shut it down */
-	if (!fb)
+	/* No visible data means shut it down */
+	if (!drm_plane_has_visible_data(plane->state))
 		return plane->funcs->disable_plane(plane, ctx);
 
 	/*
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 536a0b0091c3..6d97f38ac1f6 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -256,8 +256,8 @@ drm_atomic_plane_disabling(struct drm_plane_state *old_plane_state,
 	 * Anything else should be considered a bug in the atomic core, so we
 	 * gently warn about it.
 	 */
-	WARN_ON((new_plane_state->crtc == NULL && new_plane_state->fb != NULL) ||
-		(new_plane_state->crtc != NULL && new_plane_state->fb == NULL));
+	WARN_ON((new_plane_state->crtc == NULL && drm_plane_has_visible_data(new_plane_state)) ||
+		(new_plane_state->crtc != NULL && !drm_plane_has_visible_data(new_plane_state)));
 
 	return old_plane_state->crtc && !new_plane_state->crtc;
 }
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 73fb6cf8a5d9..f893f7a56912 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -998,6 +998,34 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
 #define drm_for_each_plane(plane, dev) \
 	list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
 
+/**
+ * drm_plane_solid_fill_enabled - Check if solid fill is enabled on plane
+ * @state: plane state
+ *
+ * Returns:
+ * Whether the plane has been assigned a solid_fill_blob
+ */
+static inline bool drm_plane_solid_fill_enabled(struct drm_plane_state *state)
+{
+	if (!state)
+		return false;
+	return state->pixel_source == DRM_PLANE_PIXEL_SOURCE_COLOR && state->solid_fill_blob;
+}
+
+static inline bool drm_plane_has_visible_data(const struct drm_plane_state *state)
+{
+	switch (state->pixel_source) {
+	case DRM_PLANE_PIXEL_SOURCE_COLOR:
+		return state->solid_fill_blob != NULL;
+
+	default:
+		return state->fb != NULL;
+	}
+
+	return false;
+}
+
+
 bool drm_any_plane_has_format(struct drm_device *dev,
 			      u32 format, u64 modifier);
 

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 5/7] drm/msm/dpu: Add solid fill and pixel source properties
  2023-06-30  0:24 ` Jessica Zhang
@ 2023-06-30  0:25   ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel, Jessica Zhang

Add solid_fill and pixel_source properties to DPU plane

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c2aaaded07ed..5f0984ce62b1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1429,6 +1429,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
 
 	drm_plane_create_alpha_property(plane);
+	drm_plane_create_solid_fill_property(plane);
+	drm_plane_create_pixel_source_property(plane, BIT(DRM_PLANE_PIXEL_SOURCE_COLOR));
 	drm_plane_create_blend_mode_property(plane,
 			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
 			BIT(DRM_MODE_BLEND_PREMULTI) |

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 5/7] drm/msm/dpu: Add solid fill and pixel source properties
@ 2023-06-30  0:25   ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, Jessica Zhang,
	wayland-devel, freedreno

Add solid_fill and pixel_source properties to DPU plane

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c2aaaded07ed..5f0984ce62b1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1429,6 +1429,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
 
 	drm_plane_create_alpha_property(plane);
+	drm_plane_create_solid_fill_property(plane);
+	drm_plane_create_pixel_source_property(plane, BIT(DRM_PLANE_PIXEL_SOURCE_COLOR));
 	drm_plane_create_blend_mode_property(plane,
 			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
 			BIT(DRM_MODE_BLEND_PREMULTI) |

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit
  2023-06-30  0:24 ` Jessica Zhang
@ 2023-06-30  0:25   ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, Jessica Zhang,
	wayland-devel, freedreno

Since solid fill planes allow for a NULL framebuffer in a valid commit,
add NULL framebuffer checks to atomic commit calls within DPU.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++++++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++++++++------------
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 1edf2b6b0a26..d1b37d2cc202 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct drm_plane_state *state;
 	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
 	struct dpu_plane_state *pstate = NULL;
+	const struct msm_format *fmt;
 	struct dpu_format *format;
 	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
 
@@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
+		if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
+			fmt = msm_framebuffer_format(pstate->base.fb);
+		else
+			fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
+					DRM_FORMAT_RGBA8888, 0);
+
+		format = to_dpu_format(fmt);
 
 		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
 			bg_alpha_enable = true;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5f0984ce62b1..4476722f03bb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	pipe_cfg->dst_rect = new_plane_state->dst;
 
-	fb_rect.x2 = new_plane_state->fb->width;
-	fb_rect.y2 = new_plane_state->fb->height;
+	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && new_plane_state->fb) {
+		fb_rect.x2 = new_plane_state->fb->width;
+		fb_rect.y2 = new_plane_state->fb->height;
+	}
 
 	/* Ensure fb size is supported */
 	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
@@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		return -E2BIG;
 	}
 
-	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
-
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
+	if (drm_plane_solid_fill_enabled(new_plane_state))
+		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
+	else
+		fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+
 	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
 		/*
 		 * In parallel multirect case only the half of the usual width
@@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	struct drm_crtc *crtc = state->crtc;
 	struct drm_framebuffer *fb = state->fb;
 	bool is_rt_pipe;
-	const struct dpu_format *fmt =
-		to_dpu_format(msm_framebuffer_format(fb));
+	const struct dpu_format *fmt;
 	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
 	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
 	struct msm_gem_address_space *aspace = kms->base.aspace;
 	struct dpu_hw_fmt_layout layout;
 	bool layout_valid = false;
-	int ret;
 
-	ret = dpu_format_populate_layout(aspace, fb, &layout);
-	if (ret)
-		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else
-		layout_valid = true;
+	if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+		int ret;
+
+		fmt = to_dpu_format(msm_framebuffer_format(fb));
+
+		ret = dpu_format_populate_layout(aspace, fb, &layout);
+		if (ret)
+			DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+		else
+			layout_valid = true;
+
+		DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
+				", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
+				crtc->base.id, DRM_RECT_ARG(&state->dst),
+				(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
+	} else {
+		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
+	}
 
 	pstate->pending = true;
 
@@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
 	pdpu->is_rt_pipe = is_rt_pipe;
 
-	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
-			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
-			crtc->base.id, DRM_RECT_ARG(&state->dst),
-			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
-
 	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
 				   drm_mode_vrefresh(&crtc->mode),
 				   layout_valid ? &layout : NULL);

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit
@ 2023-06-30  0:25   ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel, Jessica Zhang

Since solid fill planes allow for a NULL framebuffer in a valid commit,
add NULL framebuffer checks to atomic commit calls within DPU.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++++++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++++++++------------
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 1edf2b6b0a26..d1b37d2cc202 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct drm_plane_state *state;
 	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
 	struct dpu_plane_state *pstate = NULL;
+	const struct msm_format *fmt;
 	struct dpu_format *format;
 	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
 
@@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
+		if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
+			fmt = msm_framebuffer_format(pstate->base.fb);
+		else
+			fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
+					DRM_FORMAT_RGBA8888, 0);
+
+		format = to_dpu_format(fmt);
 
 		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
 			bg_alpha_enable = true;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5f0984ce62b1..4476722f03bb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	pipe_cfg->dst_rect = new_plane_state->dst;
 
-	fb_rect.x2 = new_plane_state->fb->width;
-	fb_rect.y2 = new_plane_state->fb->height;
+	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && new_plane_state->fb) {
+		fb_rect.x2 = new_plane_state->fb->width;
+		fb_rect.y2 = new_plane_state->fb->height;
+	}
 
 	/* Ensure fb size is supported */
 	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
@@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		return -E2BIG;
 	}
 
-	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
-
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
+	if (drm_plane_solid_fill_enabled(new_plane_state))
+		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
+	else
+		fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+
 	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
 		/*
 		 * In parallel multirect case only the half of the usual width
@@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	struct drm_crtc *crtc = state->crtc;
 	struct drm_framebuffer *fb = state->fb;
 	bool is_rt_pipe;
-	const struct dpu_format *fmt =
-		to_dpu_format(msm_framebuffer_format(fb));
+	const struct dpu_format *fmt;
 	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
 	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
 	struct msm_gem_address_space *aspace = kms->base.aspace;
 	struct dpu_hw_fmt_layout layout;
 	bool layout_valid = false;
-	int ret;
 
-	ret = dpu_format_populate_layout(aspace, fb, &layout);
-	if (ret)
-		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else
-		layout_valid = true;
+	if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
+		int ret;
+
+		fmt = to_dpu_format(msm_framebuffer_format(fb));
+
+		ret = dpu_format_populate_layout(aspace, fb, &layout);
+		if (ret)
+			DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+		else
+			layout_valid = true;
+
+		DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
+				", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
+				crtc->base.id, DRM_RECT_ARG(&state->dst),
+				(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
+	} else {
+		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
+	}
 
 	pstate->pending = true;
 
@@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
 	pdpu->is_rt_pipe = is_rt_pipe;
 
-	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
-			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
-			crtc->base.id, DRM_RECT_ARG(&state->dst),
-			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
-
 	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
 				   drm_mode_vrefresh(&crtc->mode),
 				   layout_valid ? &layout : NULL);

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
  2023-06-30  0:24 ` Jessica Zhang
@ 2023-06-30  0:25   ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel, Jessica Zhang

Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
determine if the plane is solid fill. In addition drop the DPU plane
color_fill field as we can now use drm_plane_state.solid_fill instead,
and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
allow userspace to configure the alpha value for the solid fill color.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 4476722f03bb..11d4fb771a1f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -42,7 +42,6 @@
 #define SHARP_SMOOTH_THR_DEFAULT	8
 #define SHARP_NOISE_THR_DEFAULT	2
 
-#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
 #define DPU_ZPOS_MAX 255
 
 /*
@@ -82,7 +81,6 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
 	const struct dpu_mdss_cfg *catalog;
@@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
 	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
 }
 
+static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
+{
+	uint32_t ret = 0;
+
+	ret |= ((uint8_t) solid_fill.b) << 16;
+	ret |= ((uint8_t) solid_fill.g) << 8;
+	ret |= ((uint8_t) solid_fill.r);
+
+	return ret;
+}
+
 /**
  * _dpu_plane_color_fill - enables color fill on plane
  * @pdpu:   Pointer to DPU plane object
@@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
 	if (pdpu->is_error)
 		/* force white frame with 100% alpha pipe output on error */
 		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
-	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
-		/* force 100% alpha */
-		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
+	else if (drm_plane_solid_fill_enabled(plane->state))
+		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
+				plane->state->alpha);
 	else {
 		dpu_plane_flush_csc(pdpu, &pstate->pipe);
 		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
@@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
 	}
 
 	/* override for color fill */
-	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
+	if (drm_plane_solid_fill_enabled(plane->state)) {
 		_dpu_plane_set_qos_ctrl(plane, pipe, false);
 
 		/* skip remaining processing on color fill */

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
@ 2023-06-30  0:25   ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30  0:25 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, Jessica Zhang,
	wayland-devel, freedreno

Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
determine if the plane is solid fill. In addition drop the DPU plane
color_fill field as we can now use drm_plane_state.solid_fill instead,
and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
allow userspace to configure the alpha value for the solid fill color.

Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 4476722f03bb..11d4fb771a1f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -42,7 +42,6 @@
 #define SHARP_SMOOTH_THR_DEFAULT	8
 #define SHARP_NOISE_THR_DEFAULT	2
 
-#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
 #define DPU_ZPOS_MAX 255
 
 /*
@@ -82,7 +81,6 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
 	const struct dpu_mdss_cfg *catalog;
@@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
 	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
 }
 
+static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
+{
+	uint32_t ret = 0;
+
+	ret |= ((uint8_t) solid_fill.b) << 16;
+	ret |= ((uint8_t) solid_fill.g) << 8;
+	ret |= ((uint8_t) solid_fill.r);
+
+	return ret;
+}
+
 /**
  * _dpu_plane_color_fill - enables color fill on plane
  * @pdpu:   Pointer to DPU plane object
@@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
 	if (pdpu->is_error)
 		/* force white frame with 100% alpha pipe output on error */
 		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
-	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
-		/* force 100% alpha */
-		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
+	else if (drm_plane_solid_fill_enabled(plane->state))
+		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
+				plane->state->alpha);
 	else {
 		dpu_plane_flush_csc(pdpu, &pstate->pipe);
 		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
@@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
 	}
 
 	/* override for color fill */
-	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
+	if (drm_plane_solid_fill_enabled(plane->state)) {
 		_dpu_plane_set_qos_ctrl(plane, pipe, false);
 
 		/* skip remaining processing on color fill */

-- 
2.41.0


^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30  0:42     ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:42 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

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.

> 
> 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.
> + *
> + *	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).

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).

> + *
> + * 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",
> +			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
> +};
> +
>   /**
>    * 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
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-06-30  0:42     ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:42 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno

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.

> 
> 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.
> + *
> + *	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).

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).

> + *
> + * 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",
> +			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
> +};
> +
>   /**
>    * 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
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 3/7] drm/atomic: Move framebuffer checks to helper
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30  0:43     ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:43 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

On 30/06/2023 03:25, Jessica Zhang wrote:
> Currently framebuffer checks happen directly in
> drm_atomic_plane_check(). Move these checks into their own helper
> method.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/drm_atomic.c | 130 ++++++++++++++++++++++++-------------------
>   1 file changed, 74 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index b4c6ffc438da..404b984d2d9f 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -580,6 +580,76 @@ plane_switching_crtc(const struct drm_plane_state *old_plane_state,
>   	return true;
>   }
>   
> +static int drm_atomic_check_fb(const struct drm_plane_state *state)
> +{
> +	struct drm_plane *plane = state->plane;
> +	const struct drm_framebuffer *fb = state->fb;
> +	struct drm_mode_rect *clips;
> +
> +	uint32_t num_clips;
> +	unsigned int fb_width, fb_height;
> +	int ret;
> +
> +	/* Check whether this plane supports the fb pixel format. */
> +	ret = drm_plane_check_pixel_format(plane, fb->format->format,
> +					   fb->modifier);
> +
> +	if (ret) {
> +		drm_dbg_atomic(plane->dev,
> +			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
> +			       plane->base.id, plane->name,
> +			       &fb->format->format, fb->modifier);
> +		return ret;
> +	}
> +
> +	fb_width = fb->width << 16;
> +	fb_height = fb->height << 16;
> +
> +	/* Make sure source coordinates are inside the fb. */
> +	if (state->src_w > fb_width ||
> +	    state->src_x > fb_width - state->src_w ||
> +	    state->src_h > fb_height ||
> +	    state->src_y > fb_height - state->src_h) {
> +		drm_dbg_atomic(plane->dev,
> +			       "[PLANE:%d:%s] invalid source coordinates "
> +			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
> +			       plane->base.id, plane->name,
> +			       state->src_w >> 16,
> +			       ((state->src_w & 0xffff) * 15625) >> 10,
> +			       state->src_h >> 16,
> +			       ((state->src_h & 0xffff) * 15625) >> 10,
> +			       state->src_x >> 16,
> +			       ((state->src_x & 0xffff) * 15625) >> 10,
> +			       state->src_y >> 16,
> +			       ((state->src_y & 0xffff) * 15625) >> 10,
> +			       fb->width, fb->height);
> +		return -ENOSPC;
> +	}
> +
> +	clips = __drm_plane_get_damage_clips(state);
> +	num_clips = drm_plane_get_damage_clips_count(state);
> +
> +	/* Make sure damage clips are valid and inside the fb. */
> +	while (num_clips > 0) {
> +		if (clips->x1 >= clips->x2 ||
> +		    clips->y1 >= clips->y2 ||
> +		    clips->x1 < 0 ||
> +		    clips->y1 < 0 ||
> +		    clips->x2 > fb_width ||
> +		    clips->y2 > fb_height) {
> +			drm_dbg_atomic(plane->dev,
> +				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
> +				       plane->base.id, plane->name, clips->x1,
> +				       clips->y1, clips->x2, clips->y2);
> +			return -EINVAL;
> +		}
> +		clips++;
> +		num_clips--;
> +	}
> +
> +	return 0;
> +}
> +
>   /**
>    * drm_atomic_plane_check - check plane state
>    * @old_plane_state: old plane state to check
> @@ -596,9 +666,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   	struct drm_plane *plane = new_plane_state->plane;
>   	struct drm_crtc *crtc = new_plane_state->crtc;
>   	const struct drm_framebuffer *fb = new_plane_state->fb;
> -	unsigned int fb_width, fb_height;
> -	struct drm_mode_rect *clips;
> -	uint32_t num_clips;
>   	int ret;
>   
>   	/* either *both* CRTC and FB must be set, or neither */
> @@ -625,17 +692,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   		return -EINVAL;
>   	}
>   
> -	/* Check whether this plane supports the fb pixel format. */
> -	ret = drm_plane_check_pixel_format(plane, fb->format->format,
> -					   fb->modifier);
> -	if (ret) {
> -		drm_dbg_atomic(plane->dev,
> -			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
> -			       plane->base.id, plane->name,
> -			       &fb->format->format, fb->modifier);
> -		return ret;
> -	}
> -
>   	/* Give drivers some help against integer overflows */
>   	if (new_plane_state->crtc_w > INT_MAX ||
>   	    new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
> @@ -649,49 +705,11 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   		return -ERANGE;
>   	}
>   
> -	fb_width = fb->width << 16;
> -	fb_height = fb->height << 16;
>   
> -	/* Make sure source coordinates are inside the fb. */
> -	if (new_plane_state->src_w > fb_width ||
> -	    new_plane_state->src_x > fb_width - new_plane_state->src_w ||
> -	    new_plane_state->src_h > fb_height ||
> -	    new_plane_state->src_y > fb_height - new_plane_state->src_h) {
> -		drm_dbg_atomic(plane->dev,
> -			       "[PLANE:%d:%s] invalid source coordinates "
> -			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
> -			       plane->base.id, plane->name,
> -			       new_plane_state->src_w >> 16,
> -			       ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
> -			       new_plane_state->src_h >> 16,
> -			       ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
> -			       new_plane_state->src_x >> 16,
> -			       ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
> -			       new_plane_state->src_y >> 16,
> -			       ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
> -			       fb->width, fb->height);
> -		return -ENOSPC;
> -	}
> -
> -	clips = __drm_plane_get_damage_clips(new_plane_state);
> -	num_clips = drm_plane_get_damage_clips_count(new_plane_state);
> -
> -	/* Make sure damage clips are valid and inside the fb. */
> -	while (num_clips > 0) {
> -		if (clips->x1 >= clips->x2 ||
> -		    clips->y1 >= clips->y2 ||
> -		    clips->x1 < 0 ||
> -		    clips->y1 < 0 ||
> -		    clips->x2 > fb_width ||
> -		    clips->y2 > fb_height) {
> -			drm_dbg_atomic(plane->dev,
> -				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
> -				       plane->base.id, plane->name, clips->x1,
> -				       clips->y1, clips->x2, clips->y2);
> -			return -EINVAL;
> -		}
> -		clips++;
> -		num_clips--;
> +	if (fb) {

This doesn't only move code, but also changes semantics, making the 
checks optional if no FB is provided. Consider moving the condition to 
the next patch. Otherwise LGTM.

> +		ret = drm_atomic_check_fb(new_plane_state);
> +		if (ret)
> +			return ret;
>   	}
>   
>   	if (plane_switching_crtc(old_plane_state, new_plane_state)) {
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 3/7] drm/atomic: Move framebuffer checks to helper
@ 2023-06-30  0:43     ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:43 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno

On 30/06/2023 03:25, Jessica Zhang wrote:
> Currently framebuffer checks happen directly in
> drm_atomic_plane_check(). Move these checks into their own helper
> method.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/drm_atomic.c | 130 ++++++++++++++++++++++++-------------------
>   1 file changed, 74 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index b4c6ffc438da..404b984d2d9f 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -580,6 +580,76 @@ plane_switching_crtc(const struct drm_plane_state *old_plane_state,
>   	return true;
>   }
>   
> +static int drm_atomic_check_fb(const struct drm_plane_state *state)
> +{
> +	struct drm_plane *plane = state->plane;
> +	const struct drm_framebuffer *fb = state->fb;
> +	struct drm_mode_rect *clips;
> +
> +	uint32_t num_clips;
> +	unsigned int fb_width, fb_height;
> +	int ret;
> +
> +	/* Check whether this plane supports the fb pixel format. */
> +	ret = drm_plane_check_pixel_format(plane, fb->format->format,
> +					   fb->modifier);
> +
> +	if (ret) {
> +		drm_dbg_atomic(plane->dev,
> +			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
> +			       plane->base.id, plane->name,
> +			       &fb->format->format, fb->modifier);
> +		return ret;
> +	}
> +
> +	fb_width = fb->width << 16;
> +	fb_height = fb->height << 16;
> +
> +	/* Make sure source coordinates are inside the fb. */
> +	if (state->src_w > fb_width ||
> +	    state->src_x > fb_width - state->src_w ||
> +	    state->src_h > fb_height ||
> +	    state->src_y > fb_height - state->src_h) {
> +		drm_dbg_atomic(plane->dev,
> +			       "[PLANE:%d:%s] invalid source coordinates "
> +			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
> +			       plane->base.id, plane->name,
> +			       state->src_w >> 16,
> +			       ((state->src_w & 0xffff) * 15625) >> 10,
> +			       state->src_h >> 16,
> +			       ((state->src_h & 0xffff) * 15625) >> 10,
> +			       state->src_x >> 16,
> +			       ((state->src_x & 0xffff) * 15625) >> 10,
> +			       state->src_y >> 16,
> +			       ((state->src_y & 0xffff) * 15625) >> 10,
> +			       fb->width, fb->height);
> +		return -ENOSPC;
> +	}
> +
> +	clips = __drm_plane_get_damage_clips(state);
> +	num_clips = drm_plane_get_damage_clips_count(state);
> +
> +	/* Make sure damage clips are valid and inside the fb. */
> +	while (num_clips > 0) {
> +		if (clips->x1 >= clips->x2 ||
> +		    clips->y1 >= clips->y2 ||
> +		    clips->x1 < 0 ||
> +		    clips->y1 < 0 ||
> +		    clips->x2 > fb_width ||
> +		    clips->y2 > fb_height) {
> +			drm_dbg_atomic(plane->dev,
> +				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
> +				       plane->base.id, plane->name, clips->x1,
> +				       clips->y1, clips->x2, clips->y2);
> +			return -EINVAL;
> +		}
> +		clips++;
> +		num_clips--;
> +	}
> +
> +	return 0;
> +}
> +
>   /**
>    * drm_atomic_plane_check - check plane state
>    * @old_plane_state: old plane state to check
> @@ -596,9 +666,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   	struct drm_plane *plane = new_plane_state->plane;
>   	struct drm_crtc *crtc = new_plane_state->crtc;
>   	const struct drm_framebuffer *fb = new_plane_state->fb;
> -	unsigned int fb_width, fb_height;
> -	struct drm_mode_rect *clips;
> -	uint32_t num_clips;
>   	int ret;
>   
>   	/* either *both* CRTC and FB must be set, or neither */
> @@ -625,17 +692,6 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   		return -EINVAL;
>   	}
>   
> -	/* Check whether this plane supports the fb pixel format. */
> -	ret = drm_plane_check_pixel_format(plane, fb->format->format,
> -					   fb->modifier);
> -	if (ret) {
> -		drm_dbg_atomic(plane->dev,
> -			       "[PLANE:%d:%s] invalid pixel format %p4cc, modifier 0x%llx\n",
> -			       plane->base.id, plane->name,
> -			       &fb->format->format, fb->modifier);
> -		return ret;
> -	}
> -
>   	/* Give drivers some help against integer overflows */
>   	if (new_plane_state->crtc_w > INT_MAX ||
>   	    new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
> @@ -649,49 +705,11 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   		return -ERANGE;
>   	}
>   
> -	fb_width = fb->width << 16;
> -	fb_height = fb->height << 16;
>   
> -	/* Make sure source coordinates are inside the fb. */
> -	if (new_plane_state->src_w > fb_width ||
> -	    new_plane_state->src_x > fb_width - new_plane_state->src_w ||
> -	    new_plane_state->src_h > fb_height ||
> -	    new_plane_state->src_y > fb_height - new_plane_state->src_h) {
> -		drm_dbg_atomic(plane->dev,
> -			       "[PLANE:%d:%s] invalid source coordinates "
> -			       "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
> -			       plane->base.id, plane->name,
> -			       new_plane_state->src_w >> 16,
> -			       ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
> -			       new_plane_state->src_h >> 16,
> -			       ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
> -			       new_plane_state->src_x >> 16,
> -			       ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
> -			       new_plane_state->src_y >> 16,
> -			       ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
> -			       fb->width, fb->height);
> -		return -ENOSPC;
> -	}
> -
> -	clips = __drm_plane_get_damage_clips(new_plane_state);
> -	num_clips = drm_plane_get_damage_clips_count(new_plane_state);
> -
> -	/* Make sure damage clips are valid and inside the fb. */
> -	while (num_clips > 0) {
> -		if (clips->x1 >= clips->x2 ||
> -		    clips->y1 >= clips->y2 ||
> -		    clips->x1 < 0 ||
> -		    clips->y1 < 0 ||
> -		    clips->x2 > fb_width ||
> -		    clips->y2 > fb_height) {
> -			drm_dbg_atomic(plane->dev,
> -				       "[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
> -				       plane->base.id, plane->name, clips->x1,
> -				       clips->y1, clips->x2, clips->y2);
> -			return -EINVAL;
> -		}
> -		clips++;
> -		num_clips--;
> +	if (fb) {

This doesn't only move code, but also changes semantics, making the 
checks optional if no FB is provided. Consider moving the condition to 
the next patch. Otherwise LGTM.

> +		ret = drm_atomic_check_fb(new_plane_state);
> +		if (ret)
> +			return ret;
>   	}
>   
>   	if (plane_switching_crtc(old_plane_state, new_plane_state)) {
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 4/7] drm/atomic: Loosen FB atomic checks
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30  0:48     ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:48 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno

On 30/06/2023 03:25, Jessica Zhang wrote:
> Loosen the requirements for atomic and legacy commit so that, in cases
> where solid fill planes is enabled but no FB is set, the commit can
> still go through.
> 
> This includes adding framebuffer NULL checks in other areas to account
> for FB being NULL when solid fill is enabled.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/drm_atomic.c        | 14 +++++++-------
>   drivers/gpu/drm/drm_atomic_helper.c | 34 ++++++++++++++++++++--------------
>   drivers/gpu/drm/drm_plane.c         |  8 ++++----
>   include/drm/drm_atomic_helper.h     |  4 ++--
>   include/drm/drm_plane.h             | 28 ++++++++++++++++++++++++++++
>   5 files changed, 61 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 404b984d2d9f..ec9681c25366 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -668,14 +668,14 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   	const struct drm_framebuffer *fb = new_plane_state->fb;
>   	int ret;
>   
> -	/* either *both* CRTC and FB must be set, or neither */
> -	if (crtc && !fb) {
> -		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
> +	/* either *both* CRTC and pixel source must be set, or neither */
> +	if (crtc && !drm_plane_has_visible_data(new_plane_state)) {
> +		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no visible data\n",
>   			       plane->base.id, plane->name);
>   		return -EINVAL;
> -	} else if (fb && !crtc) {
> -		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
> -			       plane->base.id, plane->name);
> +	} else if (drm_plane_has_visible_data(new_plane_state) && !crtc) {
> +		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] Source %d has visible data but no CRTC\n",
> +			       plane->base.id, plane->name, new_plane_state->pixel_source);
>   		return -EINVAL;
>   	}
>   
> @@ -706,7 +706,7 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   	}
>   
>   
> -	if (fb) {
> +	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
>   		ret = drm_atomic_check_fb(new_plane_state);
>   		if (ret)
>   			return ret;
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 41b8066f61ff..d05ec9ef2b3e 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -864,7 +864,7 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
>   	*src = drm_plane_state_src(plane_state);
>   	*dst = drm_plane_state_dest(plane_state);
>   
> -	if (!fb) {
> +	if (!drm_plane_has_visible_data(plane_state)) {
>   		plane_state->visible = false;
>   		return 0;
>   	}
> @@ -881,25 +881,31 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
>   		return -EINVAL;
>   	}
>   
> -	drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
> +	if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> +		drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
>   
> -	/* Check scaling */
> -	hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
> -	vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
> -	if (hscale < 0 || vscale < 0) {
> -		drm_dbg_kms(plane_state->plane->dev,
> -			    "Invalid scaling of plane\n");
> -		drm_rect_debug_print("src: ", &plane_state->src, true);
> -		drm_rect_debug_print("dst: ", &plane_state->dst, false);
> -		return -ERANGE;
> +		/* Check scaling */
> +		hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
> +		vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
> +
> +		if (hscale < 0 || vscale < 0) {
> +			drm_dbg_kms(plane_state->plane->dev,
> +					"Invalid scaling of plane\n");
> +			drm_rect_debug_print("src: ", &plane_state->src, true);
> +			drm_rect_debug_print("dst: ", &plane_state->dst, false);
> +			return -ERANGE;
> +		}
>   	}
>   
>   	if (crtc_state->enable)
>   		drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
>   
> -	plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
> -
> -	drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
> +	if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> +		plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
> +		drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
> +	} else if (drm_plane_solid_fill_enabled(plane_state)) {
> +		plane_state->visible = true;
> +	}
>   
>   	if (!plane_state->visible)
>   		/*
> diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
> index 24e7998d1731..5f19a27ba182 100644
> --- a/drivers/gpu/drm/drm_plane.c
> +++ b/drivers/gpu/drm/drm_plane.c
> @@ -861,8 +861,8 @@ static int __setplane_internal(struct drm_plane *plane,
>   
>   	WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
>   
> -	/* No fb means shut it down */
> -	if (!fb) {
> +	/* No visible data means shut it down */
> +	if (!drm_plane_has_visible_data(plane->state)) {
>   		plane->old_fb = plane->fb;
>   		ret = plane->funcs->disable_plane(plane, ctx);
>   		if (!ret) {
> @@ -913,8 +913,8 @@ static int __setplane_atomic(struct drm_plane *plane,
>   
>   	WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
>   
> -	/* No fb means shut it down */
> -	if (!fb)
> +	/* No visible data means shut it down */
> +	if (!drm_plane_has_visible_data(plane->state))
>   		return plane->funcs->disable_plane(plane, ctx);
>   
>   	/*
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index 536a0b0091c3..6d97f38ac1f6 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -256,8 +256,8 @@ drm_atomic_plane_disabling(struct drm_plane_state *old_plane_state,
>   	 * Anything else should be considered a bug in the atomic core, so we
>   	 * gently warn about it.
>   	 */
> -	WARN_ON((new_plane_state->crtc == NULL && new_plane_state->fb != NULL) ||
> -		(new_plane_state->crtc != NULL && new_plane_state->fb == NULL));
> +	WARN_ON((new_plane_state->crtc == NULL && drm_plane_has_visible_data(new_plane_state)) ||
> +		(new_plane_state->crtc != NULL && !drm_plane_has_visible_data(new_plane_state)));
>   
>   	return old_plane_state->crtc && !new_plane_state->crtc;
>   }
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index 73fb6cf8a5d9..f893f7a56912 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -998,6 +998,34 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
>   #define drm_for_each_plane(plane, dev) \
>   	list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
>   
> +/**
> + * drm_plane_solid_fill_enabled - Check if solid fill is enabled on plane
> + * @state: plane state
> + *
> + * Returns:
> + * Whether the plane has been assigned a solid_fill_blob
> + */
> +static inline bool drm_plane_solid_fill_enabled(struct drm_plane_state *state)
> +{
> +	if (!state)
> +		return false;
> +	return state->pixel_source == DRM_PLANE_PIXEL_SOURCE_COLOR && state->solid_fill_blob;
> +}
> +
> +static inline bool drm_plane_has_visible_data(const struct drm_plane_state *state)
> +{
> +	switch (state->pixel_source) {
> +	case DRM_PLANE_PIXEL_SOURCE_COLOR:
> +		return state->solid_fill_blob != NULL;
> +
> +	default:

I'd say, there should a WARN_ON for the default case and then 
fallthrough to the FB case.

> +		return state->fb != NULL;
> +	}
> +
> +	return false;
> +}
> +
> +
>   bool drm_any_plane_has_format(struct drm_device *dev,
>   			      u32 format, u64 modifier);
>   
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 4/7] drm/atomic: Loosen FB atomic checks
@ 2023-06-30  0:48     ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:48 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

On 30/06/2023 03:25, Jessica Zhang wrote:
> Loosen the requirements for atomic and legacy commit so that, in cases
> where solid fill planes is enabled but no FB is set, the commit can
> still go through.
> 
> This includes adding framebuffer NULL checks in other areas to account
> for FB being NULL when solid fill is enabled.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/drm_atomic.c        | 14 +++++++-------
>   drivers/gpu/drm/drm_atomic_helper.c | 34 ++++++++++++++++++++--------------
>   drivers/gpu/drm/drm_plane.c         |  8 ++++----
>   include/drm/drm_atomic_helper.h     |  4 ++--
>   include/drm/drm_plane.h             | 28 ++++++++++++++++++++++++++++
>   5 files changed, 61 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 404b984d2d9f..ec9681c25366 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -668,14 +668,14 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   	const struct drm_framebuffer *fb = new_plane_state->fb;
>   	int ret;
>   
> -	/* either *both* CRTC and FB must be set, or neither */
> -	if (crtc && !fb) {
> -		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
> +	/* either *both* CRTC and pixel source must be set, or neither */
> +	if (crtc && !drm_plane_has_visible_data(new_plane_state)) {
> +		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no visible data\n",
>   			       plane->base.id, plane->name);
>   		return -EINVAL;
> -	} else if (fb && !crtc) {
> -		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
> -			       plane->base.id, plane->name);
> +	} else if (drm_plane_has_visible_data(new_plane_state) && !crtc) {
> +		drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] Source %d has visible data but no CRTC\n",
> +			       plane->base.id, plane->name, new_plane_state->pixel_source);
>   		return -EINVAL;
>   	}
>   
> @@ -706,7 +706,7 @@ static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
>   	}
>   
>   
> -	if (fb) {
> +	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
>   		ret = drm_atomic_check_fb(new_plane_state);
>   		if (ret)
>   			return ret;
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 41b8066f61ff..d05ec9ef2b3e 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -864,7 +864,7 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
>   	*src = drm_plane_state_src(plane_state);
>   	*dst = drm_plane_state_dest(plane_state);
>   
> -	if (!fb) {
> +	if (!drm_plane_has_visible_data(plane_state)) {
>   		plane_state->visible = false;
>   		return 0;
>   	}
> @@ -881,25 +881,31 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
>   		return -EINVAL;
>   	}
>   
> -	drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
> +	if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> +		drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
>   
> -	/* Check scaling */
> -	hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
> -	vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
> -	if (hscale < 0 || vscale < 0) {
> -		drm_dbg_kms(plane_state->plane->dev,
> -			    "Invalid scaling of plane\n");
> -		drm_rect_debug_print("src: ", &plane_state->src, true);
> -		drm_rect_debug_print("dst: ", &plane_state->dst, false);
> -		return -ERANGE;
> +		/* Check scaling */
> +		hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
> +		vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
> +
> +		if (hscale < 0 || vscale < 0) {
> +			drm_dbg_kms(plane_state->plane->dev,
> +					"Invalid scaling of plane\n");
> +			drm_rect_debug_print("src: ", &plane_state->src, true);
> +			drm_rect_debug_print("dst: ", &plane_state->dst, false);
> +			return -ERANGE;
> +		}
>   	}
>   
>   	if (crtc_state->enable)
>   		drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
>   
> -	plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
> -
> -	drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
> +	if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> +		plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
> +		drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
> +	} else if (drm_plane_solid_fill_enabled(plane_state)) {
> +		plane_state->visible = true;
> +	}
>   
>   	if (!plane_state->visible)
>   		/*
> diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
> index 24e7998d1731..5f19a27ba182 100644
> --- a/drivers/gpu/drm/drm_plane.c
> +++ b/drivers/gpu/drm/drm_plane.c
> @@ -861,8 +861,8 @@ static int __setplane_internal(struct drm_plane *plane,
>   
>   	WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
>   
> -	/* No fb means shut it down */
> -	if (!fb) {
> +	/* No visible data means shut it down */
> +	if (!drm_plane_has_visible_data(plane->state)) {
>   		plane->old_fb = plane->fb;
>   		ret = plane->funcs->disable_plane(plane, ctx);
>   		if (!ret) {
> @@ -913,8 +913,8 @@ static int __setplane_atomic(struct drm_plane *plane,
>   
>   	WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
>   
> -	/* No fb means shut it down */
> -	if (!fb)
> +	/* No visible data means shut it down */
> +	if (!drm_plane_has_visible_data(plane->state))
>   		return plane->funcs->disable_plane(plane, ctx);
>   
>   	/*
> diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
> index 536a0b0091c3..6d97f38ac1f6 100644
> --- a/include/drm/drm_atomic_helper.h
> +++ b/include/drm/drm_atomic_helper.h
> @@ -256,8 +256,8 @@ drm_atomic_plane_disabling(struct drm_plane_state *old_plane_state,
>   	 * Anything else should be considered a bug in the atomic core, so we
>   	 * gently warn about it.
>   	 */
> -	WARN_ON((new_plane_state->crtc == NULL && new_plane_state->fb != NULL) ||
> -		(new_plane_state->crtc != NULL && new_plane_state->fb == NULL));
> +	WARN_ON((new_plane_state->crtc == NULL && drm_plane_has_visible_data(new_plane_state)) ||
> +		(new_plane_state->crtc != NULL && !drm_plane_has_visible_data(new_plane_state)));
>   
>   	return old_plane_state->crtc && !new_plane_state->crtc;
>   }
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index 73fb6cf8a5d9..f893f7a56912 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -998,6 +998,34 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev,
>   #define drm_for_each_plane(plane, dev) \
>   	list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
>   
> +/**
> + * drm_plane_solid_fill_enabled - Check if solid fill is enabled on plane
> + * @state: plane state
> + *
> + * Returns:
> + * Whether the plane has been assigned a solid_fill_blob
> + */
> +static inline bool drm_plane_solid_fill_enabled(struct drm_plane_state *state)
> +{
> +	if (!state)
> +		return false;
> +	return state->pixel_source == DRM_PLANE_PIXEL_SOURCE_COLOR && state->solid_fill_blob;
> +}
> +
> +static inline bool drm_plane_has_visible_data(const struct drm_plane_state *state)
> +{
> +	switch (state->pixel_source) {
> +	case DRM_PLANE_PIXEL_SOURCE_COLOR:
> +		return state->solid_fill_blob != NULL;
> +
> +	default:

I'd say, there should a WARN_ON for the default case and then 
fallthrough to the FB case.

> +		return state->fb != NULL;
> +	}
> +
> +	return false;
> +}
> +
> +
>   bool drm_any_plane_has_format(struct drm_device *dev,
>   			      u32 format, u64 modifier);
>   
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 5/7] drm/msm/dpu: Add solid fill and pixel source properties
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30  0:49     ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:49 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

On 30/06/2023 03:25, Jessica Zhang wrote:
> Add solid_fill and pixel_source properties to DPU plane
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 ++
>   1 file changed, 2 insertions(+)

This should be the last commit.
Otherwise:

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index c2aaaded07ed..5f0984ce62b1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1429,6 +1429,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
>   
>   	drm_plane_create_alpha_property(plane);
> +	drm_plane_create_solid_fill_property(plane);
> +	drm_plane_create_pixel_source_property(plane, BIT(DRM_PLANE_PIXEL_SOURCE_COLOR));
>   	drm_plane_create_blend_mode_property(plane,
>   			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
>   			BIT(DRM_MODE_BLEND_PREMULTI) |
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 5/7] drm/msm/dpu: Add solid fill and pixel source properties
@ 2023-06-30  0:49     ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:49 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno

On 30/06/2023 03:25, Jessica Zhang wrote:
> Add solid_fill and pixel_source properties to DPU plane
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 ++
>   1 file changed, 2 insertions(+)

This should be the last commit.
Otherwise:

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index c2aaaded07ed..5f0984ce62b1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1429,6 +1429,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
>   
>   	drm_plane_create_alpha_property(plane);
> +	drm_plane_create_solid_fill_property(plane);
> +	drm_plane_create_pixel_source_property(plane, BIT(DRM_PLANE_PIXEL_SOURCE_COLOR));
>   	drm_plane_create_blend_mode_property(plane,
>   			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
>   			BIT(DRM_MODE_BLEND_PREMULTI) |
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30  0:52     ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:52 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

On 30/06/2023 03:25, Jessica Zhang wrote:
> Since solid fill planes allow for a NULL framebuffer in a valid commit,
> add NULL framebuffer checks to atomic commit calls within DPU.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++++++-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++++++++------------
>   2 files changed, 36 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 1edf2b6b0a26..d1b37d2cc202 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   	struct drm_plane_state *state;
>   	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
>   	struct dpu_plane_state *pstate = NULL;
> +	const struct msm_format *fmt;
>   	struct dpu_format *format;
>   	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>   
> @@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		pstate = to_dpu_plane_state(state);
>   		fb = state->fb;
>   
> -		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
> +		if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
> +			fmt = msm_framebuffer_format(pstate->base.fb);
> +		else
> +			fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
> +					DRM_FORMAT_RGBA8888, 0);

The DRM_FORMAT_RGBA8888 should be defined somewhere in patch 1 as format 
for the solid_fill, then that define can be used in this patch.

> +
> +		format = to_dpu_format(fmt);
>   
>   		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
>   			bg_alpha_enable = true;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 5f0984ce62b1..4476722f03bb 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   
>   	pipe_cfg->dst_rect = new_plane_state->dst;
>   
> -	fb_rect.x2 = new_plane_state->fb->width;
> -	fb_rect.y2 = new_plane_state->fb->height;
> +	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && new_plane_state->fb) {
> +		fb_rect.x2 = new_plane_state->fb->width;
> +		fb_rect.y2 = new_plane_state->fb->height;
> +	}
>   
>   	/* Ensure fb size is supported */
>   	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
> @@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   		return -E2BIG;
>   	}
>   
> -	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> -
>   	max_linewidth = pdpu->catalog->caps->max_linewidth;
>   
> +	if (drm_plane_solid_fill_enabled(new_plane_state))
> +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> +	else
> +		fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> +
>   	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
>   		/*
>   		 * In parallel multirect case only the half of the usual width
> @@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	struct drm_crtc *crtc = state->crtc;
>   	struct drm_framebuffer *fb = state->fb;
>   	bool is_rt_pipe;
> -	const struct dpu_format *fmt =
> -		to_dpu_format(msm_framebuffer_format(fb));
> +	const struct dpu_format *fmt;
>   	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
>   	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>   	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>   	struct msm_gem_address_space *aspace = kms->base.aspace;
>   	struct dpu_hw_fmt_layout layout;
>   	bool layout_valid = false;
> -	int ret;
>   
> -	ret = dpu_format_populate_layout(aspace, fb, &layout);
> -	if (ret)
> -		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> -	else
> -		layout_valid = true;
> +	if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> +		int ret;
> +
> +		fmt = to_dpu_format(msm_framebuffer_format(fb));
> +
> +		ret = dpu_format_populate_layout(aspace, fb, &layout);
> +		if (ret)
> +			DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> +		else
> +			layout_valid = true;
> +
> +		DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
> +				", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
> +				crtc->base.id, DRM_RECT_ARG(&state->dst),
> +				(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
> +	} else {
> +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> +	}
>   
>   	pstate->pending = true;
>   
> @@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>   	pdpu->is_rt_pipe = is_rt_pipe;
>   
> -	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
> -			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
> -			crtc->base.id, DRM_RECT_ARG(&state->dst),
> -			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
> -
>   	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
>   				   drm_mode_vrefresh(&crtc->mode),
>   				   layout_valid ? &layout : NULL);
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit
@ 2023-06-30  0:52     ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:52 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno

On 30/06/2023 03:25, Jessica Zhang wrote:
> Since solid fill planes allow for a NULL framebuffer in a valid commit,
> add NULL framebuffer checks to atomic commit calls within DPU.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++++++-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++++++++------------
>   2 files changed, 36 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 1edf2b6b0a26..d1b37d2cc202 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   	struct drm_plane_state *state;
>   	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
>   	struct dpu_plane_state *pstate = NULL;
> +	const struct msm_format *fmt;
>   	struct dpu_format *format;
>   	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>   
> @@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		pstate = to_dpu_plane_state(state);
>   		fb = state->fb;
>   
> -		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
> +		if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
> +			fmt = msm_framebuffer_format(pstate->base.fb);
> +		else
> +			fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
> +					DRM_FORMAT_RGBA8888, 0);

The DRM_FORMAT_RGBA8888 should be defined somewhere in patch 1 as format 
for the solid_fill, then that define can be used in this patch.

> +
> +		format = to_dpu_format(fmt);
>   
>   		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
>   			bg_alpha_enable = true;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 5f0984ce62b1..4476722f03bb 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   
>   	pipe_cfg->dst_rect = new_plane_state->dst;
>   
> -	fb_rect.x2 = new_plane_state->fb->width;
> -	fb_rect.y2 = new_plane_state->fb->height;
> +	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && new_plane_state->fb) {
> +		fb_rect.x2 = new_plane_state->fb->width;
> +		fb_rect.y2 = new_plane_state->fb->height;
> +	}
>   
>   	/* Ensure fb size is supported */
>   	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
> @@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   		return -E2BIG;
>   	}
>   
> -	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> -
>   	max_linewidth = pdpu->catalog->caps->max_linewidth;
>   
> +	if (drm_plane_solid_fill_enabled(new_plane_state))
> +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> +	else
> +		fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> +
>   	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
>   		/*
>   		 * In parallel multirect case only the half of the usual width
> @@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	struct drm_crtc *crtc = state->crtc;
>   	struct drm_framebuffer *fb = state->fb;
>   	bool is_rt_pipe;
> -	const struct dpu_format *fmt =
> -		to_dpu_format(msm_framebuffer_format(fb));
> +	const struct dpu_format *fmt;
>   	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
>   	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>   	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>   	struct msm_gem_address_space *aspace = kms->base.aspace;
>   	struct dpu_hw_fmt_layout layout;
>   	bool layout_valid = false;
> -	int ret;
>   
> -	ret = dpu_format_populate_layout(aspace, fb, &layout);
> -	if (ret)
> -		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> -	else
> -		layout_valid = true;
> +	if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> +		int ret;
> +
> +		fmt = to_dpu_format(msm_framebuffer_format(fb));
> +
> +		ret = dpu_format_populate_layout(aspace, fb, &layout);
> +		if (ret)
> +			DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> +		else
> +			layout_valid = true;
> +
> +		DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
> +				", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
> +				crtc->base.id, DRM_RECT_ARG(&state->dst),
> +				(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
> +	} else {
> +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> +	}
>   
>   	pstate->pending = true;
>   
> @@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>   	pdpu->is_rt_pipe = is_rt_pipe;
>   
> -	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
> -			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
> -			crtc->base.id, DRM_RECT_ARG(&state->dst),
> -			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
> -
>   	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
>   				   drm_mode_vrefresh(&crtc->mode),
>   				   layout_valid ? &layout : NULL);
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30  0:59     ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:59 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

On 30/06/2023 03:25, Jessica Zhang wrote:
> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
> determine if the plane is solid fill. In addition drop the DPU plane
> color_fill field as we can now use drm_plane_state.solid_fill instead,
> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
> allow userspace to configure the alpha value for the solid fill color.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Minor suggestion below.

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
>   1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 4476722f03bb..11d4fb771a1f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -42,7 +42,6 @@
>   #define SHARP_SMOOTH_THR_DEFAULT	8
>   #define SHARP_NOISE_THR_DEFAULT	2
>   
> -#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
>   #define DPU_ZPOS_MAX 255
>   
>   /*
> @@ -82,7 +81,6 @@ struct dpu_plane {
>   
>   	enum dpu_sspp pipe;
>   
> -	uint32_t color_fill;
>   	bool is_error;
>   	bool is_rt_pipe;
>   	const struct dpu_mdss_cfg *catalog;
> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>   	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
>   }
>   
> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)

Please consider accepting drm_plane_state instead and handling alpha 
here. Then _dpu_color_fill can accept rgba colour instead of separate 
RGB and alpha values.

> +{
> +	uint32_t ret = 0;
> +
> +	ret |= ((uint8_t) solid_fill.b) << 16;
> +	ret |= ((uint8_t) solid_fill.g) << 8;
> +	ret |= ((uint8_t) solid_fill.r);
> +
> +	return ret;
> +}
> +
>   /**
>    * _dpu_plane_color_fill - enables color fill on plane
>    * @pdpu:   Pointer to DPU plane object
> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>   	if (pdpu->is_error)
>   		/* force white frame with 100% alpha pipe output on error */
>   		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
> -	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
> -		/* force 100% alpha */
> -		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> +	else if (drm_plane_solid_fill_enabled(plane->state))
> +		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
> +				plane->state->alpha);
>   	else {
>   		dpu_plane_flush_csc(pdpu, &pstate->pipe);
>   		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>   	}
>   
>   	/* override for color fill */
> -	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
> +	if (drm_plane_solid_fill_enabled(plane->state)) {
>   		_dpu_plane_set_qos_ctrl(plane, pipe, false);
>   
>   		/* skip remaining processing on color fill */
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
@ 2023-06-30  0:59     ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30  0:59 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno

On 30/06/2023 03:25, Jessica Zhang wrote:
> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
> determine if the plane is solid fill. In addition drop the DPU plane
> color_fill field as we can now use drm_plane_state.solid_fill instead,
> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
> allow userspace to configure the alpha value for the solid fill color.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Minor suggestion below.

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
>   1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 4476722f03bb..11d4fb771a1f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -42,7 +42,6 @@
>   #define SHARP_SMOOTH_THR_DEFAULT	8
>   #define SHARP_NOISE_THR_DEFAULT	2
>   
> -#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
>   #define DPU_ZPOS_MAX 255
>   
>   /*
> @@ -82,7 +81,6 @@ struct dpu_plane {
>   
>   	enum dpu_sspp pipe;
>   
> -	uint32_t color_fill;
>   	bool is_error;
>   	bool is_rt_pipe;
>   	const struct dpu_mdss_cfg *catalog;
> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>   	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
>   }
>   
> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)

Please consider accepting drm_plane_state instead and handling alpha 
here. Then _dpu_color_fill can accept rgba colour instead of separate 
RGB and alpha values.

> +{
> +	uint32_t ret = 0;
> +
> +	ret |= ((uint8_t) solid_fill.b) << 16;
> +	ret |= ((uint8_t) solid_fill.g) << 8;
> +	ret |= ((uint8_t) solid_fill.r);
> +
> +	return ret;
> +}
> +
>   /**
>    * _dpu_plane_color_fill - enables color fill on plane
>    * @pdpu:   Pointer to DPU plane object
> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>   	if (pdpu->is_error)
>   		/* force white frame with 100% alpha pipe output on error */
>   		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
> -	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
> -		/* force 100% alpha */
> -		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> +	else if (drm_plane_solid_fill_enabled(plane->state))
> +		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
> +				plane->state->alpha);
>   	else {
>   		dpu_plane_flush_csc(pdpu, &pstate->pipe);
>   		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>   	}
>   
>   	/* override for color fill */
> -	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
> +	if (drm_plane_solid_fill_enabled(plane->state)) {
>   		_dpu_plane_set_qos_ctrl(plane, pipe, false);
>   
>   		/* skip remaining processing on color fill */
> 

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit
  2023-06-30  0:52     ` Dmitry Baryshkov
@ 2023-06-30  8:21       ` Pekka Paalanen
  -1 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-06-30  8:21 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten, quic_abhinavk, contact,
	laurent.pinchart, sebastian.wick, ville.syrjala, dri-devel,
	linux-kernel, linux-arm-msm, freedreno, wayland-devel

[-- Attachment #1: Type: text/plain, Size: 5945 bytes --]

On Fri, 30 Jun 2023 03:52:37 +0300
Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:

> On 30/06/2023 03:25, Jessica Zhang wrote:
> > Since solid fill planes allow for a NULL framebuffer in a valid commit,
> > add NULL framebuffer checks to atomic commit calls within DPU.
> > 
> > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++++++-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++++++++------------
> >   2 files changed, 36 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 1edf2b6b0a26..d1b37d2cc202 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >   	struct drm_plane_state *state;
> >   	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
> >   	struct dpu_plane_state *pstate = NULL;
> > +	const struct msm_format *fmt;
> >   	struct dpu_format *format;
> >   	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
> >   
> > @@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >   		pstate = to_dpu_plane_state(state);
> >   		fb = state->fb;
> >   
> > -		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
> > +		if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
> > +			fmt = msm_framebuffer_format(pstate->base.fb);
> > +		else
> > +			fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
> > +					DRM_FORMAT_RGBA8888, 0);  
> 
> The DRM_FORMAT_RGBA8888 should be defined somewhere in patch 1 as format 
> for the solid_fill, then that define can be used in this patch.

Isn't this just a driver-specific decision to convert a RGB323232
solid_fill to be presented as a RGBA8888?

Though, below there is ABGR8888 used for something... inconsistent?


Thanks,
pq

> 
> > +
> > +		format = to_dpu_format(fmt);
> >   
> >   		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
> >   			bg_alpha_enable = true;
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 5f0984ce62b1..4476722f03bb 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >   
> >   	pipe_cfg->dst_rect = new_plane_state->dst;
> >   
> > -	fb_rect.x2 = new_plane_state->fb->width;
> > -	fb_rect.y2 = new_plane_state->fb->height;
> > +	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && new_plane_state->fb) {
> > +		fb_rect.x2 = new_plane_state->fb->width;
> > +		fb_rect.y2 = new_plane_state->fb->height;
> > +	}
> >   
> >   	/* Ensure fb size is supported */
> >   	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
> > @@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >   		return -E2BIG;
> >   	}
> >   
> > -	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> > -
> >   	max_linewidth = pdpu->catalog->caps->max_linewidth;
> >   
> > +	if (drm_plane_solid_fill_enabled(new_plane_state))
> > +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> > +	else
> > +		fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> > +
> >   	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
> >   		/*
> >   		 * In parallel multirect case only the half of the usual width
> > @@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
> >   	struct drm_crtc *crtc = state->crtc;
> >   	struct drm_framebuffer *fb = state->fb;
> >   	bool is_rt_pipe;
> > -	const struct dpu_format *fmt =
> > -		to_dpu_format(msm_framebuffer_format(fb));
> > +	const struct dpu_format *fmt;
> >   	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> >   	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >   	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> >   	struct msm_gem_address_space *aspace = kms->base.aspace;
> >   	struct dpu_hw_fmt_layout layout;
> >   	bool layout_valid = false;
> > -	int ret;
> >   
> > -	ret = dpu_format_populate_layout(aspace, fb, &layout);
> > -	if (ret)
> > -		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> > -	else
> > -		layout_valid = true;
> > +	if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> > +		int ret;
> > +
> > +		fmt = to_dpu_format(msm_framebuffer_format(fb));
> > +
> > +		ret = dpu_format_populate_layout(aspace, fb, &layout);
> > +		if (ret)
> > +			DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> > +		else
> > +			layout_valid = true;
> > +
> > +		DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
> > +				", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
> > +				crtc->base.id, DRM_RECT_ARG(&state->dst),
> > +				(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
> > +	} else {
> > +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> > +	}
> >   
> >   	pstate->pending = true;
> >   
> > @@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
> >   	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
> >   	pdpu->is_rt_pipe = is_rt_pipe;
> >   
> > -	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
> > -			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
> > -			crtc->base.id, DRM_RECT_ARG(&state->dst),
> > -			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
> > -
> >   	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
> >   				   drm_mode_vrefresh(&crtc->mode),
> >   				   layout_valid ? &layout : NULL);
> >   
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit
@ 2023-06-30  8:21       ` Pekka Paalanen
  0 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-06-30  8:21 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	wayland-devel, laurent.pinchart, Marijn Suijten, Jessica Zhang

[-- Attachment #1: Type: text/plain, Size: 5945 bytes --]

On Fri, 30 Jun 2023 03:52:37 +0300
Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:

> On 30/06/2023 03:25, Jessica Zhang wrote:
> > Since solid fill planes allow for a NULL framebuffer in a valid commit,
> > add NULL framebuffer checks to atomic commit calls within DPU.
> > 
> > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++++++-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++++++++------------
> >   2 files changed, 36 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 1edf2b6b0a26..d1b37d2cc202 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >   	struct drm_plane_state *state;
> >   	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
> >   	struct dpu_plane_state *pstate = NULL;
> > +	const struct msm_format *fmt;
> >   	struct dpu_format *format;
> >   	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
> >   
> > @@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >   		pstate = to_dpu_plane_state(state);
> >   		fb = state->fb;
> >   
> > -		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
> > +		if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
> > +			fmt = msm_framebuffer_format(pstate->base.fb);
> > +		else
> > +			fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
> > +					DRM_FORMAT_RGBA8888, 0);  
> 
> The DRM_FORMAT_RGBA8888 should be defined somewhere in patch 1 as format 
> for the solid_fill, then that define can be used in this patch.

Isn't this just a driver-specific decision to convert a RGB323232
solid_fill to be presented as a RGBA8888?

Though, below there is ABGR8888 used for something... inconsistent?


Thanks,
pq

> 
> > +
> > +		format = to_dpu_format(fmt);
> >   
> >   		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
> >   			bg_alpha_enable = true;
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 5f0984ce62b1..4476722f03bb 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >   
> >   	pipe_cfg->dst_rect = new_plane_state->dst;
> >   
> > -	fb_rect.x2 = new_plane_state->fb->width;
> > -	fb_rect.y2 = new_plane_state->fb->height;
> > +	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && new_plane_state->fb) {
> > +		fb_rect.x2 = new_plane_state->fb->width;
> > +		fb_rect.y2 = new_plane_state->fb->height;
> > +	}
> >   
> >   	/* Ensure fb size is supported */
> >   	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
> > @@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >   		return -E2BIG;
> >   	}
> >   
> > -	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> > -
> >   	max_linewidth = pdpu->catalog->caps->max_linewidth;
> >   
> > +	if (drm_plane_solid_fill_enabled(new_plane_state))
> > +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> > +	else
> > +		fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> > +
> >   	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
> >   		/*
> >   		 * In parallel multirect case only the half of the usual width
> > @@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
> >   	struct drm_crtc *crtc = state->crtc;
> >   	struct drm_framebuffer *fb = state->fb;
> >   	bool is_rt_pipe;
> > -	const struct dpu_format *fmt =
> > -		to_dpu_format(msm_framebuffer_format(fb));
> > +	const struct dpu_format *fmt;
> >   	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> >   	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >   	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> >   	struct msm_gem_address_space *aspace = kms->base.aspace;
> >   	struct dpu_hw_fmt_layout layout;
> >   	bool layout_valid = false;
> > -	int ret;
> >   
> > -	ret = dpu_format_populate_layout(aspace, fb, &layout);
> > -	if (ret)
> > -		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> > -	else
> > -		layout_valid = true;
> > +	if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
> > +		int ret;
> > +
> > +		fmt = to_dpu_format(msm_framebuffer_format(fb));
> > +
> > +		ret = dpu_format_populate_layout(aspace, fb, &layout);
> > +		if (ret)
> > +			DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> > +		else
> > +			layout_valid = true;
> > +
> > +		DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
> > +				", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
> > +				crtc->base.id, DRM_RECT_ARG(&state->dst),
> > +				(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
> > +	} else {
> > +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> > +	}
> >   
> >   	pstate->pending = true;
> >   
> > @@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
> >   	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
> >   	pdpu->is_rt_pipe = is_rt_pipe;
> >   
> > -	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
> > -			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
> > -			crtc->base.id, DRM_RECT_ARG(&state->dst),
> > -			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
> > -
> >   	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
> >   				   drm_mode_vrefresh(&crtc->mode),
> >   				   layout_valid ? &layout : NULL);
> >   
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30  8:26     ` Pekka Paalanen
  -1 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-06-30  8:26 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten, quic_abhinavk, contact,
	laurent.pinchart, sebastian.wick, ville.syrjala, dri-devel,
	linux-kernel, linux-arm-msm, freedreno, wayland-devel

[-- Attachment #1: Type: text/plain, Size: 3256 bytes --]

On Thu, 29 Jun 2023 17:25:06 -0700
Jessica Zhang <quic_jesszhan@quicinc.com> wrote:

> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
> determine if the plane is solid fill. In addition drop the DPU plane
> color_fill field as we can now use drm_plane_state.solid_fill instead,
> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
> allow userspace to configure the alpha value for the solid fill color.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 4476722f03bb..11d4fb771a1f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -42,7 +42,6 @@
>  #define SHARP_SMOOTH_THR_DEFAULT	8
>  #define SHARP_NOISE_THR_DEFAULT	2
>  
> -#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
>  #define DPU_ZPOS_MAX 255
>  
>  /*
> @@ -82,7 +81,6 @@ struct dpu_plane {
>  
>  	enum dpu_sspp pipe;
>  
> -	uint32_t color_fill;
>  	bool is_error;
>  	bool is_rt_pipe;
>  	const struct dpu_mdss_cfg *catalog;
> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>  	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
>  }
>  
> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
> +{
> +	uint32_t ret = 0;
> +
> +	ret |= ((uint8_t) solid_fill.b) << 16;
> +	ret |= ((uint8_t) solid_fill.g) << 8;
> +	ret |= ((uint8_t) solid_fill.r);

solid_fill.r, g and b are uint32_t, yes?

What's the value encoding in the UAPI? That doc was missing.

I wouldn't expect the UAPI to use 32-bit variables if it was
essentially 8-bit, so this conversion looks wrong.

Nominal color value 1.0 in u8 is 0xff. The same in u32 is probably
0xffffffff? So a simple cast to u8 won't work. You'd want to take the
upper 8 bits instead.


Thanks,
pq

> +
> +	return ret;
> +}
> +
>  /**
>   * _dpu_plane_color_fill - enables color fill on plane
>   * @pdpu:   Pointer to DPU plane object
> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>  	if (pdpu->is_error)
>  		/* force white frame with 100% alpha pipe output on error */
>  		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
> -	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
> -		/* force 100% alpha */
> -		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> +	else if (drm_plane_solid_fill_enabled(plane->state))
> +		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
> +				plane->state->alpha);
>  	else {
>  		dpu_plane_flush_csc(pdpu, &pstate->pipe);
>  		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>  	}
>  
>  	/* override for color fill */
> -	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
> +	if (drm_plane_solid_fill_enabled(plane->state)) {
>  		_dpu_plane_set_qos_ctrl(plane, pipe, false);
>  
>  		/* skip remaining processing on color fill */
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
@ 2023-06-30  8:26     ` Pekka Paalanen
  0 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-06-30  8:26 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Dmitry Baryshkov, Marijn Suijten,
	wayland-devel

[-- Attachment #1: Type: text/plain, Size: 3256 bytes --]

On Thu, 29 Jun 2023 17:25:06 -0700
Jessica Zhang <quic_jesszhan@quicinc.com> wrote:

> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
> determine if the plane is solid fill. In addition drop the DPU plane
> color_fill field as we can now use drm_plane_state.solid_fill instead,
> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
> allow userspace to configure the alpha value for the solid fill color.
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 4476722f03bb..11d4fb771a1f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -42,7 +42,6 @@
>  #define SHARP_SMOOTH_THR_DEFAULT	8
>  #define SHARP_NOISE_THR_DEFAULT	2
>  
> -#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
>  #define DPU_ZPOS_MAX 255
>  
>  /*
> @@ -82,7 +81,6 @@ struct dpu_plane {
>  
>  	enum dpu_sspp pipe;
>  
> -	uint32_t color_fill;
>  	bool is_error;
>  	bool is_rt_pipe;
>  	const struct dpu_mdss_cfg *catalog;
> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>  	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
>  }
>  
> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
> +{
> +	uint32_t ret = 0;
> +
> +	ret |= ((uint8_t) solid_fill.b) << 16;
> +	ret |= ((uint8_t) solid_fill.g) << 8;
> +	ret |= ((uint8_t) solid_fill.r);

solid_fill.r, g and b are uint32_t, yes?

What's the value encoding in the UAPI? That doc was missing.

I wouldn't expect the UAPI to use 32-bit variables if it was
essentially 8-bit, so this conversion looks wrong.

Nominal color value 1.0 in u8 is 0xff. The same in u32 is probably
0xffffffff? So a simple cast to u8 won't work. You'd want to take the
upper 8 bits instead.


Thanks,
pq

> +
> +	return ret;
> +}
> +
>  /**
>   * _dpu_plane_color_fill - enables color fill on plane
>   * @pdpu:   Pointer to DPU plane object
> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>  	if (pdpu->is_error)
>  		/* force white frame with 100% alpha pipe output on error */
>  		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
> -	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
> -		/* force 100% alpha */
> -		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> +	else if (drm_plane_solid_fill_enabled(plane->state))
> +		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
> +				plane->state->alpha);
>  	else {
>  		dpu_plane_flush_csc(pdpu, &pstate->pipe);
>  		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>  	}
>  
>  	/* override for color fill */
> -	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
> +	if (drm_plane_solid_fill_enabled(plane->state)) {
>  		_dpu_plane_set_qos_ctrl(plane, pipe, false);
>  
>  		/* skip remaining processing on color fill */
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30  8:27     ` Pekka Paalanen
  -1 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-06-30  8:27 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten, quic_abhinavk, contact,
	laurent.pinchart, sebastian.wick, ville.syrjala, dri-devel,
	linux-kernel, linux-arm-msm, freedreno, wayland-devel

[-- Attachment #1: Type: text/plain, Size: 11093 bytes --]

On Thu, 29 Jun 2023 17:25:00 -0700
Jessica Zhang <quic_jesszhan@quicinc.com> wrote:

> Document and add support for solid_fill property to drm_plane. In
> addition, add support for setting and getting the values for solid_fill.
> 
> To enable solid fill planes, userspace must assign a property blob to
> the "solid_fill" plane property containing the following information:
> 
> struct drm_solid_fill_info {
> 	u8 version;
> 	u32 r, g, b;
> };
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>

Hi Jessica,

I've left some general UAPI related comments here.

> ---
>  drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>  drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>  include/drm/drm_blend.h                   |  1 +
>  include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>  5 files changed, 141 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
> index 784e63d70a42..fe14be2bd2b2 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -253,6 +253,11 @@ 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;
>  
> +	if (plane_state->solid_fill_blob) {
> +		drm_property_blob_put(plane_state->solid_fill_blob);
> +		plane_state->solid_fill_blob = NULL;
> +	}
> +
>  	if (plane->color_encoding_property) {
>  		if (!drm_object_property_get_default_value(&plane->base,
>  							   plane->color_encoding_property,
> @@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
>  	if (state->fb)
>  		drm_framebuffer_get(state->fb);
>  
> +	if (state->solid_fill_blob)
> +		drm_property_blob_get(state->solid_fill_blob);
> +
>  	state->fence = NULL;
>  	state->commit = NULL;
>  	state->fb_damage_clips = NULL;
> @@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
>  		drm_crtc_commit_put(state->commit);
>  
>  	drm_property_blob_put(state->fb_damage_clips);
> +	drm_property_blob_put(state->solid_fill_blob);
>  }
>  EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
>  
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index d867e7f9f2cd..a28b4ee79444 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -316,6 +316,51 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
>  }
>  EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
>  
> +static int drm_atomic_set_solid_fill_prop(struct drm_plane_state *state,
> +		struct drm_property_blob *blob)
> +{
> +	int ret = 0;
> +	int blob_version;
> +
> +	if (blob == state->solid_fill_blob)
> +		return 0;
> +
> +	drm_property_blob_put(state->solid_fill_blob);
> +	state->solid_fill_blob = NULL;

Is it ok to destroy old state before it is guaranteed that the new
state is accepted?

> +
> +	memset(&state->solid_fill, 0, sizeof(state->solid_fill));
> +
> +	if (blob) {
> +		struct drm_solid_fill_info *user_info = (struct drm_solid_fill_info *)blob->data;
> +
> +		if (blob->length != sizeof(struct drm_solid_fill_info)) {
> +			drm_dbg_atomic(state->plane->dev,
> +				       "[PLANE:%d:%s] bad solid fill blob length: %zu\n",
> +				       state->plane->base.id, state->plane->name,
> +				       blob->length);
> +			return -EINVAL;
> +		}
> +
> +		blob_version = user_info->version;
> +
> +		/* Add more versions if necessary */
> +		if (blob_version == 1) {
> +			state->solid_fill.r = user_info->r;
> +			state->solid_fill.g = user_info->g;
> +			state->solid_fill.b = user_info->b;
> +		} else {
> +			drm_dbg_atomic(state->plane->dev,
> +				       "[PLANE:%d:%s] failed to set solid fill (ret=%d)\n",
> +				       state->plane->base.id, state->plane->name,
> +				       ret);
> +			return -EINVAL;

Btw. how does the atomic check machinery work here?

I expect that a TEST_ONLY atomic commit will do all the above checks
and return failure if anything is not right. Right?

> +		}
> +		state->solid_fill_blob = drm_property_blob_get(blob);
> +	}
> +
> +	return ret;
> +}
> +
>  static void set_out_fence_for_crtc(struct drm_atomic_state *state,
>  				   struct drm_crtc *crtc, s32 __user *fence_ptr)
>  {
> @@ -544,6 +589,13 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
>  		state->src_w = val;
>  	} else if (property == config->prop_src_h) {
>  		state->src_h = val;
> +	} else if (property == plane->solid_fill_property) {
> +		struct drm_property_blob *solid_fill = drm_property_lookup_blob(dev, val);
> +
> +		ret = drm_atomic_set_solid_fill_prop(state, solid_fill);
> +		drm_property_blob_put(solid_fill);
> +
> +		return ret;
>  	} else if (property == plane->alpha_property) {
>  		state->alpha = val;
>  	} else if (property == plane->blend_mode_property) {
> @@ -616,6 +668,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>  		*val = state->src_w;
>  	} else if (property == config->prop_src_h) {
>  		*val = state->src_h;
> +	} else if (property == plane->solid_fill_property) {
> +		*val = state->solid_fill_blob ?
> +			state->solid_fill_blob->base.id : 0;
>  	} 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 6e74de833466..38c3c5d6453a 100644
> --- a/drivers/gpu/drm/drm_blend.c
> +++ b/drivers/gpu/drm/drm_blend.c
> @@ -185,6 +185,10 @@
>   *		 plane does not expose the "alpha" property, then this is
>   *		 assumed to be 1.0
>   *
> + * solid_fill:
> + *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
> + *	contains pixel data that drivers can use to fill a plane.

This is a nice start, but I feel it needs to explain much more about
how userspace should go about making use of this.

Yeah, the pixel_source property comes in the next patch, but I feel
that it is harder to review if the doc is built over multiple patches.
My personal approach would be to write the doc in full and referring to
pixel_source property already, and explain in the commit message that
the next patch will add pixel_source so people don't wonder about
referring to a non-existing property.

I mean just a reference to pixel_source, and leave the actual
pixel_source doc for the patch adding the property like it already is.

Dmitry's suggestion of swapping the patch order is good too.

> + *
>   * 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).
> @@ -615,3 +619,32 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>  	return 0;
>  }
>  EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
> +
> +/**
> + * drm_plane_create_solid_fill_property - create a new solid_fill property
> + * @plane: drm plane
> + *
> + * This creates a new property that holds pixel data for solid fill planes. This
> + * property is exposed to userspace as a property blob called "solid_fill".
> + *
> + * For information on what the blob contains, see `drm_solid_fill_info`.

I think you should be more explicit here. For example: the blob must
contain exactly one struct drm_solid_fill_info.

It's better to put this content spec with the UAPI doc rather than in this
kerner-internal function doc that userspace programmers won't know to
look at.

> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_plane_create_solid_fill_property(struct drm_plane *plane)
> +{
> +	struct drm_property *prop;
> +
> +	prop = drm_property_create(plane->dev,
> +			DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
> +			"solid_fill", 0);
> +	if (!prop)
> +		return -ENOMEM;
> +
> +	drm_object_attach_property(&plane->base, prop, 0);
> +	plane->solid_fill_property = prop;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> index 88bdfec3bd88..0338a860b9c8 100644
> --- a/include/drm/drm_blend.h
> +++ b/include/drm/drm_blend.h
> @@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>  			      struct drm_atomic_state *state);
>  int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>  					 unsigned int supported_modes);
> +int drm_plane_create_solid_fill_property(struct drm_plane *plane);
>  #endif
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index 51291983ea44..f6ab313cb83e 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -40,6 +40,25 @@ enum drm_scaling_filter {
>  	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
>  };
>  
> +/**
> + * struct drm_solid_fill_info - User info for solid fill planes
> + */
> +struct drm_solid_fill_info {
> +	__u8 version;
> +	__u32 r, g, b;
> +};

Shouldn't UAPI structs be in UAPI headers?

Shouldn't UAPI structs use explicit padding to not leave any gaps when
it's unavoidable? And the kernel to check that the gaps are indeed
zeroed?

It also needs more UAPI doc, like a link to the property doc that uses
this and an explanation of what the values mean.


Thanks,
pq

> +
> +/**
> + * struct solid_fill_property - RGB values for solid fill plane
> + *
> + * Note: This is the V1 for this feature
> + */
> +struct drm_solid_fill {
> +	uint32_t r;
> +	uint32_t g;
> +	uint32_t b;
> +};
> +
>  /**
>   * struct drm_plane_state - mutable plane state
>   *
> @@ -116,6 +135,23 @@ struct drm_plane_state {
>  	/** @src_h: height of visible portion of plane (in 16.16) */
>  	uint32_t src_h, src_w;
>  
> +	/**
> +	 * @solid_fill_blob:
> +	 *
> +	 * Blob containing relevant information for a solid fill plane
> +	 * including pixel format and data. See
> +	 * drm_plane_create_solid_fill_property() for more details.
> +	 */
> +	struct drm_property_blob *solid_fill_blob;
> +
> +	/**
> +	 * @solid_fill:
> +	 *
> +	 * Pixel data for solid fill planes. See
> +	 * drm_plane_create_solid_fill_property() for more details.
> +	 */
> +	struct drm_solid_fill solid_fill;
> +
>  	/**
>  	 * @alpha:
>  	 * Opacity of the plane with 0 as completely transparent and 0xffff as
> @@ -699,6 +735,13 @@ struct drm_plane {
>  	 */
>  	struct drm_plane_state *state;
>  
> +	/*
> +	 * @solid_fill_property:
> +	 * Optional solid_fill property for this plane. See
> +	 * drm_plane_create_solid_fill_property().
> +	 */
> +	struct drm_property *solid_fill_property;
> +
>  	/**
>  	 * @alpha_property:
>  	 * Optional alpha property for this plane. See
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
@ 2023-06-30  8:27     ` Pekka Paalanen
  0 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-06-30  8:27 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Dmitry Baryshkov, Marijn Suijten,
	wayland-devel

[-- Attachment #1: Type: text/plain, Size: 11093 bytes --]

On Thu, 29 Jun 2023 17:25:00 -0700
Jessica Zhang <quic_jesszhan@quicinc.com> wrote:

> Document and add support for solid_fill property to drm_plane. In
> addition, add support for setting and getting the values for solid_fill.
> 
> To enable solid fill planes, userspace must assign a property blob to
> the "solid_fill" plane property containing the following information:
> 
> struct drm_solid_fill_info {
> 	u8 version;
> 	u32 r, g, b;
> };
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>

Hi Jessica,

I've left some general UAPI related comments here.

> ---
>  drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>  drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>  include/drm/drm_blend.h                   |  1 +
>  include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>  5 files changed, 141 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
> index 784e63d70a42..fe14be2bd2b2 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -253,6 +253,11 @@ 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;
>  
> +	if (plane_state->solid_fill_blob) {
> +		drm_property_blob_put(plane_state->solid_fill_blob);
> +		plane_state->solid_fill_blob = NULL;
> +	}
> +
>  	if (plane->color_encoding_property) {
>  		if (!drm_object_property_get_default_value(&plane->base,
>  							   plane->color_encoding_property,
> @@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
>  	if (state->fb)
>  		drm_framebuffer_get(state->fb);
>  
> +	if (state->solid_fill_blob)
> +		drm_property_blob_get(state->solid_fill_blob);
> +
>  	state->fence = NULL;
>  	state->commit = NULL;
>  	state->fb_damage_clips = NULL;
> @@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
>  		drm_crtc_commit_put(state->commit);
>  
>  	drm_property_blob_put(state->fb_damage_clips);
> +	drm_property_blob_put(state->solid_fill_blob);
>  }
>  EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
>  
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index d867e7f9f2cd..a28b4ee79444 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -316,6 +316,51 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
>  }
>  EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
>  
> +static int drm_atomic_set_solid_fill_prop(struct drm_plane_state *state,
> +		struct drm_property_blob *blob)
> +{
> +	int ret = 0;
> +	int blob_version;
> +
> +	if (blob == state->solid_fill_blob)
> +		return 0;
> +
> +	drm_property_blob_put(state->solid_fill_blob);
> +	state->solid_fill_blob = NULL;

Is it ok to destroy old state before it is guaranteed that the new
state is accepted?

> +
> +	memset(&state->solid_fill, 0, sizeof(state->solid_fill));
> +
> +	if (blob) {
> +		struct drm_solid_fill_info *user_info = (struct drm_solid_fill_info *)blob->data;
> +
> +		if (blob->length != sizeof(struct drm_solid_fill_info)) {
> +			drm_dbg_atomic(state->plane->dev,
> +				       "[PLANE:%d:%s] bad solid fill blob length: %zu\n",
> +				       state->plane->base.id, state->plane->name,
> +				       blob->length);
> +			return -EINVAL;
> +		}
> +
> +		blob_version = user_info->version;
> +
> +		/* Add more versions if necessary */
> +		if (blob_version == 1) {
> +			state->solid_fill.r = user_info->r;
> +			state->solid_fill.g = user_info->g;
> +			state->solid_fill.b = user_info->b;
> +		} else {
> +			drm_dbg_atomic(state->plane->dev,
> +				       "[PLANE:%d:%s] failed to set solid fill (ret=%d)\n",
> +				       state->plane->base.id, state->plane->name,
> +				       ret);
> +			return -EINVAL;

Btw. how does the atomic check machinery work here?

I expect that a TEST_ONLY atomic commit will do all the above checks
and return failure if anything is not right. Right?

> +		}
> +		state->solid_fill_blob = drm_property_blob_get(blob);
> +	}
> +
> +	return ret;
> +}
> +
>  static void set_out_fence_for_crtc(struct drm_atomic_state *state,
>  				   struct drm_crtc *crtc, s32 __user *fence_ptr)
>  {
> @@ -544,6 +589,13 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
>  		state->src_w = val;
>  	} else if (property == config->prop_src_h) {
>  		state->src_h = val;
> +	} else if (property == plane->solid_fill_property) {
> +		struct drm_property_blob *solid_fill = drm_property_lookup_blob(dev, val);
> +
> +		ret = drm_atomic_set_solid_fill_prop(state, solid_fill);
> +		drm_property_blob_put(solid_fill);
> +
> +		return ret;
>  	} else if (property == plane->alpha_property) {
>  		state->alpha = val;
>  	} else if (property == plane->blend_mode_property) {
> @@ -616,6 +668,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>  		*val = state->src_w;
>  	} else if (property == config->prop_src_h) {
>  		*val = state->src_h;
> +	} else if (property == plane->solid_fill_property) {
> +		*val = state->solid_fill_blob ?
> +			state->solid_fill_blob->base.id : 0;
>  	} 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 6e74de833466..38c3c5d6453a 100644
> --- a/drivers/gpu/drm/drm_blend.c
> +++ b/drivers/gpu/drm/drm_blend.c
> @@ -185,6 +185,10 @@
>   *		 plane does not expose the "alpha" property, then this is
>   *		 assumed to be 1.0
>   *
> + * solid_fill:
> + *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
> + *	contains pixel data that drivers can use to fill a plane.

This is a nice start, but I feel it needs to explain much more about
how userspace should go about making use of this.

Yeah, the pixel_source property comes in the next patch, but I feel
that it is harder to review if the doc is built over multiple patches.
My personal approach would be to write the doc in full and referring to
pixel_source property already, and explain in the commit message that
the next patch will add pixel_source so people don't wonder about
referring to a non-existing property.

I mean just a reference to pixel_source, and leave the actual
pixel_source doc for the patch adding the property like it already is.

Dmitry's suggestion of swapping the patch order is good too.

> + *
>   * 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).
> @@ -615,3 +619,32 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>  	return 0;
>  }
>  EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
> +
> +/**
> + * drm_plane_create_solid_fill_property - create a new solid_fill property
> + * @plane: drm plane
> + *
> + * This creates a new property that holds pixel data for solid fill planes. This
> + * property is exposed to userspace as a property blob called "solid_fill".
> + *
> + * For information on what the blob contains, see `drm_solid_fill_info`.

I think you should be more explicit here. For example: the blob must
contain exactly one struct drm_solid_fill_info.

It's better to put this content spec with the UAPI doc rather than in this
kerner-internal function doc that userspace programmers won't know to
look at.

> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_plane_create_solid_fill_property(struct drm_plane *plane)
> +{
> +	struct drm_property *prop;
> +
> +	prop = drm_property_create(plane->dev,
> +			DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
> +			"solid_fill", 0);
> +	if (!prop)
> +		return -ENOMEM;
> +
> +	drm_object_attach_property(&plane->base, prop, 0);
> +	plane->solid_fill_property = prop;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> index 88bdfec3bd88..0338a860b9c8 100644
> --- a/include/drm/drm_blend.h
> +++ b/include/drm/drm_blend.h
> @@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>  			      struct drm_atomic_state *state);
>  int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>  					 unsigned int supported_modes);
> +int drm_plane_create_solid_fill_property(struct drm_plane *plane);
>  #endif
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index 51291983ea44..f6ab313cb83e 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -40,6 +40,25 @@ enum drm_scaling_filter {
>  	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
>  };
>  
> +/**
> + * struct drm_solid_fill_info - User info for solid fill planes
> + */
> +struct drm_solid_fill_info {
> +	__u8 version;
> +	__u32 r, g, b;
> +};

Shouldn't UAPI structs be in UAPI headers?

Shouldn't UAPI structs use explicit padding to not leave any gaps when
it's unavoidable? And the kernel to check that the gaps are indeed
zeroed?

It also needs more UAPI doc, like a link to the property doc that uses
this and an explanation of what the values mean.


Thanks,
pq

> +
> +/**
> + * struct solid_fill_property - RGB values for solid fill plane
> + *
> + * Note: This is the V1 for this feature
> + */
> +struct drm_solid_fill {
> +	uint32_t r;
> +	uint32_t g;
> +	uint32_t b;
> +};
> +
>  /**
>   * struct drm_plane_state - mutable plane state
>   *
> @@ -116,6 +135,23 @@ struct drm_plane_state {
>  	/** @src_h: height of visible portion of plane (in 16.16) */
>  	uint32_t src_h, src_w;
>  
> +	/**
> +	 * @solid_fill_blob:
> +	 *
> +	 * Blob containing relevant information for a solid fill plane
> +	 * including pixel format and data. See
> +	 * drm_plane_create_solid_fill_property() for more details.
> +	 */
> +	struct drm_property_blob *solid_fill_blob;
> +
> +	/**
> +	 * @solid_fill:
> +	 *
> +	 * Pixel data for solid fill planes. See
> +	 * drm_plane_create_solid_fill_property() for more details.
> +	 */
> +	struct drm_solid_fill solid_fill;
> +
>  	/**
>  	 * @alpha:
>  	 * Opacity of the plane with 0 as completely transparent and 0xffff as
> @@ -699,6 +735,13 @@ struct drm_plane {
>  	 */
>  	struct drm_plane_state *state;
>  
> +	/*
> +	 * @solid_fill_property:
> +	 * Optional solid_fill property for this plane. See
> +	 * drm_plane_create_solid_fill_property().
> +	 */
> +	struct drm_property *solid_fill_property;
> +
>  	/**
>  	 * @alpha_property:
>  	 * Optional alpha property for this plane. See
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-06-30  0:42     ` Dmitry Baryshkov
@ 2023-06-30  8:27       ` Pekka Paalanen
  -1 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-06-30  8:27 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten, quic_abhinavk, contact,
	laurent.pinchart, sebastian.wick, ville.syrjala, dri-devel,
	linux-kernel, linux-arm-msm, freedreno, wayland-devel

[-- Attachment #1: Type: text/plain, Size: 9973 bytes --]

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
> >   
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-06-30  8:27       ` Pekka Paalanen
  0 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-06-30  8:27 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Dmitry Baryshkov, Marijn Suijten,
	wayland-devel

[-- Attachment #1: Type: text/plain, Size: 9973 bytes --]

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
> >   
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30 10:33     ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30 10:33 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

On 30/06/2023 03:25, Jessica Zhang wrote:
> Document and add support for solid_fill property to drm_plane. In
> addition, add support for setting and getting the values for solid_fill.
> 
> To enable solid fill planes, userspace must assign a property blob to
> the "solid_fill" plane property containing the following information:
> 
> struct drm_solid_fill_info {
> 	u8 version;
> 	u32 r, g, b;
> };
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>   drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
>   drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>   include/drm/drm_blend.h                   |  1 +
>   include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>   5 files changed, 141 insertions(+)

Also, I think the point which we missed up to now. Could you please add 
both new properties to dri/N/state debugfs?

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
@ 2023-06-30 10:33     ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-06-30 10:33 UTC (permalink / raw)
  To: Jessica Zhang, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno

On 30/06/2023 03:25, Jessica Zhang wrote:
> Document and add support for solid_fill property to drm_plane. In
> addition, add support for setting and getting the values for solid_fill.
> 
> To enable solid fill planes, userspace must assign a property blob to
> the "solid_fill" plane property containing the following information:
> 
> struct drm_solid_fill_info {
> 	u8 version;
> 	u32 r, g, b;
> };
> 
> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> ---
>   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>   drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
>   drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>   include/drm/drm_blend.h                   |  1 +
>   include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>   5 files changed, 141 insertions(+)

Also, I think the point which we missed up to now. Could you please add 
both new properties to dri/N/state debugfs?

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-06-30  0:25   ` Jessica Zhang
@ 2023-06-30 14:43     ` Sebastian Wick
  -1 siblings, 0 replies; 80+ messages in thread
From: Sebastian Wick @ 2023-06-30 14:43 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: freedreno, ppaalanen, Thomas Zimmermann, Sean Paul,
	quic_abhinavk, Maxime Ripard, linux-kernel, dri-devel,
	linux-arm-msm, Dmitry Baryshkov, Marijn Suijten, wayland-devel,
	laurent.pinchart

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
>


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-06-30 14:43     ` Sebastian Wick
  0 siblings, 0 replies; 80+ messages in thread
From: Sebastian Wick @ 2023-06-30 14:43 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten, quic_abhinavk, dri-devel,
	linux-kernel, ppaalanen, laurent.pinchart, linux-arm-msm,
	wayland-devel, freedreno

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
>


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
  2023-06-30 10:33     ` Dmitry Baryshkov
@ 2023-06-30 17:54       ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 17:54 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel



On 6/30/2023 3:33 AM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Document and add support for solid_fill property to drm_plane. In
>> addition, add support for setting and getting the values for solid_fill.
>>
>> To enable solid fill planes, userspace must assign a property blob to
>> the "solid_fill" plane property containing the following information:
>>
>> struct drm_solid_fill_info {
>>     u8 version;
>>     u32 r, g, b;
>> };
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>>   drivers/gpu/drm/drm_atomic_uapi.c         | 55 
>> +++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>>   include/drm/drm_blend.h                   |  1 +
>>   include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>>   5 files changed, 141 insertions(+)
> 
> Also, I think the point which we missed up to now. Could you please add 
> both new properties to dri/N/state debugfs?

Hi Dmitry,

Good catch -- acked.

Thanks,

Jessica Zhang

> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
@ 2023-06-30 17:54       ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 17:54 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno



On 6/30/2023 3:33 AM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Document and add support for solid_fill property to drm_plane. In
>> addition, add support for setting and getting the values for solid_fill.
>>
>> To enable solid fill planes, userspace must assign a property blob to
>> the "solid_fill" plane property containing the following information:
>>
>> struct drm_solid_fill_info {
>>     u8 version;
>>     u32 r, g, b;
>> };
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>>   drivers/gpu/drm/drm_atomic_uapi.c         | 55 
>> +++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>>   include/drm/drm_blend.h                   |  1 +
>>   include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>>   5 files changed, 141 insertions(+)
> 
> Also, I think the point which we missed up to now. Could you please add 
> both new properties to dri/N/state debugfs?

Hi Dmitry,

Good catch -- acked.

Thanks,

Jessica Zhang

> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 3/7] drm/atomic: Move framebuffer checks to helper
  2023-06-30  0:43     ` Dmitry Baryshkov
@ 2023-06-30 17:59       ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 17:59 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel



On 6/29/2023 5:43 PM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Currently framebuffer checks happen directly in
>> drm_atomic_plane_check(). Move these checks into their own helper
>> method.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/drm_atomic.c | 130 
>> ++++++++++++++++++++++++-------------------
>>   1 file changed, 74 insertions(+), 56 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> index b4c6ffc438da..404b984d2d9f 100644
>> --- a/drivers/gpu/drm/drm_atomic.c
>> +++ b/drivers/gpu/drm/drm_atomic.c
>> @@ -580,6 +580,76 @@ plane_switching_crtc(const struct drm_plane_state 
>> *old_plane_state,
>>       return true;
>>   }
>> +static int drm_atomic_check_fb(const struct drm_plane_state *state)
>> +{
>> +    struct drm_plane *plane = state->plane;
>> +    const struct drm_framebuffer *fb = state->fb;
>> +    struct drm_mode_rect *clips;
>> +
>> +    uint32_t num_clips;
>> +    unsigned int fb_width, fb_height;
>> +    int ret;
>> +
>> +    /* Check whether this plane supports the fb pixel format. */
>> +    ret = drm_plane_check_pixel_format(plane, fb->format->format,
>> +                       fb->modifier);
>> +
>> +    if (ret) {
>> +        drm_dbg_atomic(plane->dev,
>> +                   "[PLANE:%d:%s] invalid pixel format %p4cc, 
>> modifier 0x%llx\n",
>> +                   plane->base.id, plane->name,
>> +                   &fb->format->format, fb->modifier);
>> +        return ret;
>> +    }
>> +
>> +    fb_width = fb->width << 16;
>> +    fb_height = fb->height << 16;
>> +
>> +    /* Make sure source coordinates are inside the fb. */
>> +    if (state->src_w > fb_width ||
>> +        state->src_x > fb_width - state->src_w ||
>> +        state->src_h > fb_height ||
>> +        state->src_y > fb_height - state->src_h) {
>> +        drm_dbg_atomic(plane->dev,
>> +                   "[PLANE:%d:%s] invalid source coordinates "
>> +                   "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
>> +                   plane->base.id, plane->name,
>> +                   state->src_w >> 16,
>> +                   ((state->src_w & 0xffff) * 15625) >> 10,
>> +                   state->src_h >> 16,
>> +                   ((state->src_h & 0xffff) * 15625) >> 10,
>> +                   state->src_x >> 16,
>> +                   ((state->src_x & 0xffff) * 15625) >> 10,
>> +                   state->src_y >> 16,
>> +                   ((state->src_y & 0xffff) * 15625) >> 10,
>> +                   fb->width, fb->height);
>> +        return -ENOSPC;
>> +    }
>> +
>> +    clips = __drm_plane_get_damage_clips(state);
>> +    num_clips = drm_plane_get_damage_clips_count(state);
>> +
>> +    /* Make sure damage clips are valid and inside the fb. */
>> +    while (num_clips > 0) {
>> +        if (clips->x1 >= clips->x2 ||
>> +            clips->y1 >= clips->y2 ||
>> +            clips->x1 < 0 ||
>> +            clips->y1 < 0 ||
>> +            clips->x2 > fb_width ||
>> +            clips->y2 > fb_height) {
>> +            drm_dbg_atomic(plane->dev,
>> +                       "[PLANE:%d:%s] invalid damage clip %d %d %d 
>> %d\n",
>> +                       plane->base.id, plane->name, clips->x1,
>> +                       clips->y1, clips->x2, clips->y2);
>> +            return -EINVAL;
>> +        }
>> +        clips++;
>> +        num_clips--;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   /**
>>    * drm_atomic_plane_check - check plane state
>>    * @old_plane_state: old plane state to check
>> @@ -596,9 +666,6 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>       struct drm_plane *plane = new_plane_state->plane;
>>       struct drm_crtc *crtc = new_plane_state->crtc;
>>       const struct drm_framebuffer *fb = new_plane_state->fb;
>> -    unsigned int fb_width, fb_height;
>> -    struct drm_mode_rect *clips;
>> -    uint32_t num_clips;
>>       int ret;
>>       /* either *both* CRTC and FB must be set, or neither */
>> @@ -625,17 +692,6 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>           return -EINVAL;
>>       }
>> -    /* Check whether this plane supports the fb pixel format. */
>> -    ret = drm_plane_check_pixel_format(plane, fb->format->format,
>> -                       fb->modifier);
>> -    if (ret) {
>> -        drm_dbg_atomic(plane->dev,
>> -                   "[PLANE:%d:%s] invalid pixel format %p4cc, 
>> modifier 0x%llx\n",
>> -                   plane->base.id, plane->name,
>> -                   &fb->format->format, fb->modifier);
>> -        return ret;
>> -    }
>> -
>>       /* Give drivers some help against integer overflows */
>>       if (new_plane_state->crtc_w > INT_MAX ||
>>           new_plane_state->crtc_x > INT_MAX - (int32_t) 
>> new_plane_state->crtc_w ||
>> @@ -649,49 +705,11 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>           return -ERANGE;
>>       }
>> -    fb_width = fb->width << 16;
>> -    fb_height = fb->height << 16;
>> -    /* Make sure source coordinates are inside the fb. */
>> -    if (new_plane_state->src_w > fb_width ||
>> -        new_plane_state->src_x > fb_width - new_plane_state->src_w ||
>> -        new_plane_state->src_h > fb_height ||
>> -        new_plane_state->src_y > fb_height - new_plane_state->src_h) {
>> -        drm_dbg_atomic(plane->dev,
>> -                   "[PLANE:%d:%s] invalid source coordinates "
>> -                   "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
>> -                   plane->base.id, plane->name,
>> -                   new_plane_state->src_w >> 16,
>> -                   ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
>> -                   new_plane_state->src_h >> 16,
>> -                   ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
>> -                   new_plane_state->src_x >> 16,
>> -                   ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
>> -                   new_plane_state->src_y >> 16,
>> -                   ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
>> -                   fb->width, fb->height);
>> -        return -ENOSPC;
>> -    }
>> -
>> -    clips = __drm_plane_get_damage_clips(new_plane_state);
>> -    num_clips = drm_plane_get_damage_clips_count(new_plane_state);
>> -
>> -    /* Make sure damage clips are valid and inside the fb. */
>> -    while (num_clips > 0) {
>> -        if (clips->x1 >= clips->x2 ||
>> -            clips->y1 >= clips->y2 ||
>> -            clips->x1 < 0 ||
>> -            clips->y1 < 0 ||
>> -            clips->x2 > fb_width ||
>> -            clips->y2 > fb_height) {
>> -            drm_dbg_atomic(plane->dev,
>> -                       "[PLANE:%d:%s] invalid damage clip %d %d %d 
>> %d\n",
>> -                       plane->base.id, plane->name, clips->x1,
>> -                       clips->y1, clips->x2, clips->y2);
>> -            return -EINVAL;
>> -        }
>> -        clips++;
>> -        num_clips--;
>> +    if (fb) {
> 
> This doesn't only move code, but also changes semantics, making the 
> checks optional if no FB is provided. Consider moving the condition to 
> the next patch. Otherwise LGTM.

Hi Dmitry,

Sounds good.

Thanks,

Jessica Zhang

> 
>> +        ret = drm_atomic_check_fb(new_plane_state);
>> +        if (ret)
>> +            return ret;
>>       }
>>       if (plane_switching_crtc(old_plane_state, new_plane_state)) {
>>
> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 3/7] drm/atomic: Move framebuffer checks to helper
@ 2023-06-30 17:59       ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 17:59 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno



On 6/29/2023 5:43 PM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Currently framebuffer checks happen directly in
>> drm_atomic_plane_check(). Move these checks into their own helper
>> method.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/drm_atomic.c | 130 
>> ++++++++++++++++++++++++-------------------
>>   1 file changed, 74 insertions(+), 56 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> index b4c6ffc438da..404b984d2d9f 100644
>> --- a/drivers/gpu/drm/drm_atomic.c
>> +++ b/drivers/gpu/drm/drm_atomic.c
>> @@ -580,6 +580,76 @@ plane_switching_crtc(const struct drm_plane_state 
>> *old_plane_state,
>>       return true;
>>   }
>> +static int drm_atomic_check_fb(const struct drm_plane_state *state)
>> +{
>> +    struct drm_plane *plane = state->plane;
>> +    const struct drm_framebuffer *fb = state->fb;
>> +    struct drm_mode_rect *clips;
>> +
>> +    uint32_t num_clips;
>> +    unsigned int fb_width, fb_height;
>> +    int ret;
>> +
>> +    /* Check whether this plane supports the fb pixel format. */
>> +    ret = drm_plane_check_pixel_format(plane, fb->format->format,
>> +                       fb->modifier);
>> +
>> +    if (ret) {
>> +        drm_dbg_atomic(plane->dev,
>> +                   "[PLANE:%d:%s] invalid pixel format %p4cc, 
>> modifier 0x%llx\n",
>> +                   plane->base.id, plane->name,
>> +                   &fb->format->format, fb->modifier);
>> +        return ret;
>> +    }
>> +
>> +    fb_width = fb->width << 16;
>> +    fb_height = fb->height << 16;
>> +
>> +    /* Make sure source coordinates are inside the fb. */
>> +    if (state->src_w > fb_width ||
>> +        state->src_x > fb_width - state->src_w ||
>> +        state->src_h > fb_height ||
>> +        state->src_y > fb_height - state->src_h) {
>> +        drm_dbg_atomic(plane->dev,
>> +                   "[PLANE:%d:%s] invalid source coordinates "
>> +                   "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
>> +                   plane->base.id, plane->name,
>> +                   state->src_w >> 16,
>> +                   ((state->src_w & 0xffff) * 15625) >> 10,
>> +                   state->src_h >> 16,
>> +                   ((state->src_h & 0xffff) * 15625) >> 10,
>> +                   state->src_x >> 16,
>> +                   ((state->src_x & 0xffff) * 15625) >> 10,
>> +                   state->src_y >> 16,
>> +                   ((state->src_y & 0xffff) * 15625) >> 10,
>> +                   fb->width, fb->height);
>> +        return -ENOSPC;
>> +    }
>> +
>> +    clips = __drm_plane_get_damage_clips(state);
>> +    num_clips = drm_plane_get_damage_clips_count(state);
>> +
>> +    /* Make sure damage clips are valid and inside the fb. */
>> +    while (num_clips > 0) {
>> +        if (clips->x1 >= clips->x2 ||
>> +            clips->y1 >= clips->y2 ||
>> +            clips->x1 < 0 ||
>> +            clips->y1 < 0 ||
>> +            clips->x2 > fb_width ||
>> +            clips->y2 > fb_height) {
>> +            drm_dbg_atomic(plane->dev,
>> +                       "[PLANE:%d:%s] invalid damage clip %d %d %d 
>> %d\n",
>> +                       plane->base.id, plane->name, clips->x1,
>> +                       clips->y1, clips->x2, clips->y2);
>> +            return -EINVAL;
>> +        }
>> +        clips++;
>> +        num_clips--;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   /**
>>    * drm_atomic_plane_check - check plane state
>>    * @old_plane_state: old plane state to check
>> @@ -596,9 +666,6 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>       struct drm_plane *plane = new_plane_state->plane;
>>       struct drm_crtc *crtc = new_plane_state->crtc;
>>       const struct drm_framebuffer *fb = new_plane_state->fb;
>> -    unsigned int fb_width, fb_height;
>> -    struct drm_mode_rect *clips;
>> -    uint32_t num_clips;
>>       int ret;
>>       /* either *both* CRTC and FB must be set, or neither */
>> @@ -625,17 +692,6 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>           return -EINVAL;
>>       }
>> -    /* Check whether this plane supports the fb pixel format. */
>> -    ret = drm_plane_check_pixel_format(plane, fb->format->format,
>> -                       fb->modifier);
>> -    if (ret) {
>> -        drm_dbg_atomic(plane->dev,
>> -                   "[PLANE:%d:%s] invalid pixel format %p4cc, 
>> modifier 0x%llx\n",
>> -                   plane->base.id, plane->name,
>> -                   &fb->format->format, fb->modifier);
>> -        return ret;
>> -    }
>> -
>>       /* Give drivers some help against integer overflows */
>>       if (new_plane_state->crtc_w > INT_MAX ||
>>           new_plane_state->crtc_x > INT_MAX - (int32_t) 
>> new_plane_state->crtc_w ||
>> @@ -649,49 +705,11 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>           return -ERANGE;
>>       }
>> -    fb_width = fb->width << 16;
>> -    fb_height = fb->height << 16;
>> -    /* Make sure source coordinates are inside the fb. */
>> -    if (new_plane_state->src_w > fb_width ||
>> -        new_plane_state->src_x > fb_width - new_plane_state->src_w ||
>> -        new_plane_state->src_h > fb_height ||
>> -        new_plane_state->src_y > fb_height - new_plane_state->src_h) {
>> -        drm_dbg_atomic(plane->dev,
>> -                   "[PLANE:%d:%s] invalid source coordinates "
>> -                   "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
>> -                   plane->base.id, plane->name,
>> -                   new_plane_state->src_w >> 16,
>> -                   ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
>> -                   new_plane_state->src_h >> 16,
>> -                   ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
>> -                   new_plane_state->src_x >> 16,
>> -                   ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
>> -                   new_plane_state->src_y >> 16,
>> -                   ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
>> -                   fb->width, fb->height);
>> -        return -ENOSPC;
>> -    }
>> -
>> -    clips = __drm_plane_get_damage_clips(new_plane_state);
>> -    num_clips = drm_plane_get_damage_clips_count(new_plane_state);
>> -
>> -    /* Make sure damage clips are valid and inside the fb. */
>> -    while (num_clips > 0) {
>> -        if (clips->x1 >= clips->x2 ||
>> -            clips->y1 >= clips->y2 ||
>> -            clips->x1 < 0 ||
>> -            clips->y1 < 0 ||
>> -            clips->x2 > fb_width ||
>> -            clips->y2 > fb_height) {
>> -            drm_dbg_atomic(plane->dev,
>> -                       "[PLANE:%d:%s] invalid damage clip %d %d %d 
>> %d\n",
>> -                       plane->base.id, plane->name, clips->x1,
>> -                       clips->y1, clips->x2, clips->y2);
>> -            return -EINVAL;
>> -        }
>> -        clips++;
>> -        num_clips--;
>> +    if (fb) {
> 
> This doesn't only move code, but also changes semantics, making the 
> checks optional if no FB is provided. Consider moving the condition to 
> the next patch. Otherwise LGTM.

Hi Dmitry,

Sounds good.

Thanks,

Jessica Zhang

> 
>> +        ret = drm_atomic_check_fb(new_plane_state);
>> +        if (ret)
>> +            return ret;
>>       }
>>       if (plane_switching_crtc(old_plane_state, new_plane_state)) {
>>
> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-06-30 14:43     ` Sebastian Wick
@ 2023-06-30 21:27       ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 21:27 UTC (permalink / raw)
  To: Sebastian Wick
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten, quic_abhinavk, dri-devel,
	linux-kernel, ppaalanen, laurent.pinchart, linux-arm-msm,
	wayland-devel, freedreno



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
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-06-30 21:27       ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 21:27 UTC (permalink / raw)
  To: Sebastian Wick
  Cc: freedreno, ppaalanen, Thomas Zimmermann, Sean Paul,
	quic_abhinavk, Maxime Ripard, linux-kernel, dri-devel,
	linux-arm-msm, Dmitry Baryshkov, Marijn Suijten, wayland-devel,
	laurent.pinchart



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
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 4/7] drm/atomic: Loosen FB atomic checks
  2023-06-30  0:48     ` Dmitry Baryshkov
@ 2023-06-30 23:41       ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 23:41 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel



On 6/29/2023 5:48 PM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Loosen the requirements for atomic and legacy commit so that, in cases
>> where solid fill planes is enabled but no FB is set, the commit can
>> still go through.
>>
>> This includes adding framebuffer NULL checks in other areas to account
>> for FB being NULL when solid fill is enabled.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/drm_atomic.c        | 14 +++++++-------
>>   drivers/gpu/drm/drm_atomic_helper.c | 34 
>> ++++++++++++++++++++--------------
>>   drivers/gpu/drm/drm_plane.c         |  8 ++++----
>>   include/drm/drm_atomic_helper.h     |  4 ++--
>>   include/drm/drm_plane.h             | 28 ++++++++++++++++++++++++++++
>>   5 files changed, 61 insertions(+), 27 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> index 404b984d2d9f..ec9681c25366 100644
>> --- a/drivers/gpu/drm/drm_atomic.c
>> +++ b/drivers/gpu/drm/drm_atomic.c
>> @@ -668,14 +668,14 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>       const struct drm_framebuffer *fb = new_plane_state->fb;
>>       int ret;
>> -    /* either *both* CRTC and FB must be set, or neither */
>> -    if (crtc && !fb) {
>> -        drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
>> +    /* either *both* CRTC and pixel source must be set, or neither */
>> +    if (crtc && !drm_plane_has_visible_data(new_plane_state)) {
>> +        drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no 
>> visible data\n",
>>                      plane->base.id, plane->name);
>>           return -EINVAL;
>> -    } else if (fb && !crtc) {
>> -        drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
>> -                   plane->base.id, plane->name);
>> +    } else if (drm_plane_has_visible_data(new_plane_state) && !crtc) {
>> +        drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] Source %d has 
>> visible data but no CRTC\n",
>> +                   plane->base.id, plane->name, 
>> new_plane_state->pixel_source);
>>           return -EINVAL;
>>       }
>> @@ -706,7 +706,7 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>       }
>> -    if (fb) {
>> +    if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && 
>> fb) {
>>           ret = drm_atomic_check_fb(new_plane_state);
>>           if (ret)
>>               return ret;
>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
>> b/drivers/gpu/drm/drm_atomic_helper.c
>> index 41b8066f61ff..d05ec9ef2b3e 100644
>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>> @@ -864,7 +864,7 @@ int drm_atomic_helper_check_plane_state(struct 
>> drm_plane_state *plane_state,
>>       *src = drm_plane_state_src(plane_state);
>>       *dst = drm_plane_state_dest(plane_state);
>> -    if (!fb) {
>> +    if (!drm_plane_has_visible_data(plane_state)) {
>>           plane_state->visible = false;
>>           return 0;
>>       }
>> @@ -881,25 +881,31 @@ int drm_atomic_helper_check_plane_state(struct 
>> drm_plane_state *plane_state,
>>           return -EINVAL;
>>       }
>> -    drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
>> +    if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
>> +        drm_rect_rotate(src, fb->width << 16, fb->height << 16, 
>> rotation);
>> -    /* Check scaling */
>> -    hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
>> -    vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
>> -    if (hscale < 0 || vscale < 0) {
>> -        drm_dbg_kms(plane_state->plane->dev,
>> -                "Invalid scaling of plane\n");
>> -        drm_rect_debug_print("src: ", &plane_state->src, true);
>> -        drm_rect_debug_print("dst: ", &plane_state->dst, false);
>> -        return -ERANGE;
>> +        /* Check scaling */
>> +        hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
>> +        vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
>> +
>> +        if (hscale < 0 || vscale < 0) {
>> +            drm_dbg_kms(plane_state->plane->dev,
>> +                    "Invalid scaling of plane\n");
>> +            drm_rect_debug_print("src: ", &plane_state->src, true);
>> +            drm_rect_debug_print("dst: ", &plane_state->dst, false);
>> +            return -ERANGE;
>> +        }
>>       }
>>       if (crtc_state->enable)
>>           drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
>> -    plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
>> -
>> -    drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 
>> rotation);
>> +    if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
>> +        plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
>> +        drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 
>> rotation);
>> +    } else if (drm_plane_solid_fill_enabled(plane_state)) {
>> +        plane_state->visible = true;
>> +    }
>>       if (!plane_state->visible)
>>           /*
>> diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
>> index 24e7998d1731..5f19a27ba182 100644
>> --- a/drivers/gpu/drm/drm_plane.c
>> +++ b/drivers/gpu/drm/drm_plane.c
>> @@ -861,8 +861,8 @@ static int __setplane_internal(struct drm_plane 
>> *plane,
>>       WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
>> -    /* No fb means shut it down */
>> -    if (!fb) {
>> +    /* No visible data means shut it down */
>> +    if (!drm_plane_has_visible_data(plane->state)) {
>>           plane->old_fb = plane->fb;
>>           ret = plane->funcs->disable_plane(plane, ctx);
>>           if (!ret) {
>> @@ -913,8 +913,8 @@ static int __setplane_atomic(struct drm_plane *plane,
>>       WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
>> -    /* No fb means shut it down */
>> -    if (!fb)
>> +    /* No visible data means shut it down */
>> +    if (!drm_plane_has_visible_data(plane->state))
>>           return plane->funcs->disable_plane(plane, ctx);
>>       /*
>> diff --git a/include/drm/drm_atomic_helper.h 
>> b/include/drm/drm_atomic_helper.h
>> index 536a0b0091c3..6d97f38ac1f6 100644
>> --- a/include/drm/drm_atomic_helper.h
>> +++ b/include/drm/drm_atomic_helper.h
>> @@ -256,8 +256,8 @@ drm_atomic_plane_disabling(struct drm_plane_state 
>> *old_plane_state,
>>        * Anything else should be considered a bug in the atomic core, 
>> so we
>>        * gently warn about it.
>>        */
>> -    WARN_ON((new_plane_state->crtc == NULL && new_plane_state->fb != 
>> NULL) ||
>> -        (new_plane_state->crtc != NULL && new_plane_state->fb == NULL));
>> +    WARN_ON((new_plane_state->crtc == NULL && 
>> drm_plane_has_visible_data(new_plane_state)) ||
>> +        (new_plane_state->crtc != NULL && 
>> !drm_plane_has_visible_data(new_plane_state)));
>>       return old_plane_state->crtc && !new_plane_state->crtc;
>>   }
>> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
>> index 73fb6cf8a5d9..f893f7a56912 100644
>> --- a/include/drm/drm_plane.h
>> +++ b/include/drm/drm_plane.h
>> @@ -998,6 +998,34 @@ static inline struct drm_plane 
>> *drm_plane_find(struct drm_device *dev,
>>   #define drm_for_each_plane(plane, dev) \
>>       list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
>> +/**
>> + * drm_plane_solid_fill_enabled - Check if solid fill is enabled on 
>> plane
>> + * @state: plane state
>> + *
>> + * Returns:
>> + * Whether the plane has been assigned a solid_fill_blob
>> + */
>> +static inline bool drm_plane_solid_fill_enabled(struct 
>> drm_plane_state *state)
>> +{
>> +    if (!state)
>> +        return false;
>> +    return state->pixel_source == DRM_PLANE_PIXEL_SOURCE_COLOR && 
>> state->solid_fill_blob;
>> +}
>> +
>> +static inline bool drm_plane_has_visible_data(const struct 
>> drm_plane_state *state)
>> +{
>> +    switch (state->pixel_source) {
>> +    case DRM_PLANE_PIXEL_SOURCE_COLOR:
>> +        return state->solid_fill_blob != NULL;
>> +
>> +    default:
> 
> I'd say, there should a WARN_ON for the default case and then 
> fallthrough to the FB case.

Hi Dmitry,

Sounds good.

Thanks,

Jessica Zhang

> 
>> +        return state->fb != NULL;
>> +    }
>> +
>> +    return false;
>> +}
>> +
>> +
>>   bool drm_any_plane_has_format(struct drm_device *dev,
>>                     u32 format, u64 modifier);
>>
> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 4/7] drm/atomic: Loosen FB atomic checks
@ 2023-06-30 23:41       ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 23:41 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno



On 6/29/2023 5:48 PM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Loosen the requirements for atomic and legacy commit so that, in cases
>> where solid fill planes is enabled but no FB is set, the commit can
>> still go through.
>>
>> This includes adding framebuffer NULL checks in other areas to account
>> for FB being NULL when solid fill is enabled.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/drm_atomic.c        | 14 +++++++-------
>>   drivers/gpu/drm/drm_atomic_helper.c | 34 
>> ++++++++++++++++++++--------------
>>   drivers/gpu/drm/drm_plane.c         |  8 ++++----
>>   include/drm/drm_atomic_helper.h     |  4 ++--
>>   include/drm/drm_plane.h             | 28 ++++++++++++++++++++++++++++
>>   5 files changed, 61 insertions(+), 27 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>> index 404b984d2d9f..ec9681c25366 100644
>> --- a/drivers/gpu/drm/drm_atomic.c
>> +++ b/drivers/gpu/drm/drm_atomic.c
>> @@ -668,14 +668,14 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>       const struct drm_framebuffer *fb = new_plane_state->fb;
>>       int ret;
>> -    /* either *both* CRTC and FB must be set, or neither */
>> -    if (crtc && !fb) {
>> -        drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no FB\n",
>> +    /* either *both* CRTC and pixel source must be set, or neither */
>> +    if (crtc && !drm_plane_has_visible_data(new_plane_state)) {
>> +        drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] CRTC set but no 
>> visible data\n",
>>                      plane->base.id, plane->name);
>>           return -EINVAL;
>> -    } else if (fb && !crtc) {
>> -        drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] FB set but no CRTC\n",
>> -                   plane->base.id, plane->name);
>> +    } else if (drm_plane_has_visible_data(new_plane_state) && !crtc) {
>> +        drm_dbg_atomic(plane->dev, "[PLANE:%d:%s] Source %d has 
>> visible data but no CRTC\n",
>> +                   plane->base.id, plane->name, 
>> new_plane_state->pixel_source);
>>           return -EINVAL;
>>       }
>> @@ -706,7 +706,7 @@ static int drm_atomic_plane_check(const struct 
>> drm_plane_state *old_plane_state,
>>       }
>> -    if (fb) {
>> +    if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && 
>> fb) {
>>           ret = drm_atomic_check_fb(new_plane_state);
>>           if (ret)
>>               return ret;
>> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
>> b/drivers/gpu/drm/drm_atomic_helper.c
>> index 41b8066f61ff..d05ec9ef2b3e 100644
>> --- a/drivers/gpu/drm/drm_atomic_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_helper.c
>> @@ -864,7 +864,7 @@ int drm_atomic_helper_check_plane_state(struct 
>> drm_plane_state *plane_state,
>>       *src = drm_plane_state_src(plane_state);
>>       *dst = drm_plane_state_dest(plane_state);
>> -    if (!fb) {
>> +    if (!drm_plane_has_visible_data(plane_state)) {
>>           plane_state->visible = false;
>>           return 0;
>>       }
>> @@ -881,25 +881,31 @@ int drm_atomic_helper_check_plane_state(struct 
>> drm_plane_state *plane_state,
>>           return -EINVAL;
>>       }
>> -    drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
>> +    if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
>> +        drm_rect_rotate(src, fb->width << 16, fb->height << 16, 
>> rotation);
>> -    /* Check scaling */
>> -    hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
>> -    vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
>> -    if (hscale < 0 || vscale < 0) {
>> -        drm_dbg_kms(plane_state->plane->dev,
>> -                "Invalid scaling of plane\n");
>> -        drm_rect_debug_print("src: ", &plane_state->src, true);
>> -        drm_rect_debug_print("dst: ", &plane_state->dst, false);
>> -        return -ERANGE;
>> +        /* Check scaling */
>> +        hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
>> +        vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
>> +
>> +        if (hscale < 0 || vscale < 0) {
>> +            drm_dbg_kms(plane_state->plane->dev,
>> +                    "Invalid scaling of plane\n");
>> +            drm_rect_debug_print("src: ", &plane_state->src, true);
>> +            drm_rect_debug_print("dst: ", &plane_state->dst, false);
>> +            return -ERANGE;
>> +        }
>>       }
>>       if (crtc_state->enable)
>>           drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
>> -    plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
>> -
>> -    drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 
>> rotation);
>> +    if (plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
>> +        plane_state->visible = drm_rect_clip_scaled(src, dst, &clip);
>> +        drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, 
>> rotation);
>> +    } else if (drm_plane_solid_fill_enabled(plane_state)) {
>> +        plane_state->visible = true;
>> +    }
>>       if (!plane_state->visible)
>>           /*
>> diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
>> index 24e7998d1731..5f19a27ba182 100644
>> --- a/drivers/gpu/drm/drm_plane.c
>> +++ b/drivers/gpu/drm/drm_plane.c
>> @@ -861,8 +861,8 @@ static int __setplane_internal(struct drm_plane 
>> *plane,
>>       WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
>> -    /* No fb means shut it down */
>> -    if (!fb) {
>> +    /* No visible data means shut it down */
>> +    if (!drm_plane_has_visible_data(plane->state)) {
>>           plane->old_fb = plane->fb;
>>           ret = plane->funcs->disable_plane(plane, ctx);
>>           if (!ret) {
>> @@ -913,8 +913,8 @@ static int __setplane_atomic(struct drm_plane *plane,
>>       WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
>> -    /* No fb means shut it down */
>> -    if (!fb)
>> +    /* No visible data means shut it down */
>> +    if (!drm_plane_has_visible_data(plane->state))
>>           return plane->funcs->disable_plane(plane, ctx);
>>       /*
>> diff --git a/include/drm/drm_atomic_helper.h 
>> b/include/drm/drm_atomic_helper.h
>> index 536a0b0091c3..6d97f38ac1f6 100644
>> --- a/include/drm/drm_atomic_helper.h
>> +++ b/include/drm/drm_atomic_helper.h
>> @@ -256,8 +256,8 @@ drm_atomic_plane_disabling(struct drm_plane_state 
>> *old_plane_state,
>>        * Anything else should be considered a bug in the atomic core, 
>> so we
>>        * gently warn about it.
>>        */
>> -    WARN_ON((new_plane_state->crtc == NULL && new_plane_state->fb != 
>> NULL) ||
>> -        (new_plane_state->crtc != NULL && new_plane_state->fb == NULL));
>> +    WARN_ON((new_plane_state->crtc == NULL && 
>> drm_plane_has_visible_data(new_plane_state)) ||
>> +        (new_plane_state->crtc != NULL && 
>> !drm_plane_has_visible_data(new_plane_state)));
>>       return old_plane_state->crtc && !new_plane_state->crtc;
>>   }
>> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
>> index 73fb6cf8a5d9..f893f7a56912 100644
>> --- a/include/drm/drm_plane.h
>> +++ b/include/drm/drm_plane.h
>> @@ -998,6 +998,34 @@ static inline struct drm_plane 
>> *drm_plane_find(struct drm_device *dev,
>>   #define drm_for_each_plane(plane, dev) \
>>       list_for_each_entry(plane, &(dev)->mode_config.plane_list, head)
>> +/**
>> + * drm_plane_solid_fill_enabled - Check if solid fill is enabled on 
>> plane
>> + * @state: plane state
>> + *
>> + * Returns:
>> + * Whether the plane has been assigned a solid_fill_blob
>> + */
>> +static inline bool drm_plane_solid_fill_enabled(struct 
>> drm_plane_state *state)
>> +{
>> +    if (!state)
>> +        return false;
>> +    return state->pixel_source == DRM_PLANE_PIXEL_SOURCE_COLOR && 
>> state->solid_fill_blob;
>> +}
>> +
>> +static inline bool drm_plane_has_visible_data(const struct 
>> drm_plane_state *state)
>> +{
>> +    switch (state->pixel_source) {
>> +    case DRM_PLANE_PIXEL_SOURCE_COLOR:
>> +        return state->solid_fill_blob != NULL;
>> +
>> +    default:
> 
> I'd say, there should a WARN_ON for the default case and then 
> fallthrough to the FB case.

Hi Dmitry,

Sounds good.

Thanks,

Jessica Zhang

> 
>> +        return state->fb != NULL;
>> +    }
>> +
>> +    return false;
>> +}
>> +
>> +
>>   bool drm_any_plane_has_format(struct drm_device *dev,
>>                     u32 format, u64 modifier);
>>
> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 5/7] drm/msm/dpu: Add solid fill and pixel source properties
  2023-06-30  0:49     ` Dmitry Baryshkov
@ 2023-06-30 23:41       ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 23:41 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel



On 6/29/2023 5:49 PM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Add solid_fill and pixel_source properties to DPU plane
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 ++
>>   1 file changed, 2 insertions(+)
> 
> This should be the last commit.

Hi Dmitry,

Acked, will move this to the end.

Thanks,

Jessica Zhang

> Otherwise:
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index c2aaaded07ed..5f0984ce62b1 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -1429,6 +1429,8 @@ struct drm_plane *dpu_plane_init(struct 
>> drm_device *dev,
>>           DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
>>       drm_plane_create_alpha_property(plane);
>> +    drm_plane_create_solid_fill_property(plane);
>> +    drm_plane_create_pixel_source_property(plane, 
>> BIT(DRM_PLANE_PIXEL_SOURCE_COLOR));
>>       drm_plane_create_blend_mode_property(plane,
>>               BIT(DRM_MODE_BLEND_PIXEL_NONE) |
>>               BIT(DRM_MODE_BLEND_PREMULTI) |
>>
> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 5/7] drm/msm/dpu: Add solid fill and pixel source properties
@ 2023-06-30 23:41       ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-06-30 23:41 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno



On 6/29/2023 5:49 PM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Add solid_fill and pixel_source properties to DPU plane
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 ++
>>   1 file changed, 2 insertions(+)
> 
> This should be the last commit.

Hi Dmitry,

Acked, will move this to the end.

Thanks,

Jessica Zhang

> Otherwise:
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index c2aaaded07ed..5f0984ce62b1 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -1429,6 +1429,8 @@ struct drm_plane *dpu_plane_init(struct 
>> drm_device *dev,
>>           DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
>>       drm_plane_create_alpha_property(plane);
>> +    drm_plane_create_solid_fill_property(plane);
>> +    drm_plane_create_pixel_source_property(plane, 
>> BIT(DRM_PLANE_PIXEL_SOURCE_COLOR));
>>       drm_plane_create_blend_mode_property(plane,
>>               BIT(DRM_MODE_BLEND_PIXEL_NONE) |
>>               BIT(DRM_MODE_BLEND_PREMULTI) |
>>
> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit
  2023-06-30  8:21       ` Pekka Paalanen
@ 2023-07-01  1:14         ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-01  1:14 UTC (permalink / raw)
  To: Pekka Paalanen, Dmitry Baryshkov
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Sean Paul,
	Marijn Suijten, quic_abhinavk, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel



On 6/30/2023 1:21 AM, Pekka Paalanen wrote:
> On Fri, 30 Jun 2023 03:52:37 +0300
> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
> 
>> On 30/06/2023 03:25, Jessica Zhang wrote:
>>> Since solid fill planes allow for a NULL framebuffer in a valid commit,
>>> add NULL framebuffer checks to atomic commit calls within DPU.
>>>
>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>> ---
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++++++-
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++++++++------------
>>>    2 files changed, 36 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> index 1edf2b6b0a26..d1b37d2cc202 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> @@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>    	struct drm_plane_state *state;
>>>    	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
>>>    	struct dpu_plane_state *pstate = NULL;
>>> +	const struct msm_format *fmt;
>>>    	struct dpu_format *format;
>>>    	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>>>    
>>> @@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>    		pstate = to_dpu_plane_state(state);
>>>    		fb = state->fb;
>>>    
>>> -		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>>> +		if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
>>> +			fmt = msm_framebuffer_format(pstate->base.fb);
>>> +		else
>>> +			fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
>>> +					DRM_FORMAT_RGBA8888, 0);
>>
>> The DRM_FORMAT_RGBA8888 should be defined somewhere in patch 1 as format
>> for the solid_fill, then that define can be used in this patch.
> 
> Isn't this just a driver-specific decision to convert a RGB323232
> solid_fill to be presented as a RGBA8888?

Hi Dmitry and Pekka,

Yes, the ABGR8888 format is specific to msm/dpu. In earlier revisions of 
the series, we had come to an agreement that the solid fill property 
should take RGB323232 to match the similar Wayland single pixel buffer 
protocol [1].

[1] 
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/104

> 
> Though, below there is ABGR8888 used for something... inconsistent?

Typo on my part. The format should be consistently ABGR8888.

Thanks,

Jessica Zhang

> 
> 
> Thanks,
> pq
> 
>>
>>> +
>>> +		format = to_dpu_format(fmt);
>>>    
>>>    		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
>>>    			bg_alpha_enable = true;
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index 5f0984ce62b1..4476722f03bb 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>    
>>>    	pipe_cfg->dst_rect = new_plane_state->dst;
>>>    
>>> -	fb_rect.x2 = new_plane_state->fb->width;
>>> -	fb_rect.y2 = new_plane_state->fb->height;
>>> +	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && new_plane_state->fb) {
>>> +		fb_rect.x2 = new_plane_state->fb->width;
>>> +		fb_rect.y2 = new_plane_state->fb->height;
>>> +	}
>>>    
>>>    	/* Ensure fb size is supported */
>>>    	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
>>> @@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>    		return -E2BIG;
>>>    	}
>>>    
>>> -	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>> -
>>>    	max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>    
>>> +	if (drm_plane_solid_fill_enabled(new_plane_state))
>>> +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>> +	else
>>> +		fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>> +
>>>    	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
>>>    		/*
>>>    		 * In parallel multirect case only the half of the usual width
>>> @@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>    	struct drm_crtc *crtc = state->crtc;
>>>    	struct drm_framebuffer *fb = state->fb;
>>>    	bool is_rt_pipe;
>>> -	const struct dpu_format *fmt =
>>> -		to_dpu_format(msm_framebuffer_format(fb));
>>> +	const struct dpu_format *fmt;
>>>    	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>    	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>    	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>>>    	struct msm_gem_address_space *aspace = kms->base.aspace;
>>>    	struct dpu_hw_fmt_layout layout;
>>>    	bool layout_valid = false;
>>> -	int ret;
>>>    
>>> -	ret = dpu_format_populate_layout(aspace, fb, &layout);
>>> -	if (ret)
>>> -		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>>> -	else
>>> -		layout_valid = true;
>>> +	if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
>>> +		int ret;
>>> +
>>> +		fmt = to_dpu_format(msm_framebuffer_format(fb));
>>> +
>>> +		ret = dpu_format_populate_layout(aspace, fb, &layout);
>>> +		if (ret)
>>> +			DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>>> +		else
>>> +			layout_valid = true;
>>> +
>>> +		DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
>>> +				", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
>>> +				crtc->base.id, DRM_RECT_ARG(&state->dst),
>>> +				(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
>>> +	} else {
>>> +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>> +	}
>>>    
>>>    	pstate->pending = true;
>>>    
>>> @@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>    	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>>>    	pdpu->is_rt_pipe = is_rt_pipe;
>>>    
>>> -	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
>>> -			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
>>> -			crtc->base.id, DRM_RECT_ARG(&state->dst),
>>> -			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
>>> -
>>>    	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
>>>    				   drm_mode_vrefresh(&crtc->mode),
>>>    				   layout_valid ? &layout : NULL);
>>>    
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit
@ 2023-07-01  1:14         ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-01  1:14 UTC (permalink / raw)
  To: Pekka Paalanen, Dmitry Baryshkov
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Marijn Suijten, wayland-devel



On 6/30/2023 1:21 AM, Pekka Paalanen wrote:
> On Fri, 30 Jun 2023 03:52:37 +0300
> Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote:
> 
>> On 30/06/2023 03:25, Jessica Zhang wrote:
>>> Since solid fill planes allow for a NULL framebuffer in a valid commit,
>>> add NULL framebuffer checks to atomic commit calls within DPU.
>>>
>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>> ---
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  9 ++++++-
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++++++++------------
>>>    2 files changed, 36 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> index 1edf2b6b0a26..d1b37d2cc202 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> @@ -451,6 +451,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>    	struct drm_plane_state *state;
>>>    	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
>>>    	struct dpu_plane_state *pstate = NULL;
>>> +	const struct msm_format *fmt;
>>>    	struct dpu_format *format;
>>>    	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>>>    
>>> @@ -470,7 +471,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>    		pstate = to_dpu_plane_state(state);
>>>    		fb = state->fb;
>>>    
>>> -		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>>> +		if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb)
>>> +			fmt = msm_framebuffer_format(pstate->base.fb);
>>> +		else
>>> +			fmt = dpu_get_msm_format(&_dpu_crtc_get_kms(crtc)->base,
>>> +					DRM_FORMAT_RGBA8888, 0);
>>
>> The DRM_FORMAT_RGBA8888 should be defined somewhere in patch 1 as format
>> for the solid_fill, then that define can be used in this patch.
> 
> Isn't this just a driver-specific decision to convert a RGB323232
> solid_fill to be presented as a RGBA8888?

Hi Dmitry and Pekka,

Yes, the ABGR8888 format is specific to msm/dpu. In earlier revisions of 
the series, we had come to an agreement that the solid fill property 
should take RGB323232 to match the similar Wayland single pixel buffer 
protocol [1].

[1] 
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/104

> 
> Though, below there is ABGR8888 used for something... inconsistent?

Typo on my part. The format should be consistently ABGR8888.

Thanks,

Jessica Zhang

> 
> 
> Thanks,
> pq
> 
>>
>>> +
>>> +		format = to_dpu_format(fmt);
>>>    
>>>    		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
>>>    			bg_alpha_enable = true;
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index 5f0984ce62b1..4476722f03bb 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -837,8 +837,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>    
>>>    	pipe_cfg->dst_rect = new_plane_state->dst;
>>>    
>>> -	fb_rect.x2 = new_plane_state->fb->width;
>>> -	fb_rect.y2 = new_plane_state->fb->height;
>>> +	if (new_plane_state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && new_plane_state->fb) {
>>> +		fb_rect.x2 = new_plane_state->fb->width;
>>> +		fb_rect.y2 = new_plane_state->fb->height;
>>> +	}
>>>    
>>>    	/* Ensure fb size is supported */
>>>    	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
>>> @@ -848,10 +850,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>    		return -E2BIG;
>>>    	}
>>>    
>>> -	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>> -
>>>    	max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>    
>>> +	if (drm_plane_solid_fill_enabled(new_plane_state))
>>> +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>> +	else
>>> +		fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>> +
>>>    	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
>>>    		/*
>>>    		 * In parallel multirect case only the half of the usual width
>>> @@ -1082,21 +1087,32 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>    	struct drm_crtc *crtc = state->crtc;
>>>    	struct drm_framebuffer *fb = state->fb;
>>>    	bool is_rt_pipe;
>>> -	const struct dpu_format *fmt =
>>> -		to_dpu_format(msm_framebuffer_format(fb));
>>> +	const struct dpu_format *fmt;
>>>    	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>    	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>    	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>>>    	struct msm_gem_address_space *aspace = kms->base.aspace;
>>>    	struct dpu_hw_fmt_layout layout;
>>>    	bool layout_valid = false;
>>> -	int ret;
>>>    
>>> -	ret = dpu_format_populate_layout(aspace, fb, &layout);
>>> -	if (ret)
>>> -		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>>> -	else
>>> -		layout_valid = true;
>>> +	if (state->pixel_source == DRM_PLANE_PIXEL_SOURCE_FB && fb) {
>>> +		int ret;
>>> +
>>> +		fmt = to_dpu_format(msm_framebuffer_format(fb));
>>> +
>>> +		ret = dpu_format_populate_layout(aspace, fb, &layout);
>>> +		if (ret)
>>> +			DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>>> +		else
>>> +			layout_valid = true;
>>> +
>>> +		DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
>>> +				", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
>>> +				crtc->base.id, DRM_RECT_ARG(&state->dst),
>>> +				(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
>>> +	} else {
>>> +		fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>> +	}
>>>    
>>>    	pstate->pending = true;
>>>    
>>> @@ -1104,11 +1120,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>    	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>>>    	pdpu->is_rt_pipe = is_rt_pipe;
>>>    
>>> -	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
>>> -			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
>>> -			crtc->base.id, DRM_RECT_ARG(&state->dst),
>>> -			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
>>> -
>>>    	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
>>>    				   drm_mode_vrefresh(&crtc->mode),
>>>    				   layout_valid ? &layout : NULL);
>>>    
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
  2023-06-30  0:59     ` Dmitry Baryshkov
@ 2023-07-01  1:26       ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-01  1:26 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: quic_abhinavk, ppaalanen, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel



On 6/29/2023 5:59 PM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
>> determine if the plane is solid fill. In addition drop the DPU plane
>> color_fill field as we can now use drm_plane_state.solid_fill instead,
>> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
>> allow userspace to configure the alpha value for the solid fill color.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> Minor suggestion below.
> 
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
>>   1 file changed, 15 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 4476722f03bb..11d4fb771a1f 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -42,7 +42,6 @@
>>   #define SHARP_SMOOTH_THR_DEFAULT    8
>>   #define SHARP_NOISE_THR_DEFAULT    2
>> -#define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
>>   #define DPU_ZPOS_MAX 255
>>   /*
>> @@ -82,7 +81,6 @@ struct dpu_plane {
>>       enum dpu_sspp pipe;
>> -    uint32_t color_fill;
>>       bool is_error;
>>       bool is_rt_pipe;
>>       const struct dpu_mdss_cfg *catalog;
>> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct 
>> dpu_plane_state *pstate,
>>       _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, 
>> pstate->rotation);
>>   }
>> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill 
>> solid_fill)
> 
> Please consider accepting drm_plane_state instead and handling alpha 
> here. Then _dpu_color_fill can accept rgba colour instead of separate 
> RGB and alpha values.

Hi Dmitry,

Do you mean adding a patch to refactor _dpu_plane_color_fill() to accept 
an RGBA8888 color?

Since, currently, the `color` parameter gets truncated to a BGR888 value 
and OR'd with the `alpha` parameter [1].

Thanks,

Jessica Zhang

[1] 
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c#L682

> 
>> +{
>> +    uint32_t ret = 0;
>> +
>> +    ret |= ((uint8_t) solid_fill.b) << 16;
>> +    ret |= ((uint8_t) solid_fill.g) << 8;
>> +    ret |= ((uint8_t) solid_fill.r);
>> +
>> +    return ret;
>> +}
>> +
>>   /**
>>    * _dpu_plane_color_fill - enables color fill on plane
>>    * @pdpu:   Pointer to DPU plane object
>> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>>       if (pdpu->is_error)
>>           /* force white frame with 100% alpha pipe output on error */
>>           _dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
>> -    else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>> -        /* force 100% alpha */
>> -        _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>> +    else if (drm_plane_solid_fill_enabled(plane->state))
>> +        _dpu_plane_color_fill(pdpu, 
>> _dpu_plane_get_fill_color(plane->state->solid_fill),
>> +                plane->state->alpha);
>>       else {
>>           dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>           dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
>> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct 
>> drm_plane *plane,
>>       }
>>       /* override for color fill */
>> -    if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
>> +    if (drm_plane_solid_fill_enabled(plane->state)) {
>>           _dpu_plane_set_qos_ctrl(plane, pipe, false);
>>           /* skip remaining processing on color fill */
>>
> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
@ 2023-07-01  1:26       ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-01  1:26 UTC (permalink / raw)
  To: Dmitry Baryshkov, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten
  Cc: sebastian.wick, quic_abhinavk, dri-devel, linux-kernel,
	ppaalanen, laurent.pinchart, linux-arm-msm, wayland-devel,
	freedreno



On 6/29/2023 5:59 PM, Dmitry Baryshkov wrote:
> On 30/06/2023 03:25, Jessica Zhang wrote:
>> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
>> determine if the plane is solid fill. In addition drop the DPU plane
>> color_fill field as we can now use drm_plane_state.solid_fill instead,
>> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
>> allow userspace to configure the alpha value for the solid fill color.
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> Minor suggestion below.
> 
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
>>   1 file changed, 15 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 4476722f03bb..11d4fb771a1f 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -42,7 +42,6 @@
>>   #define SHARP_SMOOTH_THR_DEFAULT    8
>>   #define SHARP_NOISE_THR_DEFAULT    2
>> -#define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
>>   #define DPU_ZPOS_MAX 255
>>   /*
>> @@ -82,7 +81,6 @@ struct dpu_plane {
>>       enum dpu_sspp pipe;
>> -    uint32_t color_fill;
>>       bool is_error;
>>       bool is_rt_pipe;
>>       const struct dpu_mdss_cfg *catalog;
>> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct 
>> dpu_plane_state *pstate,
>>       _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, 
>> pstate->rotation);
>>   }
>> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill 
>> solid_fill)
> 
> Please consider accepting drm_plane_state instead and handling alpha 
> here. Then _dpu_color_fill can accept rgba colour instead of separate 
> RGB and alpha values.

Hi Dmitry,

Do you mean adding a patch to refactor _dpu_plane_color_fill() to accept 
an RGBA8888 color?

Since, currently, the `color` parameter gets truncated to a BGR888 value 
and OR'd with the `alpha` parameter [1].

Thanks,

Jessica Zhang

[1] 
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c#L682

> 
>> +{
>> +    uint32_t ret = 0;
>> +
>> +    ret |= ((uint8_t) solid_fill.b) << 16;
>> +    ret |= ((uint8_t) solid_fill.g) << 8;
>> +    ret |= ((uint8_t) solid_fill.r);
>> +
>> +    return ret;
>> +}
>> +
>>   /**
>>    * _dpu_plane_color_fill - enables color fill on plane
>>    * @pdpu:   Pointer to DPU plane object
>> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>>       if (pdpu->is_error)
>>           /* force white frame with 100% alpha pipe output on error */
>>           _dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
>> -    else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>> -        /* force 100% alpha */
>> -        _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>> +    else if (drm_plane_solid_fill_enabled(plane->state))
>> +        _dpu_plane_color_fill(pdpu, 
>> _dpu_plane_get_fill_color(plane->state->solid_fill),
>> +                plane->state->alpha);
>>       else {
>>           dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>           dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
>> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct 
>> drm_plane *plane,
>>       }
>>       /* override for color fill */
>> -    if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
>> +    if (drm_plane_solid_fill_enabled(plane->state)) {
>>           _dpu_plane_set_qos_ctrl(plane, pipe, false);
>>           /* skip remaining processing on color fill */
>>
> 
> -- 
> With best wishes
> Dmitry
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
  2023-06-30  8:26     ` Pekka Paalanen
@ 2023-07-03  7:42       ` Pekka Paalanen
  -1 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-07-03  7:42 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten, quic_abhinavk, contact,
	laurent.pinchart, sebastian.wick, ville.syrjala, dri-devel,
	linux-kernel, linux-arm-msm, freedreno, wayland-devel

[-- Attachment #1: Type: text/plain, Size: 3790 bytes --]

On Fri, 30 Jun 2023 11:26:49 +0300
Pekka Paalanen <ppaalanen@gmail.com> wrote:

> On Thu, 29 Jun 2023 17:25:06 -0700
> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> 
> > Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
> > determine if the plane is solid fill. In addition drop the DPU plane
> > color_fill field as we can now use drm_plane_state.solid_fill instead,
> > and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
> > allow userspace to configure the alpha value for the solid fill color.
> > 
> > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
> >  1 file changed, 15 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 4476722f03bb..11d4fb771a1f 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -42,7 +42,6 @@
> >  #define SHARP_SMOOTH_THR_DEFAULT	8
> >  #define SHARP_NOISE_THR_DEFAULT	2
> >  
> > -#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
> >  #define DPU_ZPOS_MAX 255
> >  
> >  /*
> > @@ -82,7 +81,6 @@ struct dpu_plane {
> >  
> >  	enum dpu_sspp pipe;
> >  
> > -	uint32_t color_fill;
> >  	bool is_error;
> >  	bool is_rt_pipe;
> >  	const struct dpu_mdss_cfg *catalog;
> > @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> >  	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
> >  }
> >  
> > +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
> > +{
> > +	uint32_t ret = 0;
> > +
> > +	ret |= ((uint8_t) solid_fill.b) << 16;
> > +	ret |= ((uint8_t) solid_fill.g) << 8;
> > +	ret |= ((uint8_t) solid_fill.r);  
> 
> solid_fill.r, g and b are uint32_t, yes?
> 
> What's the value encoding in the UAPI? That doc was missing.
> 
> I wouldn't expect the UAPI to use 32-bit variables if it was
> essentially 8-bit, so this conversion looks wrong.
> 
> Nominal color value 1.0 in u8 is 0xff. The same in u32 is probably
> 0xffffffff? So a simple cast to u8 won't work. You'd want to take the
> upper 8 bits instead.
> 
> 
> Thanks,
> pq
> 
> > +
> > +	return ret;

Btw. if your driver format is ABGR, then this function leaves alpha as
zero. That's confusing.

It would be nice to mention the exact pixel format in the function name
so the consistency is easier to check in both here and in callers.


Thanks,
pq

> > +}
> > +
> >  /**
> >   * _dpu_plane_color_fill - enables color fill on plane
> >   * @pdpu:   Pointer to DPU plane object
> > @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
> >  	if (pdpu->is_error)
> >  		/* force white frame with 100% alpha pipe output on error */
> >  		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
> > -	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
> > -		/* force 100% alpha */
> > -		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> > +	else if (drm_plane_solid_fill_enabled(plane->state))
> > +		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
> > +				plane->state->alpha);
> >  	else {
> >  		dpu_plane_flush_csc(pdpu, &pstate->pipe);
> >  		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> > @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
> >  	}
> >  
> >  	/* override for color fill */
> > -	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
> > +	if (drm_plane_solid_fill_enabled(plane->state)) {
> >  		_dpu_plane_set_qos_ctrl(plane, pipe, false);
> >  
> >  		/* skip remaining processing on color fill */
> >   
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
@ 2023-07-03  7:42       ` Pekka Paalanen
  0 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-07-03  7:42 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Dmitry Baryshkov, Marijn Suijten,
	wayland-devel

[-- Attachment #1: Type: text/plain, Size: 3790 bytes --]

On Fri, 30 Jun 2023 11:26:49 +0300
Pekka Paalanen <ppaalanen@gmail.com> wrote:

> On Thu, 29 Jun 2023 17:25:06 -0700
> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> 
> > Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
> > determine if the plane is solid fill. In addition drop the DPU plane
> > color_fill field as we can now use drm_plane_state.solid_fill instead,
> > and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
> > allow userspace to configure the alpha value for the solid fill color.
> > 
> > Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
> >  1 file changed, 15 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 4476722f03bb..11d4fb771a1f 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -42,7 +42,6 @@
> >  #define SHARP_SMOOTH_THR_DEFAULT	8
> >  #define SHARP_NOISE_THR_DEFAULT	2
> >  
> > -#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
> >  #define DPU_ZPOS_MAX 255
> >  
> >  /*
> > @@ -82,7 +81,6 @@ struct dpu_plane {
> >  
> >  	enum dpu_sspp pipe;
> >  
> > -	uint32_t color_fill;
> >  	bool is_error;
> >  	bool is_rt_pipe;
> >  	const struct dpu_mdss_cfg *catalog;
> > @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> >  	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
> >  }
> >  
> > +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
> > +{
> > +	uint32_t ret = 0;
> > +
> > +	ret |= ((uint8_t) solid_fill.b) << 16;
> > +	ret |= ((uint8_t) solid_fill.g) << 8;
> > +	ret |= ((uint8_t) solid_fill.r);  
> 
> solid_fill.r, g and b are uint32_t, yes?
> 
> What's the value encoding in the UAPI? That doc was missing.
> 
> I wouldn't expect the UAPI to use 32-bit variables if it was
> essentially 8-bit, so this conversion looks wrong.
> 
> Nominal color value 1.0 in u8 is 0xff. The same in u32 is probably
> 0xffffffff? So a simple cast to u8 won't work. You'd want to take the
> upper 8 bits instead.
> 
> 
> Thanks,
> pq
> 
> > +
> > +	return ret;

Btw. if your driver format is ABGR, then this function leaves alpha as
zero. That's confusing.

It would be nice to mention the exact pixel format in the function name
so the consistency is easier to check in both here and in callers.


Thanks,
pq

> > +}
> > +
> >  /**
> >   * _dpu_plane_color_fill - enables color fill on plane
> >   * @pdpu:   Pointer to DPU plane object
> > @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
> >  	if (pdpu->is_error)
> >  		/* force white frame with 100% alpha pipe output on error */
> >  		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
> > -	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
> > -		/* force 100% alpha */
> > -		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> > +	else if (drm_plane_solid_fill_enabled(plane->state))
> > +		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
> > +				plane->state->alpha);
> >  	else {
> >  		dpu_plane_flush_csc(pdpu, &pstate->pipe);
> >  		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> > @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
> >  	}
> >  
> >  	/* override for color fill */
> > -	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
> > +	if (drm_plane_solid_fill_enabled(plane->state)) {
> >  		_dpu_plane_set_qos_ctrl(plane, pipe, false);
> >  
> >  		/* skip remaining processing on color fill */
> >   
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-06-30 21:27       ` Jessica Zhang
@ 2023-07-03 11:49         ` Sebastian Wick
  -1 siblings, 0 replies; 80+ messages in thread
From: Sebastian Wick @ 2023-07-03 11:49 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: freedreno, ppaalanen, Thomas Zimmermann, Sean Paul,
	quic_abhinavk, Maxime Ripard, linux-kernel, dri-devel,
	linux-arm-msm, Dmitry Baryshkov, Marijn Suijten, wayland-devel,
	laurent.pinchart

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
> >>
> >
>


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-07-03 11:49         ` Sebastian Wick
  0 siblings, 0 replies; 80+ messages in thread
From: Sebastian Wick @ 2023-07-03 11:49 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten, quic_abhinavk, dri-devel,
	linux-kernel, ppaalanen, laurent.pinchart, linux-arm-msm,
	wayland-devel, freedreno

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
> >>
> >
>


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-06-30  8:27       ` Pekka Paalanen
@ 2023-07-10 19:51         ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-10 19:51 UTC (permalink / raw)
  To: Pekka Paalanen, Dmitry Baryshkov
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Sean Paul,
	Marijn Suijten, quic_abhinavk, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel



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
>>>    
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-07-10 19:51         ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-10 19:51 UTC (permalink / raw)
  To: Pekka Paalanen, Dmitry Baryshkov
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Marijn Suijten, wayland-devel



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
>>>    
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-07-10 19:51         ` Jessica Zhang
@ 2023-07-10 20:11           ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-07-10 20:11 UTC (permalink / raw)
  To: Jessica Zhang, Pekka Paalanen
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Sean Paul,
	Marijn Suijten, quic_abhinavk, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

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]

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-07-10 20:11           ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-07-10 20:11 UTC (permalink / raw)
  To: Jessica Zhang, Pekka Paalanen
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Marijn Suijten, wayland-devel

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]

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Freedreno] [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
  2023-06-30  8:27     ` Pekka Paalanen
@ 2023-07-10 23:12       ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-10 23:12 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, Maarten Lankhorst, quic_abhinavk,
	Maxime Ripard, linux-kernel, Rob Clark, laurent.pinchart,
	Daniel Vetter, Dmitry Baryshkov, contact, Marijn Suijten,
	wayland-devel, David Airlie, ville.syrjala



On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
> On Thu, 29 Jun 2023 17:25:00 -0700
> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> 
>> Document and add support for solid_fill property to drm_plane. In
>> addition, add support for setting and getting the values for solid_fill.
>>
>> To enable solid fill planes, userspace must assign a property blob to
>> the "solid_fill" plane property containing the following information:
>>
>> struct drm_solid_fill_info {
>> 	u8 version;
>> 	u32 r, g, b;
>> };
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> 
> Hi Jessica,
> 
> I've left some general UAPI related comments here.
> 
>> ---
>>   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>>   drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>>   include/drm/drm_blend.h                   |  1 +
>>   include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>>   5 files changed, 141 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
>> index 784e63d70a42..fe14be2bd2b2 100644
>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>> @@ -253,6 +253,11 @@ 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;
>>   
>> +	if (plane_state->solid_fill_blob) {
>> +		drm_property_blob_put(plane_state->solid_fill_blob);
>> +		plane_state->solid_fill_blob = NULL;
>> +	}
>> +
>>   	if (plane->color_encoding_property) {
>>   		if (!drm_object_property_get_default_value(&plane->base,
>>   							   plane->color_encoding_property,
>> @@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
>>   	if (state->fb)
>>   		drm_framebuffer_get(state->fb);
>>   
>> +	if (state->solid_fill_blob)
>> +		drm_property_blob_get(state->solid_fill_blob);
>> +
>>   	state->fence = NULL;
>>   	state->commit = NULL;
>>   	state->fb_damage_clips = NULL;
>> @@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
>>   		drm_crtc_commit_put(state->commit);
>>   
>>   	drm_property_blob_put(state->fb_damage_clips);
>> +	drm_property_blob_put(state->solid_fill_blob);
>>   }
>>   EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
>>   
>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
>> index d867e7f9f2cd..a28b4ee79444 100644
>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>> @@ -316,6 +316,51 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
>>   }
>>   EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
>>   
>> +static int drm_atomic_set_solid_fill_prop(struct drm_plane_state *state,
>> +		struct drm_property_blob *blob)
>> +{
>> +	int ret = 0;
>> +	int blob_version;
>> +
>> +	if (blob == state->solid_fill_blob)
>> +		return 0;
>> +
>> +	drm_property_blob_put(state->solid_fill_blob);
>> +	state->solid_fill_blob = NULL;
> 
> Is it ok to destroy old state before it is guaranteed that the new
> state is accepted?

Hi Pekka,

Good point. I'll change this behavior so that an error case will keep 
the old solid_fill_blob value.

> 
>> +
>> +	memset(&state->solid_fill, 0, sizeof(state->solid_fill));
>> +
>> +	if (blob) {
>> +		struct drm_solid_fill_info *user_info = (struct drm_solid_fill_info *)blob->data;
>> +
>> +		if (blob->length != sizeof(struct drm_solid_fill_info)) {
>> +			drm_dbg_atomic(state->plane->dev,
>> +				       "[PLANE:%d:%s] bad solid fill blob length: %zu\n",
>> +				       state->plane->base.id, state->plane->name,
>> +				       blob->length);
>> +			return -EINVAL;
>> +		}
>> +
>> +		blob_version = user_info->version;
>> +
>> +		/* Add more versions if necessary */
>> +		if (blob_version == 1) {
>> +			state->solid_fill.r = user_info->r;
>> +			state->solid_fill.g = user_info->g;
>> +			state->solid_fill.b = user_info->b;
>> +		} else {
>> +			drm_dbg_atomic(state->plane->dev,
>> +				       "[PLANE:%d:%s] failed to set solid fill (ret=%d)\n",
>> +				       state->plane->base.id, state->plane->name,
>> +				       ret);
>> +			return -EINVAL;
> 
> Btw. how does the atomic check machinery work here?
> 
> I expect that a TEST_ONLY atomic commit will do all the above checks
> and return failure if anything is not right. Right?

Correct, drm_atomic_set_property() will still be called for a TEST_ONLY 
commit, so these checks will still happen and return an error (or set 
the property) when appropriate.

> 
>> +		}
>> +		state->solid_fill_blob = drm_property_blob_get(blob);
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>>   static void set_out_fence_for_crtc(struct drm_atomic_state *state,
>>   				   struct drm_crtc *crtc, s32 __user *fence_ptr)
>>   {
>> @@ -544,6 +589,13 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
>>   		state->src_w = val;
>>   	} else if (property == config->prop_src_h) {
>>   		state->src_h = val;
>> +	} else if (property == plane->solid_fill_property) {
>> +		struct drm_property_blob *solid_fill = drm_property_lookup_blob(dev, val);
>> +
>> +		ret = drm_atomic_set_solid_fill_prop(state, solid_fill);
>> +		drm_property_blob_put(solid_fill);
>> +
>> +		return ret;
>>   	} else if (property == plane->alpha_property) {
>>   		state->alpha = val;
>>   	} else if (property == plane->blend_mode_property) {
>> @@ -616,6 +668,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>>   		*val = state->src_w;
>>   	} else if (property == config->prop_src_h) {
>>   		*val = state->src_h;
>> +	} else if (property == plane->solid_fill_property) {
>> +		*val = state->solid_fill_blob ?
>> +			state->solid_fill_blob->base.id : 0;
>>   	} 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 6e74de833466..38c3c5d6453a 100644
>> --- a/drivers/gpu/drm/drm_blend.c
>> +++ b/drivers/gpu/drm/drm_blend.c
>> @@ -185,6 +185,10 @@
>>    *		 plane does not expose the "alpha" property, then this is
>>    *		 assumed to be 1.0
>>    *
>> + * solid_fill:
>> + *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
>> + *	contains pixel data that drivers can use to fill a plane.
> 
> This is a nice start, but I feel it needs to explain much more about
> how userspace should go about making use of this.
> 
> Yeah, the pixel_source property comes in the next patch, but I feel
> that it is harder to review if the doc is built over multiple patches.
> My personal approach would be to write the doc in full and referring to
> pixel_source property already, and explain in the commit message that
> the next patch will add pixel_source so people don't wonder about
> referring to a non-existing property.
> 
> I mean just a reference to pixel_source, and leave the actual
> pixel_source doc for the patch adding the property like it already is.
> 
> Dmitry's suggestion of swapping the patch order is good too.

Makes sense. I'll switch the patch order, but will keep this in mind.

> 
>> + *
>>    * 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).
>> @@ -615,3 +619,32 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>>   	return 0;
>>   }
>>   EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
>> +
>> +/**
>> + * drm_plane_create_solid_fill_property - create a new solid_fill property
>> + * @plane: drm plane
>> + *
>> + * This creates a new property that holds pixel data for solid fill planes. This
>> + * property is exposed to userspace as a property blob called "solid_fill".
>> + *
>> + * For information on what the blob contains, see `drm_solid_fill_info`.
> 
> I think you should be more explicit here. For example: the blob must
> contain exactly one struct drm_solid_fill_info.
> 
> It's better to put this content spec with the UAPI doc rather than in this
> kerner-internal function doc that userspace programmers won't know to
> look at.

Acked.

> 
>> + *
>> + * Returns:
>> + * Zero on success, negative errno on failure.
>> + */
>> +int drm_plane_create_solid_fill_property(struct drm_plane *plane)
>> +{
>> +	struct drm_property *prop;
>> +
>> +	prop = drm_property_create(plane->dev,
>> +			DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
>> +			"solid_fill", 0);
>> +	if (!prop)
>> +		return -ENOMEM;
>> +
>> +	drm_object_attach_property(&plane->base, prop, 0);
>> +	plane->solid_fill_property = prop;
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
>> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
>> index 88bdfec3bd88..0338a860b9c8 100644
>> --- a/include/drm/drm_blend.h
>> +++ b/include/drm/drm_blend.h
>> @@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>>   			      struct drm_atomic_state *state);
>>   int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>>   					 unsigned int supported_modes);
>> +int drm_plane_create_solid_fill_property(struct drm_plane *plane);
>>   #endif
>> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
>> index 51291983ea44..f6ab313cb83e 100644
>> --- a/include/drm/drm_plane.h
>> +++ b/include/drm/drm_plane.h
>> @@ -40,6 +40,25 @@ enum drm_scaling_filter {
>>   	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
>>   };
>>   
>> +/**
>> + * struct drm_solid_fill_info - User info for solid fill planes
>> + */
>> +struct drm_solid_fill_info {
>> +	__u8 version;
>> +	__u32 r, g, b;
>> +};
> 
> Shouldn't UAPI structs be in UAPI headers?

Acked, will move this to uapi/drm_mode.h

> 
> Shouldn't UAPI structs use explicit padding to not leave any gaps when
> it's unavoidable? And the kernel to check that the gaps are indeed
> zeroed?

I don't believe so... From my understanding, padding will be taken care 
of by the compiler by default. Looking at the drm_mode_modeinfo UAPI 
struct [1], it also doesn't seem to do explicit padding. And the 
corresponding set_property() code doesn't seem check the gaps either.

That being said, it's possible that I'm missing something here, so 
please let me know if that's the case.

[1] 
https://elixir.bootlin.com/linux/v6.5-rc1/source/include/uapi/drm/drm_mode.h#L242

> 
> It also needs more UAPI doc, like a link to the property doc that uses
> this and an explanation of what the values mean.

Acked.

Thanks,

Jessica Zhang

> 
> 
> Thanks,
> pq
> 
>> +
>> +/**
>> + * struct solid_fill_property - RGB values for solid fill plane
>> + *
>> + * Note: This is the V1 for this feature
>> + */
>> +struct drm_solid_fill {
>> +	uint32_t r;
>> +	uint32_t g;
>> +	uint32_t b;
>> +};
>> +
>>   /**
>>    * struct drm_plane_state - mutable plane state
>>    *
>> @@ -116,6 +135,23 @@ struct drm_plane_state {
>>   	/** @src_h: height of visible portion of plane (in 16.16) */
>>   	uint32_t src_h, src_w;
>>   
>> +	/**
>> +	 * @solid_fill_blob:
>> +	 *
>> +	 * Blob containing relevant information for a solid fill plane
>> +	 * including pixel format and data. See
>> +	 * drm_plane_create_solid_fill_property() for more details.
>> +	 */
>> +	struct drm_property_blob *solid_fill_blob;
>> +
>> +	/**
>> +	 * @solid_fill:
>> +	 *
>> +	 * Pixel data for solid fill planes. See
>> +	 * drm_plane_create_solid_fill_property() for more details.
>> +	 */
>> +	struct drm_solid_fill solid_fill;
>> +
>>   	/**
>>   	 * @alpha:
>>   	 * Opacity of the plane with 0 as completely transparent and 0xffff as
>> @@ -699,6 +735,13 @@ struct drm_plane {
>>   	 */
>>   	struct drm_plane_state *state;
>>   
>> +	/*
>> +	 * @solid_fill_property:
>> +	 * Optional solid_fill property for this plane. See
>> +	 * drm_plane_create_solid_fill_property().
>> +	 */
>> +	struct drm_property *solid_fill_property;
>> +
>>   	/**
>>   	 * @alpha_property:
>>   	 * Optional alpha property for this plane. See
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Freedreno] [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
@ 2023-07-10 23:12       ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-10 23:12 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: freedreno, sebastian.wick, linux-arm-msm, quic_abhinavk,
	dri-devel, linux-kernel, Maxime Ripard, Thomas Zimmermann,
	Dmitry Baryshkov, Marijn Suijten, wayland-devel, Sean Paul,
	laurent.pinchart



On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
> On Thu, 29 Jun 2023 17:25:00 -0700
> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> 
>> Document and add support for solid_fill property to drm_plane. In
>> addition, add support for setting and getting the values for solid_fill.
>>
>> To enable solid fill planes, userspace must assign a property blob to
>> the "solid_fill" plane property containing the following information:
>>
>> struct drm_solid_fill_info {
>> 	u8 version;
>> 	u32 r, g, b;
>> };
>>
>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
> 
> Hi Jessica,
> 
> I've left some general UAPI related comments here.
> 
>> ---
>>   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>>   drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>>   include/drm/drm_blend.h                   |  1 +
>>   include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>>   5 files changed, 141 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
>> index 784e63d70a42..fe14be2bd2b2 100644
>> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
>> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
>> @@ -253,6 +253,11 @@ 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;
>>   
>> +	if (plane_state->solid_fill_blob) {
>> +		drm_property_blob_put(plane_state->solid_fill_blob);
>> +		plane_state->solid_fill_blob = NULL;
>> +	}
>> +
>>   	if (plane->color_encoding_property) {
>>   		if (!drm_object_property_get_default_value(&plane->base,
>>   							   plane->color_encoding_property,
>> @@ -335,6 +340,9 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
>>   	if (state->fb)
>>   		drm_framebuffer_get(state->fb);
>>   
>> +	if (state->solid_fill_blob)
>> +		drm_property_blob_get(state->solid_fill_blob);
>> +
>>   	state->fence = NULL;
>>   	state->commit = NULL;
>>   	state->fb_damage_clips = NULL;
>> @@ -384,6 +392,7 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
>>   		drm_crtc_commit_put(state->commit);
>>   
>>   	drm_property_blob_put(state->fb_damage_clips);
>> +	drm_property_blob_put(state->solid_fill_blob);
>>   }
>>   EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
>>   
>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
>> index d867e7f9f2cd..a28b4ee79444 100644
>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>> @@ -316,6 +316,51 @@ drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
>>   }
>>   EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
>>   
>> +static int drm_atomic_set_solid_fill_prop(struct drm_plane_state *state,
>> +		struct drm_property_blob *blob)
>> +{
>> +	int ret = 0;
>> +	int blob_version;
>> +
>> +	if (blob == state->solid_fill_blob)
>> +		return 0;
>> +
>> +	drm_property_blob_put(state->solid_fill_blob);
>> +	state->solid_fill_blob = NULL;
> 
> Is it ok to destroy old state before it is guaranteed that the new
> state is accepted?

Hi Pekka,

Good point. I'll change this behavior so that an error case will keep 
the old solid_fill_blob value.

> 
>> +
>> +	memset(&state->solid_fill, 0, sizeof(state->solid_fill));
>> +
>> +	if (blob) {
>> +		struct drm_solid_fill_info *user_info = (struct drm_solid_fill_info *)blob->data;
>> +
>> +		if (blob->length != sizeof(struct drm_solid_fill_info)) {
>> +			drm_dbg_atomic(state->plane->dev,
>> +				       "[PLANE:%d:%s] bad solid fill blob length: %zu\n",
>> +				       state->plane->base.id, state->plane->name,
>> +				       blob->length);
>> +			return -EINVAL;
>> +		}
>> +
>> +		blob_version = user_info->version;
>> +
>> +		/* Add more versions if necessary */
>> +		if (blob_version == 1) {
>> +			state->solid_fill.r = user_info->r;
>> +			state->solid_fill.g = user_info->g;
>> +			state->solid_fill.b = user_info->b;
>> +		} else {
>> +			drm_dbg_atomic(state->plane->dev,
>> +				       "[PLANE:%d:%s] failed to set solid fill (ret=%d)\n",
>> +				       state->plane->base.id, state->plane->name,
>> +				       ret);
>> +			return -EINVAL;
> 
> Btw. how does the atomic check machinery work here?
> 
> I expect that a TEST_ONLY atomic commit will do all the above checks
> and return failure if anything is not right. Right?

Correct, drm_atomic_set_property() will still be called for a TEST_ONLY 
commit, so these checks will still happen and return an error (or set 
the property) when appropriate.

> 
>> +		}
>> +		state->solid_fill_blob = drm_property_blob_get(blob);
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>>   static void set_out_fence_for_crtc(struct drm_atomic_state *state,
>>   				   struct drm_crtc *crtc, s32 __user *fence_ptr)
>>   {
>> @@ -544,6 +589,13 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
>>   		state->src_w = val;
>>   	} else if (property == config->prop_src_h) {
>>   		state->src_h = val;
>> +	} else if (property == plane->solid_fill_property) {
>> +		struct drm_property_blob *solid_fill = drm_property_lookup_blob(dev, val);
>> +
>> +		ret = drm_atomic_set_solid_fill_prop(state, solid_fill);
>> +		drm_property_blob_put(solid_fill);
>> +
>> +		return ret;
>>   	} else if (property == plane->alpha_property) {
>>   		state->alpha = val;
>>   	} else if (property == plane->blend_mode_property) {
>> @@ -616,6 +668,9 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>>   		*val = state->src_w;
>>   	} else if (property == config->prop_src_h) {
>>   		*val = state->src_h;
>> +	} else if (property == plane->solid_fill_property) {
>> +		*val = state->solid_fill_blob ?
>> +			state->solid_fill_blob->base.id : 0;
>>   	} 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 6e74de833466..38c3c5d6453a 100644
>> --- a/drivers/gpu/drm/drm_blend.c
>> +++ b/drivers/gpu/drm/drm_blend.c
>> @@ -185,6 +185,10 @@
>>    *		 plane does not expose the "alpha" property, then this is
>>    *		 assumed to be 1.0
>>    *
>> + * solid_fill:
>> + *	solid_fill is set up with drm_plane_create_solid_fill_property(). It
>> + *	contains pixel data that drivers can use to fill a plane.
> 
> This is a nice start, but I feel it needs to explain much more about
> how userspace should go about making use of this.
> 
> Yeah, the pixel_source property comes in the next patch, but I feel
> that it is harder to review if the doc is built over multiple patches.
> My personal approach would be to write the doc in full and referring to
> pixel_source property already, and explain in the commit message that
> the next patch will add pixel_source so people don't wonder about
> referring to a non-existing property.
> 
> I mean just a reference to pixel_source, and leave the actual
> pixel_source doc for the patch adding the property like it already is.
> 
> Dmitry's suggestion of swapping the patch order is good too.

Makes sense. I'll switch the patch order, but will keep this in mind.

> 
>> + *
>>    * 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).
>> @@ -615,3 +619,32 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>>   	return 0;
>>   }
>>   EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
>> +
>> +/**
>> + * drm_plane_create_solid_fill_property - create a new solid_fill property
>> + * @plane: drm plane
>> + *
>> + * This creates a new property that holds pixel data for solid fill planes. This
>> + * property is exposed to userspace as a property blob called "solid_fill".
>> + *
>> + * For information on what the blob contains, see `drm_solid_fill_info`.
> 
> I think you should be more explicit here. For example: the blob must
> contain exactly one struct drm_solid_fill_info.
> 
> It's better to put this content spec with the UAPI doc rather than in this
> kerner-internal function doc that userspace programmers won't know to
> look at.

Acked.

> 
>> + *
>> + * Returns:
>> + * Zero on success, negative errno on failure.
>> + */
>> +int drm_plane_create_solid_fill_property(struct drm_plane *plane)
>> +{
>> +	struct drm_property *prop;
>> +
>> +	prop = drm_property_create(plane->dev,
>> +			DRM_MODE_PROP_ATOMIC | DRM_MODE_PROP_BLOB,
>> +			"solid_fill", 0);
>> +	if (!prop)
>> +		return -ENOMEM;
>> +
>> +	drm_object_attach_property(&plane->base, prop, 0);
>> +	plane->solid_fill_property = prop;
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL(drm_plane_create_solid_fill_property);
>> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
>> index 88bdfec3bd88..0338a860b9c8 100644
>> --- a/include/drm/drm_blend.h
>> +++ b/include/drm/drm_blend.h
>> @@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>>   			      struct drm_atomic_state *state);
>>   int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>>   					 unsigned int supported_modes);
>> +int drm_plane_create_solid_fill_property(struct drm_plane *plane);
>>   #endif
>> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
>> index 51291983ea44..f6ab313cb83e 100644
>> --- a/include/drm/drm_plane.h
>> +++ b/include/drm/drm_plane.h
>> @@ -40,6 +40,25 @@ enum drm_scaling_filter {
>>   	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
>>   };
>>   
>> +/**
>> + * struct drm_solid_fill_info - User info for solid fill planes
>> + */
>> +struct drm_solid_fill_info {
>> +	__u8 version;
>> +	__u32 r, g, b;
>> +};
> 
> Shouldn't UAPI structs be in UAPI headers?

Acked, will move this to uapi/drm_mode.h

> 
> Shouldn't UAPI structs use explicit padding to not leave any gaps when
> it's unavoidable? And the kernel to check that the gaps are indeed
> zeroed?

I don't believe so... From my understanding, padding will be taken care 
of by the compiler by default. Looking at the drm_mode_modeinfo UAPI 
struct [1], it also doesn't seem to do explicit padding. And the 
corresponding set_property() code doesn't seem check the gaps either.

That being said, it's possible that I'm missing something here, so 
please let me know if that's the case.

[1] 
https://elixir.bootlin.com/linux/v6.5-rc1/source/include/uapi/drm/drm_mode.h#L242

> 
> It also needs more UAPI doc, like a link to the property doc that uses
> this and an explanation of what the values mean.

Acked.

Thanks,

Jessica Zhang

> 
> 
> Thanks,
> pq
> 
>> +
>> +/**
>> + * struct solid_fill_property - RGB values for solid fill plane
>> + *
>> + * Note: This is the V1 for this feature
>> + */
>> +struct drm_solid_fill {
>> +	uint32_t r;
>> +	uint32_t g;
>> +	uint32_t b;
>> +};
>> +
>>   /**
>>    * struct drm_plane_state - mutable plane state
>>    *
>> @@ -116,6 +135,23 @@ struct drm_plane_state {
>>   	/** @src_h: height of visible portion of plane (in 16.16) */
>>   	uint32_t src_h, src_w;
>>   
>> +	/**
>> +	 * @solid_fill_blob:
>> +	 *
>> +	 * Blob containing relevant information for a solid fill plane
>> +	 * including pixel format and data. See
>> +	 * drm_plane_create_solid_fill_property() for more details.
>> +	 */
>> +	struct drm_property_blob *solid_fill_blob;
>> +
>> +	/**
>> +	 * @solid_fill:
>> +	 *
>> +	 * Pixel data for solid fill planes. See
>> +	 * drm_plane_create_solid_fill_property() for more details.
>> +	 */
>> +	struct drm_solid_fill solid_fill;
>> +
>>   	/**
>>   	 * @alpha:
>>   	 * Opacity of the plane with 0 as completely transparent and 0xffff as
>> @@ -699,6 +735,13 @@ struct drm_plane {
>>   	 */
>>   	struct drm_plane_state *state;
>>   
>> +	/*
>> +	 * @solid_fill_property:
>> +	 * Optional solid_fill property for this plane. See
>> +	 * drm_plane_create_solid_fill_property().
>> +	 */
>> +	struct drm_property *solid_fill_property;
>> +
>>   	/**
>>   	 * @alpha_property:
>>   	 * Optional alpha property for this plane. See
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Freedreno] [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
  2023-07-10 23:12       ` Jessica Zhang
@ 2023-07-11  7:42         ` Pekka Paalanen
  -1 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-07-11  7:42 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, Maarten Lankhorst, quic_abhinavk,
	Maxime Ripard, linux-kernel, Rob Clark, laurent.pinchart,
	Daniel Vetter, Dmitry Baryshkov, contact, Marijn Suijten,
	wayland-devel, David Airlie, ville.syrjala

[-- Attachment #1: Type: text/plain, Size: 6475 bytes --]

On Mon, 10 Jul 2023 16:12:06 -0700
Jessica Zhang <quic_jesszhan@quicinc.com> wrote:

> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
> > On Thu, 29 Jun 2023 17:25:00 -0700
> > Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> >   
> >> Document and add support for solid_fill property to drm_plane. In
> >> addition, add support for setting and getting the values for solid_fill.
> >>
> >> To enable solid fill planes, userspace must assign a property blob to
> >> the "solid_fill" plane property containing the following information:
> >>
> >> struct drm_solid_fill_info {
> >> 	u8 version;
> >> 	u32 r, g, b;
> >> };
> >>
> >> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>  
> > 
> > Hi Jessica,
> > 
> > I've left some general UAPI related comments here.
> >   
> >> ---
> >>   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
> >>   drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
> >>   drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
> >>   include/drm/drm_blend.h                   |  1 +
> >>   include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
> >>   5 files changed, 141 insertions(+)

...

> >> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> >> index 88bdfec3bd88..0338a860b9c8 100644
> >> --- a/include/drm/drm_blend.h
> >> +++ b/include/drm/drm_blend.h
> >> @@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
> >>   			      struct drm_atomic_state *state);
> >>   int drm_plane_create_blend_mode_property(struct drm_plane *plane,
> >>   					 unsigned int supported_modes);
> >> +int drm_plane_create_solid_fill_property(struct drm_plane *plane);
> >>   #endif
> >> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> >> index 51291983ea44..f6ab313cb83e 100644
> >> --- a/include/drm/drm_plane.h
> >> +++ b/include/drm/drm_plane.h
> >> @@ -40,6 +40,25 @@ enum drm_scaling_filter {
> >>   	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
> >>   };
> >>   
> >> +/**
> >> + * struct drm_solid_fill_info - User info for solid fill planes
> >> + */
> >> +struct drm_solid_fill_info {
> >> +	__u8 version;
> >> +	__u32 r, g, b;
> >> +};  
> > 
> > Shouldn't UAPI structs be in UAPI headers?  
> 
> Acked, will move this to uapi/drm_mode.h
> 
> > 
> > Shouldn't UAPI structs use explicit padding to not leave any gaps when
> > it's unavoidable? And the kernel to check that the gaps are indeed
> > zeroed?  
> 
> I don't believe so... From my understanding, padding will be taken care 
> of by the compiler by default. Looking at the drm_mode_modeinfo UAPI 
> struct [1], it also doesn't seem to do explicit padding. And the 
> corresponding set_property() code doesn't seem check the gaps either.
> 
> That being said, it's possible that I'm missing something here, so 
> please let me know if that's the case.
> 
> [1] 
> https://elixir.bootlin.com/linux/v6.5-rc1/source/include/uapi/drm/drm_mode.h#L242

I suspect that drm_mode_modeinfo predates the lessons learnt about
"botching up ioctls" by many years:
https://www.kernel.org/doc/Documentation/ioctl/botching-up-ioctls.rst

drm_mode_modeinfo goes all the way back to

commit f453ba0460742ad027ae0c4c7d61e62817b3e7ef
Date:   Fri Nov 7 14:05:41 2008 -0800

    DRM: add mode setting support

and

commit e0c8463a8b00b467611607df0ff369d062528875
Date:   Fri Dec 19 14:50:50 2008 +1000

    drm: sanitise drm modesetting API + remove unused hotplug

and it got the proper types later in

commit 1d7f83d5ad6c30b385ba549c1c3a287cc872b7ae
Date:   Thu Feb 26 00:51:42 2009 +0100

    make drm headers use strict integer types


My personal feeling is that if you cannot avoid padding in a struct,
convert it into explicit fields anyway and require them to be zero.
That way if you ever need to extend or modify the struct, you already
have an "unused" field that old userspace guarantees to be zero, so you
can re-purpose it when it's not zero.

A struct for blob contents is maybe needing slightly less forward
planning than ioctl struct, because KMS properties are cheap compared
to ioctl numbers, I believe.

Maybe eliminating compiler induced padding in structs is not strictly
necessary, but it seems like a good idea to me, because compilers are
allowed to leave the padding bits undefined. If a struct was filled in
by the kernel and delivered to userspace, undefined padding could even
be a security leak, theoretically.

Anyway, don't take my word for it. Maybe kernel devs have a different
style.


Thanks,
pq

> > 
> > It also needs more UAPI doc, like a link to the property doc that uses
> > this and an explanation of what the values mean.  
> 
> Acked.
> 
> Thanks,
> 
> Jessica Zhang
> 
> > 
> > 
> > Thanks,
> > pq
> >   
> >> +
> >> +/**
> >> + * struct solid_fill_property - RGB values for solid fill plane
> >> + *
> >> + * Note: This is the V1 for this feature
> >> + */
> >> +struct drm_solid_fill {
> >> +	uint32_t r;
> >> +	uint32_t g;
> >> +	uint32_t b;
> >> +};
> >> +
> >>   /**
> >>    * struct drm_plane_state - mutable plane state
> >>    *
> >> @@ -116,6 +135,23 @@ struct drm_plane_state {
> >>   	/** @src_h: height of visible portion of plane (in 16.16) */
> >>   	uint32_t src_h, src_w;
> >>   
> >> +	/**
> >> +	 * @solid_fill_blob:
> >> +	 *
> >> +	 * Blob containing relevant information for a solid fill plane
> >> +	 * including pixel format and data. See
> >> +	 * drm_plane_create_solid_fill_property() for more details.
> >> +	 */
> >> +	struct drm_property_blob *solid_fill_blob;
> >> +
> >> +	/**
> >> +	 * @solid_fill:
> >> +	 *
> >> +	 * Pixel data for solid fill planes. See
> >> +	 * drm_plane_create_solid_fill_property() for more details.
> >> +	 */
> >> +	struct drm_solid_fill solid_fill;
> >> +
> >>   	/**
> >>   	 * @alpha:
> >>   	 * Opacity of the plane with 0 as completely transparent and 0xffff as
> >> @@ -699,6 +735,13 @@ struct drm_plane {
> >>   	 */
> >>   	struct drm_plane_state *state;
> >>   
> >> +	/*
> >> +	 * @solid_fill_property:
> >> +	 * Optional solid_fill property for this plane. See
> >> +	 * drm_plane_create_solid_fill_property().
> >> +	 */
> >> +	struct drm_property *solid_fill_property;
> >> +
> >>   	/**
> >>   	 * @alpha_property:
> >>   	 * Optional alpha property for this plane. See
> >>  
> >   


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Freedreno] [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
@ 2023-07-11  7:42         ` Pekka Paalanen
  0 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-07-11  7:42 UTC (permalink / raw)
  To: Jessica Zhang
  Cc: freedreno, sebastian.wick, linux-arm-msm, quic_abhinavk,
	dri-devel, linux-kernel, Maxime Ripard, Thomas Zimmermann,
	Dmitry Baryshkov, Marijn Suijten, wayland-devel, Sean Paul,
	laurent.pinchart

[-- Attachment #1: Type: text/plain, Size: 6475 bytes --]

On Mon, 10 Jul 2023 16:12:06 -0700
Jessica Zhang <quic_jesszhan@quicinc.com> wrote:

> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
> > On Thu, 29 Jun 2023 17:25:00 -0700
> > Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> >   
> >> Document and add support for solid_fill property to drm_plane. In
> >> addition, add support for setting and getting the values for solid_fill.
> >>
> >> To enable solid fill planes, userspace must assign a property blob to
> >> the "solid_fill" plane property containing the following information:
> >>
> >> struct drm_solid_fill_info {
> >> 	u8 version;
> >> 	u32 r, g, b;
> >> };
> >>
> >> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>  
> > 
> > Hi Jessica,
> > 
> > I've left some general UAPI related comments here.
> >   
> >> ---
> >>   drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
> >>   drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
> >>   drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
> >>   include/drm/drm_blend.h                   |  1 +
> >>   include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
> >>   5 files changed, 141 insertions(+)

...

> >> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> >> index 88bdfec3bd88..0338a860b9c8 100644
> >> --- a/include/drm/drm_blend.h
> >> +++ b/include/drm/drm_blend.h
> >> @@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
> >>   			      struct drm_atomic_state *state);
> >>   int drm_plane_create_blend_mode_property(struct drm_plane *plane,
> >>   					 unsigned int supported_modes);
> >> +int drm_plane_create_solid_fill_property(struct drm_plane *plane);
> >>   #endif
> >> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> >> index 51291983ea44..f6ab313cb83e 100644
> >> --- a/include/drm/drm_plane.h
> >> +++ b/include/drm/drm_plane.h
> >> @@ -40,6 +40,25 @@ enum drm_scaling_filter {
> >>   	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
> >>   };
> >>   
> >> +/**
> >> + * struct drm_solid_fill_info - User info for solid fill planes
> >> + */
> >> +struct drm_solid_fill_info {
> >> +	__u8 version;
> >> +	__u32 r, g, b;
> >> +};  
> > 
> > Shouldn't UAPI structs be in UAPI headers?  
> 
> Acked, will move this to uapi/drm_mode.h
> 
> > 
> > Shouldn't UAPI structs use explicit padding to not leave any gaps when
> > it's unavoidable? And the kernel to check that the gaps are indeed
> > zeroed?  
> 
> I don't believe so... From my understanding, padding will be taken care 
> of by the compiler by default. Looking at the drm_mode_modeinfo UAPI 
> struct [1], it also doesn't seem to do explicit padding. And the 
> corresponding set_property() code doesn't seem check the gaps either.
> 
> That being said, it's possible that I'm missing something here, so 
> please let me know if that's the case.
> 
> [1] 
> https://elixir.bootlin.com/linux/v6.5-rc1/source/include/uapi/drm/drm_mode.h#L242

I suspect that drm_mode_modeinfo predates the lessons learnt about
"botching up ioctls" by many years:
https://www.kernel.org/doc/Documentation/ioctl/botching-up-ioctls.rst

drm_mode_modeinfo goes all the way back to

commit f453ba0460742ad027ae0c4c7d61e62817b3e7ef
Date:   Fri Nov 7 14:05:41 2008 -0800

    DRM: add mode setting support

and

commit e0c8463a8b00b467611607df0ff369d062528875
Date:   Fri Dec 19 14:50:50 2008 +1000

    drm: sanitise drm modesetting API + remove unused hotplug

and it got the proper types later in

commit 1d7f83d5ad6c30b385ba549c1c3a287cc872b7ae
Date:   Thu Feb 26 00:51:42 2009 +0100

    make drm headers use strict integer types


My personal feeling is that if you cannot avoid padding in a struct,
convert it into explicit fields anyway and require them to be zero.
That way if you ever need to extend or modify the struct, you already
have an "unused" field that old userspace guarantees to be zero, so you
can re-purpose it when it's not zero.

A struct for blob contents is maybe needing slightly less forward
planning than ioctl struct, because KMS properties are cheap compared
to ioctl numbers, I believe.

Maybe eliminating compiler induced padding in structs is not strictly
necessary, but it seems like a good idea to me, because compilers are
allowed to leave the padding bits undefined. If a struct was filled in
by the kernel and delivered to userspace, undefined padding could even
be a security leak, theoretically.

Anyway, don't take my word for it. Maybe kernel devs have a different
style.


Thanks,
pq

> > 
> > It also needs more UAPI doc, like a link to the property doc that uses
> > this and an explanation of what the values mean.  
> 
> Acked.
> 
> Thanks,
> 
> Jessica Zhang
> 
> > 
> > 
> > Thanks,
> > pq
> >   
> >> +
> >> +/**
> >> + * struct solid_fill_property - RGB values for solid fill plane
> >> + *
> >> + * Note: This is the V1 for this feature
> >> + */
> >> +struct drm_solid_fill {
> >> +	uint32_t r;
> >> +	uint32_t g;
> >> +	uint32_t b;
> >> +};
> >> +
> >>   /**
> >>    * struct drm_plane_state - mutable plane state
> >>    *
> >> @@ -116,6 +135,23 @@ struct drm_plane_state {
> >>   	/** @src_h: height of visible portion of plane (in 16.16) */
> >>   	uint32_t src_h, src_w;
> >>   
> >> +	/**
> >> +	 * @solid_fill_blob:
> >> +	 *
> >> +	 * Blob containing relevant information for a solid fill plane
> >> +	 * including pixel format and data. See
> >> +	 * drm_plane_create_solid_fill_property() for more details.
> >> +	 */
> >> +	struct drm_property_blob *solid_fill_blob;
> >> +
> >> +	/**
> >> +	 * @solid_fill:
> >> +	 *
> >> +	 * Pixel data for solid fill planes. See
> >> +	 * drm_plane_create_solid_fill_property() for more details.
> >> +	 */
> >> +	struct drm_solid_fill solid_fill;
> >> +
> >>   	/**
> >>   	 * @alpha:
> >>   	 * Opacity of the plane with 0 as completely transparent and 0xffff as
> >> @@ -699,6 +735,13 @@ struct drm_plane {
> >>   	 */
> >>   	struct drm_plane_state *state;
> >>   
> >> +	/*
> >> +	 * @solid_fill_property:
> >> +	 * Optional solid_fill property for this plane. See
> >> +	 * drm_plane_create_solid_fill_property().
> >> +	 */
> >> +	struct drm_property *solid_fill_property;
> >> +
> >>   	/**
> >>   	 * @alpha_property:
> >>   	 * Optional alpha property for this plane. See
> >>  
> >   


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Freedreno] [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
  2023-07-11  7:42         ` Pekka Paalanen
@ 2023-07-11 21:47           ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-11 21:47 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, Maarten Lankhorst, quic_abhinavk,
	Maxime Ripard, linux-kernel, Rob Clark, laurent.pinchart,
	Daniel Vetter, Dmitry Baryshkov, contact, Marijn Suijten,
	wayland-devel, David Airlie, ville.syrjala



On 7/11/2023 12:42 AM, Pekka Paalanen wrote:
> On Mon, 10 Jul 2023 16:12:06 -0700
> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> 
>> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
>>> On Thu, 29 Jun 2023 17:25:00 -0700
>>> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>>>    
>>>> Document and add support for solid_fill property to drm_plane. In
>>>> addition, add support for setting and getting the values for solid_fill.
>>>>
>>>> To enable solid fill planes, userspace must assign a property blob to
>>>> the "solid_fill" plane property containing the following information:
>>>>
>>>> struct drm_solid_fill_info {
>>>> 	u8 version;
>>>> 	u32 r, g, b;
>>>> };
>>>>
>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>
>>> Hi Jessica,
>>>
>>> I've left some general UAPI related comments here.
>>>    
>>>> ---
>>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>>>>    drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
>>>>    drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>>>>    include/drm/drm_blend.h                   |  1 +
>>>>    include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>>>>    5 files changed, 141 insertions(+)
> 
> ...
> 
>>>> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
>>>> index 88bdfec3bd88..0338a860b9c8 100644
>>>> --- a/include/drm/drm_blend.h
>>>> +++ b/include/drm/drm_blend.h
>>>> @@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>>>>    			      struct drm_atomic_state *state);
>>>>    int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>>>>    					 unsigned int supported_modes);
>>>> +int drm_plane_create_solid_fill_property(struct drm_plane *plane);
>>>>    #endif
>>>> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
>>>> index 51291983ea44..f6ab313cb83e 100644
>>>> --- a/include/drm/drm_plane.h
>>>> +++ b/include/drm/drm_plane.h
>>>> @@ -40,6 +40,25 @@ enum drm_scaling_filter {
>>>>    	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
>>>>    };
>>>>    
>>>> +/**
>>>> + * struct drm_solid_fill_info - User info for solid fill planes
>>>> + */
>>>> +struct drm_solid_fill_info {
>>>> +	__u8 version;
>>>> +	__u32 r, g, b;
>>>> +};
>>>
>>> Shouldn't UAPI structs be in UAPI headers?
>>
>> Acked, will move this to uapi/drm_mode.h
>>
>>>
>>> Shouldn't UAPI structs use explicit padding to not leave any gaps when
>>> it's unavoidable? And the kernel to check that the gaps are indeed
>>> zeroed?
>>
>> I don't believe so... From my understanding, padding will be taken care
>> of by the compiler by default. Looking at the drm_mode_modeinfo UAPI
>> struct [1], it also doesn't seem to do explicit padding. And the
>> corresponding set_property() code doesn't seem check the gaps either.
>>
>> That being said, it's possible that I'm missing something here, so
>> please let me know if that's the case.
>>
>> [1]
>> https://elixir.bootlin.com/linux/v6.5-rc1/source/include/uapi/drm/drm_mode.h#L242
> 
> I suspect that drm_mode_modeinfo predates the lessons learnt about
> "botching up ioctls" by many years:
> https://www.kernel.org/doc/Documentation/ioctl/botching-up-ioctls.rst
> 
> drm_mode_modeinfo goes all the way back to
> 
> commit f453ba0460742ad027ae0c4c7d61e62817b3e7ef
> Date:   Fri Nov 7 14:05:41 2008 -0800
> 
>      DRM: add mode setting support
> 
> and
> 
> commit e0c8463a8b00b467611607df0ff369d062528875
> Date:   Fri Dec 19 14:50:50 2008 +1000
> 
>      drm: sanitise drm modesetting API + remove unused hotplug
> 
> and it got the proper types later in
> 
> commit 1d7f83d5ad6c30b385ba549c1c3a287cc872b7ae
> Date:   Thu Feb 26 00:51:42 2009 +0100
> 
>      make drm headers use strict integer types
> 
> 
> My personal feeling is that if you cannot avoid padding in a struct,
> convert it into explicit fields anyway and require them to be zero.
> That way if you ever need to extend or modify the struct, you already
> have an "unused" field that old userspace guarantees to be zero, so you
> can re-purpose it when it's not zero.
> 
> A struct for blob contents is maybe needing slightly less forward
> planning than ioctl struct, because KMS properties are cheap compared
> to ioctl numbers, I believe.
> 
> Maybe eliminating compiler induced padding in structs is not strictly
> necessary, but it seems like a good idea to me, because compilers are
> allowed to leave the padding bits undefined. If a struct was filled in
> by the kernel and delivered to userspace, undefined padding could even
> be a security leak, theoretically.
> 
> Anyway, don't take my word for it. Maybe kernel devs have a different
> style.

Ah, got it. Thanks for the info! Looking over more recent 
implementations of blob properties, I do see that there's a precedent 
for explicit padding [1].

I think I could also just make `version` a __u32 instead. Either way, 
that seems to be how other structs declare `version`.

Thanks,

Jessica Zhang

[1] 
https://elixir.bootlin.com/linux/latest/source/include/uapi/drm/virtgpu_drm.h#L178

> 
> 
> Thanks,
> pq
> 
>>>
>>> It also needs more UAPI doc, like a link to the property doc that uses
>>> this and an explanation of what the values mean.
>>
>> Acked.
>>
>> Thanks,
>>
>> Jessica Zhang
>>
>>>
>>>
>>> Thanks,
>>> pq
>>>    
>>>> +
>>>> +/**
>>>> + * struct solid_fill_property - RGB values for solid fill plane
>>>> + *
>>>> + * Note: This is the V1 for this feature
>>>> + */
>>>> +struct drm_solid_fill {
>>>> +	uint32_t r;
>>>> +	uint32_t g;
>>>> +	uint32_t b;
>>>> +};
>>>> +
>>>>    /**
>>>>     * struct drm_plane_state - mutable plane state
>>>>     *
>>>> @@ -116,6 +135,23 @@ struct drm_plane_state {
>>>>    	/** @src_h: height of visible portion of plane (in 16.16) */
>>>>    	uint32_t src_h, src_w;
>>>>    
>>>> +	/**
>>>> +	 * @solid_fill_blob:
>>>> +	 *
>>>> +	 * Blob containing relevant information for a solid fill plane
>>>> +	 * including pixel format and data. See
>>>> +	 * drm_plane_create_solid_fill_property() for more details.
>>>> +	 */
>>>> +	struct drm_property_blob *solid_fill_blob;
>>>> +
>>>> +	/**
>>>> +	 * @solid_fill:
>>>> +	 *
>>>> +	 * Pixel data for solid fill planes. See
>>>> +	 * drm_plane_create_solid_fill_property() for more details.
>>>> +	 */
>>>> +	struct drm_solid_fill solid_fill;
>>>> +
>>>>    	/**
>>>>    	 * @alpha:
>>>>    	 * Opacity of the plane with 0 as completely transparent and 0xffff as
>>>> @@ -699,6 +735,13 @@ struct drm_plane {
>>>>    	 */
>>>>    	struct drm_plane_state *state;
>>>>    
>>>> +	/*
>>>> +	 * @solid_fill_property:
>>>> +	 * Optional solid_fill property for this plane. See
>>>> +	 * drm_plane_create_solid_fill_property().
>>>> +	 */
>>>> +	struct drm_property *solid_fill_property;
>>>> +
>>>>    	/**
>>>>    	 * @alpha_property:
>>>>    	 * Optional alpha property for this plane. See
>>>>   
>>>    
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Freedreno] [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property
@ 2023-07-11 21:47           ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-11 21:47 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: freedreno, sebastian.wick, linux-arm-msm, quic_abhinavk,
	dri-devel, linux-kernel, Maxime Ripard, Thomas Zimmermann,
	Dmitry Baryshkov, Marijn Suijten, wayland-devel, Sean Paul,
	laurent.pinchart



On 7/11/2023 12:42 AM, Pekka Paalanen wrote:
> On Mon, 10 Jul 2023 16:12:06 -0700
> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
> 
>> On 6/30/2023 1:27 AM, Pekka Paalanen wrote:
>>> On Thu, 29 Jun 2023 17:25:00 -0700
>>> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>>>    
>>>> Document and add support for solid_fill property to drm_plane. In
>>>> addition, add support for setting and getting the values for solid_fill.
>>>>
>>>> To enable solid fill planes, userspace must assign a property blob to
>>>> the "solid_fill" plane property containing the following information:
>>>>
>>>> struct drm_solid_fill_info {
>>>> 	u8 version;
>>>> 	u32 r, g, b;
>>>> };
>>>>
>>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>>
>>> Hi Jessica,
>>>
>>> I've left some general UAPI related comments here.
>>>    
>>>> ---
>>>>    drivers/gpu/drm/drm_atomic_state_helper.c |  9 +++++
>>>>    drivers/gpu/drm/drm_atomic_uapi.c         | 55 +++++++++++++++++++++++++++++++
>>>>    drivers/gpu/drm/drm_blend.c               | 33 +++++++++++++++++++
>>>>    include/drm/drm_blend.h                   |  1 +
>>>>    include/drm/drm_plane.h                   | 43 ++++++++++++++++++++++++
>>>>    5 files changed, 141 insertions(+)
> 
> ...
> 
>>>> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
>>>> index 88bdfec3bd88..0338a860b9c8 100644
>>>> --- a/include/drm/drm_blend.h
>>>> +++ b/include/drm/drm_blend.h
>>>> @@ -58,4 +58,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
>>>>    			      struct drm_atomic_state *state);
>>>>    int drm_plane_create_blend_mode_property(struct drm_plane *plane,
>>>>    					 unsigned int supported_modes);
>>>> +int drm_plane_create_solid_fill_property(struct drm_plane *plane);
>>>>    #endif
>>>> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
>>>> index 51291983ea44..f6ab313cb83e 100644
>>>> --- a/include/drm/drm_plane.h
>>>> +++ b/include/drm/drm_plane.h
>>>> @@ -40,6 +40,25 @@ enum drm_scaling_filter {
>>>>    	DRM_SCALING_FILTER_NEAREST_NEIGHBOR,
>>>>    };
>>>>    
>>>> +/**
>>>> + * struct drm_solid_fill_info - User info for solid fill planes
>>>> + */
>>>> +struct drm_solid_fill_info {
>>>> +	__u8 version;
>>>> +	__u32 r, g, b;
>>>> +};
>>>
>>> Shouldn't UAPI structs be in UAPI headers?
>>
>> Acked, will move this to uapi/drm_mode.h
>>
>>>
>>> Shouldn't UAPI structs use explicit padding to not leave any gaps when
>>> it's unavoidable? And the kernel to check that the gaps are indeed
>>> zeroed?
>>
>> I don't believe so... From my understanding, padding will be taken care
>> of by the compiler by default. Looking at the drm_mode_modeinfo UAPI
>> struct [1], it also doesn't seem to do explicit padding. And the
>> corresponding set_property() code doesn't seem check the gaps either.
>>
>> That being said, it's possible that I'm missing something here, so
>> please let me know if that's the case.
>>
>> [1]
>> https://elixir.bootlin.com/linux/v6.5-rc1/source/include/uapi/drm/drm_mode.h#L242
> 
> I suspect that drm_mode_modeinfo predates the lessons learnt about
> "botching up ioctls" by many years:
> https://www.kernel.org/doc/Documentation/ioctl/botching-up-ioctls.rst
> 
> drm_mode_modeinfo goes all the way back to
> 
> commit f453ba0460742ad027ae0c4c7d61e62817b3e7ef
> Date:   Fri Nov 7 14:05:41 2008 -0800
> 
>      DRM: add mode setting support
> 
> and
> 
> commit e0c8463a8b00b467611607df0ff369d062528875
> Date:   Fri Dec 19 14:50:50 2008 +1000
> 
>      drm: sanitise drm modesetting API + remove unused hotplug
> 
> and it got the proper types later in
> 
> commit 1d7f83d5ad6c30b385ba549c1c3a287cc872b7ae
> Date:   Thu Feb 26 00:51:42 2009 +0100
> 
>      make drm headers use strict integer types
> 
> 
> My personal feeling is that if you cannot avoid padding in a struct,
> convert it into explicit fields anyway and require them to be zero.
> That way if you ever need to extend or modify the struct, you already
> have an "unused" field that old userspace guarantees to be zero, so you
> can re-purpose it when it's not zero.
> 
> A struct for blob contents is maybe needing slightly less forward
> planning than ioctl struct, because KMS properties are cheap compared
> to ioctl numbers, I believe.
> 
> Maybe eliminating compiler induced padding in structs is not strictly
> necessary, but it seems like a good idea to me, because compilers are
> allowed to leave the padding bits undefined. If a struct was filled in
> by the kernel and delivered to userspace, undefined padding could even
> be a security leak, theoretically.
> 
> Anyway, don't take my word for it. Maybe kernel devs have a different
> style.

Ah, got it. Thanks for the info! Looking over more recent 
implementations of blob properties, I do see that there's a precedent 
for explicit padding [1].

I think I could also just make `version` a __u32 instead. Either way, 
that seems to be how other structs declare `version`.

Thanks,

Jessica Zhang

[1] 
https://elixir.bootlin.com/linux/latest/source/include/uapi/drm/virtgpu_drm.h#L178

> 
> 
> Thanks,
> pq
> 
>>>
>>> It also needs more UAPI doc, like a link to the property doc that uses
>>> this and an explanation of what the values mean.
>>
>> Acked.
>>
>> Thanks,
>>
>> Jessica Zhang
>>
>>>
>>>
>>> Thanks,
>>> pq
>>>    
>>>> +
>>>> +/**
>>>> + * struct solid_fill_property - RGB values for solid fill plane
>>>> + *
>>>> + * Note: This is the V1 for this feature
>>>> + */
>>>> +struct drm_solid_fill {
>>>> +	uint32_t r;
>>>> +	uint32_t g;
>>>> +	uint32_t b;
>>>> +};
>>>> +
>>>>    /**
>>>>     * struct drm_plane_state - mutable plane state
>>>>     *
>>>> @@ -116,6 +135,23 @@ struct drm_plane_state {
>>>>    	/** @src_h: height of visible portion of plane (in 16.16) */
>>>>    	uint32_t src_h, src_w;
>>>>    
>>>> +	/**
>>>> +	 * @solid_fill_blob:
>>>> +	 *
>>>> +	 * Blob containing relevant information for a solid fill plane
>>>> +	 * including pixel format and data. See
>>>> +	 * drm_plane_create_solid_fill_property() for more details.
>>>> +	 */
>>>> +	struct drm_property_blob *solid_fill_blob;
>>>> +
>>>> +	/**
>>>> +	 * @solid_fill:
>>>> +	 *
>>>> +	 * Pixel data for solid fill planes. See
>>>> +	 * drm_plane_create_solid_fill_property() for more details.
>>>> +	 */
>>>> +	struct drm_solid_fill solid_fill;
>>>> +
>>>>    	/**
>>>>    	 * @alpha:
>>>>    	 * Opacity of the plane with 0 as completely transparent and 0xffff as
>>>> @@ -699,6 +735,13 @@ struct drm_plane {
>>>>    	 */
>>>>    	struct drm_plane_state *state;
>>>>    
>>>> +	/*
>>>> +	 * @solid_fill_property:
>>>> +	 * Optional solid_fill property for this plane. See
>>>> +	 * drm_plane_create_solid_fill_property().
>>>> +	 */
>>>> +	struct drm_property *solid_fill_property;
>>>> +
>>>>    	/**
>>>>    	 * @alpha_property:
>>>>    	 * Optional alpha property for this plane. See
>>>>   
>>>    
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-07-10 20:11           ` Dmitry Baryshkov
@ 2023-07-11 22:07             ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-11 22:07 UTC (permalink / raw)
  To: Dmitry Baryshkov, Pekka Paalanen
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Sean Paul,
	Marijn Suijten, quic_abhinavk, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel



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
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-07-11 22:07             ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-11 22:07 UTC (permalink / raw)
  To: Dmitry Baryshkov, Pekka Paalanen
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Marijn Suijten, wayland-devel



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
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-07-11 22:07             ` Jessica Zhang
@ 2023-07-11 22:19               ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-07-11 22:19 UTC (permalink / raw)
  To: Jessica Zhang, Pekka Paalanen
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Sean Paul,
	Marijn Suijten, quic_abhinavk, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

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
>>

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-07-11 22:19               ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-07-11 22:19 UTC (permalink / raw)
  To: Jessica Zhang, Pekka Paalanen
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Marijn Suijten, wayland-devel

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
>>

-- 
With best wishes
Dmitry


^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-07-11 22:19               ` Dmitry Baryshkov
@ 2023-07-11 22:42                 ` Abhinav Kumar
  -1 siblings, 0 replies; 80+ messages in thread
From: Abhinav Kumar @ 2023-07-11 22:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Jessica Zhang, Pekka Paalanen
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Sean Paul,
	Marijn Suijten, contact, laurent.pinchart, sebastian.wick,
	ville.syrjala, dri-devel, linux-kernel, linux-arm-msm, freedreno,
	wayland-devel



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
>>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-07-11 22:42                 ` Abhinav Kumar
  0 siblings, 0 replies; 80+ messages in thread
From: Abhinav Kumar @ 2023-07-11 22:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Jessica Zhang, Pekka Paalanen
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, linux-kernel, Maxime Ripard, wayland-devel,
	laurent.pinchart, Marijn Suijten



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
>>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-07-11 22:42                 ` Abhinav Kumar
@ 2023-07-11 23:00                   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-07-11 23:00 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Jessica Zhang, Pekka Paalanen, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Rob Clark,
	Sean Paul, Marijn Suijten, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

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
> >>>
> >



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-07-11 23:00                   ` Dmitry Baryshkov
  0 siblings, 0 replies; 80+ messages in thread
From: Dmitry Baryshkov @ 2023-07-11 23:00 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: linux-arm-msm, freedreno, sebastian.wick, Sean Paul, dri-devel,
	Maxime Ripard, linux-kernel, wayland-devel, Pekka Paalanen,
	laurent.pinchart, Thomas Zimmermann, Marijn Suijten,
	Jessica Zhang

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
> >>>
> >



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
  2023-07-03  7:42       ` Pekka Paalanen
@ 2023-07-12  0:01         ` Jessica Zhang
  -1 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-12  0:01 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Daniel Vetter, Rob Clark, Dmitry Baryshkov,
	Sean Paul, Marijn Suijten, quic_abhinavk, contact,
	laurent.pinchart, sebastian.wick, ville.syrjala, dri-devel,
	linux-kernel, linux-arm-msm, freedreno, wayland-devel



On 7/3/2023 12:42 AM, Pekka Paalanen wrote:
> On Fri, 30 Jun 2023 11:26:49 +0300
> Pekka Paalanen <ppaalanen@gmail.com> wrote:
> 
>> On Thu, 29 Jun 2023 17:25:06 -0700
>> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>>
>>> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
>>> determine if the plane is solid fill. In addition drop the DPU plane
>>> color_fill field as we can now use drm_plane_state.solid_fill instead,
>>> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
>>> allow userspace to configure the alpha value for the solid fill color.
>>>
>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
>>>   1 file changed, 15 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index 4476722f03bb..11d4fb771a1f 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -42,7 +42,6 @@
>>>   #define SHARP_SMOOTH_THR_DEFAULT	8
>>>   #define SHARP_NOISE_THR_DEFAULT	2
>>>   
>>> -#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
>>>   #define DPU_ZPOS_MAX 255
>>>   
>>>   /*
>>> @@ -82,7 +81,6 @@ struct dpu_plane {
>>>   
>>>   	enum dpu_sspp pipe;
>>>   
>>> -	uint32_t color_fill;
>>>   	bool is_error;
>>>   	bool is_rt_pipe;
>>>   	const struct dpu_mdss_cfg *catalog;
>>> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>>>   	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
>>>   }
>>>   
>>> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
>>> +{
>>> +	uint32_t ret = 0;
>>> +
>>> +	ret |= ((uint8_t) solid_fill.b) << 16;
>>> +	ret |= ((uint8_t) solid_fill.g) << 8;
>>> +	ret |= ((uint8_t) solid_fill.r);
>>
>> solid_fill.r, g and b are uint32_t, yes?
>>
>> What's the value encoding in the UAPI? That doc was missing.

Hi Pekka,

The solid fill blob will accept an RGB323232 value -- will document this 
in the drm_solid_fill_info struct

>>
>> I wouldn't expect the UAPI to use 32-bit variables if it was
>> essentially 8-bit, so this conversion looks wrong.
>>
>> Nominal color value 1.0 in u8 is 0xff. The same in u32 is probably
>> 0xffffffff? So a simple cast to u8 won't work. You'd want to take the
>> upper 8 bits instead.

Acked.

>>
>>
>> Thanks,
>> pq
>>
>>> +
>>> +	return ret;
> 
> Btw. if your driver format is ABGR, then this function leaves alpha as
> zero. That's confusing.
> 
> It would be nice to mention the exact pixel format in the function name
> so the consistency is easier to check in both here and in callers.

Acked.

Thanks,

Jessica Zhang

> 
> 
> Thanks,
> pq
> 
>>> +}
>>> +
>>>   /**
>>>    * _dpu_plane_color_fill - enables color fill on plane
>>>    * @pdpu:   Pointer to DPU plane object
>>> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>>>   	if (pdpu->is_error)
>>>   		/* force white frame with 100% alpha pipe output on error */
>>>   		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
>>> -	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>>> -		/* force 100% alpha */
>>> -		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>>> +	else if (drm_plane_solid_fill_enabled(plane->state))
>>> +		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
>>> +				plane->state->alpha);
>>>   	else {
>>>   		dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>>   		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
>>> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>>>   	}
>>>   
>>>   	/* override for color fill */
>>> -	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
>>> +	if (drm_plane_solid_fill_enabled(plane->state)) {
>>>   		_dpu_plane_set_qos_ctrl(plane, pipe, false);
>>>   
>>>   		/* skip remaining processing on color fill */
>>>    
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property
@ 2023-07-12  0:01         ` Jessica Zhang
  0 siblings, 0 replies; 80+ messages in thread
From: Jessica Zhang @ 2023-07-12  0:01 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: linux-arm-msm, freedreno, sebastian.wick, Thomas Zimmermann,
	Sean Paul, dri-devel, quic_abhinavk, Maxime Ripard, linux-kernel,
	laurent.pinchart, Dmitry Baryshkov, Marijn Suijten,
	wayland-devel



On 7/3/2023 12:42 AM, Pekka Paalanen wrote:
> On Fri, 30 Jun 2023 11:26:49 +0300
> Pekka Paalanen <ppaalanen@gmail.com> wrote:
> 
>> On Thu, 29 Jun 2023 17:25:06 -0700
>> Jessica Zhang <quic_jesszhan@quicinc.com> wrote:
>>
>>> Drop DPU_PLANE_COLOR_FILL_FLAG and check the DRM solid_fill property to
>>> determine if the plane is solid fill. In addition drop the DPU plane
>>> color_fill field as we can now use drm_plane_state.solid_fill instead,
>>> and pass in drm_plane_state.alpha to _dpu_plane_color_fill_pipe() to
>>> allow userspace to configure the alpha value for the solid fill color.
>>>
>>> Signed-off-by: Jessica Zhang <quic_jesszhan@quicinc.com>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 21 +++++++++++++++------
>>>   1 file changed, 15 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index 4476722f03bb..11d4fb771a1f 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -42,7 +42,6 @@
>>>   #define SHARP_SMOOTH_THR_DEFAULT	8
>>>   #define SHARP_NOISE_THR_DEFAULT	2
>>>   
>>> -#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
>>>   #define DPU_ZPOS_MAX 255
>>>   
>>>   /*
>>> @@ -82,7 +81,6 @@ struct dpu_plane {
>>>   
>>>   	enum dpu_sspp pipe;
>>>   
>>> -	uint32_t color_fill;
>>>   	bool is_error;
>>>   	bool is_rt_pipe;
>>>   	const struct dpu_mdss_cfg *catalog;
>>> @@ -606,6 +604,17 @@ static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>>>   	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
>>>   }
>>>   
>>> +static uint32_t _dpu_plane_get_fill_color(struct drm_solid_fill solid_fill)
>>> +{
>>> +	uint32_t ret = 0;
>>> +
>>> +	ret |= ((uint8_t) solid_fill.b) << 16;
>>> +	ret |= ((uint8_t) solid_fill.g) << 8;
>>> +	ret |= ((uint8_t) solid_fill.r);
>>
>> solid_fill.r, g and b are uint32_t, yes?
>>
>> What's the value encoding in the UAPI? That doc was missing.

Hi Pekka,

The solid fill blob will accept an RGB323232 value -- will document this 
in the drm_solid_fill_info struct

>>
>> I wouldn't expect the UAPI to use 32-bit variables if it was
>> essentially 8-bit, so this conversion looks wrong.
>>
>> Nominal color value 1.0 in u8 is 0xff. The same in u32 is probably
>> 0xffffffff? So a simple cast to u8 won't work. You'd want to take the
>> upper 8 bits instead.

Acked.

>>
>>
>> Thanks,
>> pq
>>
>>> +
>>> +	return ret;
> 
> Btw. if your driver format is ABGR, then this function leaves alpha as
> zero. That's confusing.
> 
> It would be nice to mention the exact pixel format in the function name
> so the consistency is easier to check in both here and in callers.

Acked.

Thanks,

Jessica Zhang

> 
> 
> Thanks,
> pq
> 
>>> +}
>>> +
>>>   /**
>>>    * _dpu_plane_color_fill - enables color fill on plane
>>>    * @pdpu:   Pointer to DPU plane object
>>> @@ -977,9 +986,9 @@ void dpu_plane_flush(struct drm_plane *plane)
>>>   	if (pdpu->is_error)
>>>   		/* force white frame with 100% alpha pipe output on error */
>>>   		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
>>> -	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>>> -		/* force 100% alpha */
>>> -		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>>> +	else if (drm_plane_solid_fill_enabled(plane->state))
>>> +		_dpu_plane_color_fill(pdpu, _dpu_plane_get_fill_color(plane->state->solid_fill),
>>> +				plane->state->alpha);
>>>   	else {
>>>   		dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>>   		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
>>> @@ -1024,7 +1033,7 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>>>   	}
>>>   
>>>   	/* override for color fill */
>>> -	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
>>> +	if (drm_plane_solid_fill_enabled(plane->state)) {
>>>   		_dpu_plane_set_qos_ctrl(plane, pipe, false);
>>>   
>>>   		/* skip remaining processing on color fill */
>>>    
>>
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
  2023-07-11 22:42                 ` Abhinav Kumar
@ 2023-07-12  7:35                   ` Pekka Paalanen
  -1 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-07-12  7:35 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Dmitry Baryshkov, Jessica Zhang, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Daniel Vetter,
	Rob Clark, Sean Paul, Marijn Suijten, contact, laurent.pinchart,
	sebastian.wick, ville.syrjala, dri-devel, linux-kernel,
	linux-arm-msm, freedreno, wayland-devel

[-- Attachment #1: Type: text/plain, Size: 8080 bytes --]

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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH RFC v4 2/7] drm: Introduce pixel_source DRM plane property
@ 2023-07-12  7:35                   ` Pekka Paalanen
  0 siblings, 0 replies; 80+ messages in thread
From: Pekka Paalanen @ 2023-07-12  7:35 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: linux-arm-msm, freedreno, sebastian.wick, Sean Paul, dri-devel,
	linux-kernel, Maxime Ripard, wayland-devel, laurent.pinchart,
	Thomas Zimmermann, Marijn Suijten, Dmitry Baryshkov,
	Jessica Zhang

[-- Attachment #1: Type: text/plain, Size: 8080 bytes --]

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

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 80+ messages in thread

end of thread, other threads:[~2023-07-12  7:35 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-30  0:24 [PATCH RFC v4 0/7] Support for Solid Fill Planes Jessica Zhang
2023-06-30  0:24 ` Jessica Zhang
2023-06-30  0:25 ` [PATCH RFC v4 1/7] drm: Introduce solid fill DRM plane property Jessica Zhang
2023-06-30  0:25   ` Jessica Zhang
2023-06-30  8:27   ` Pekka Paalanen
2023-06-30  8:27     ` Pekka Paalanen
2023-07-10 23:12     ` [Freedreno] " Jessica Zhang
2023-07-10 23:12       ` Jessica Zhang
2023-07-11  7:42       ` Pekka Paalanen
2023-07-11  7:42         ` Pekka Paalanen
2023-07-11 21:47         ` Jessica Zhang
2023-07-11 21:47           ` Jessica Zhang
2023-06-30 10:33   ` Dmitry Baryshkov
2023-06-30 10:33     ` Dmitry Baryshkov
2023-06-30 17:54     ` Jessica Zhang
2023-06-30 17:54       ` Jessica Zhang
2023-06-30  0:25 ` [PATCH RFC v4 2/7] drm: Introduce pixel_source " Jessica Zhang
2023-06-30  0:25   ` Jessica Zhang
2023-06-30  0:42   ` Dmitry Baryshkov
2023-06-30  0:42     ` Dmitry Baryshkov
2023-06-30  8:27     ` Pekka Paalanen
2023-06-30  8:27       ` Pekka Paalanen
2023-07-10 19:51       ` Jessica Zhang
2023-07-10 19:51         ` Jessica Zhang
2023-07-10 20:11         ` Dmitry Baryshkov
2023-07-10 20:11           ` Dmitry Baryshkov
2023-07-11 22:07           ` Jessica Zhang
2023-07-11 22:07             ` Jessica Zhang
2023-07-11 22:19             ` Dmitry Baryshkov
2023-07-11 22:19               ` Dmitry Baryshkov
2023-07-11 22:42               ` Abhinav Kumar
2023-07-11 22:42                 ` Abhinav Kumar
2023-07-11 23:00                 ` Dmitry Baryshkov
2023-07-11 23:00                   ` Dmitry Baryshkov
2023-07-12  7:35                 ` Pekka Paalanen
2023-07-12  7:35                   ` Pekka Paalanen
2023-06-30 14:43   ` Sebastian Wick
2023-06-30 14:43     ` Sebastian Wick
2023-06-30 21:27     ` Jessica Zhang
2023-06-30 21:27       ` Jessica Zhang
2023-07-03 11:49       ` Sebastian Wick
2023-07-03 11:49         ` Sebastian Wick
2023-06-30  0:25 ` [PATCH RFC v4 3/7] drm/atomic: Move framebuffer checks to helper Jessica Zhang
2023-06-30  0:25   ` Jessica Zhang
2023-06-30  0:43   ` Dmitry Baryshkov
2023-06-30  0:43     ` Dmitry Baryshkov
2023-06-30 17:59     ` Jessica Zhang
2023-06-30 17:59       ` Jessica Zhang
2023-06-30  0:25 ` [PATCH RFC v4 4/7] drm/atomic: Loosen FB atomic checks Jessica Zhang
2023-06-30  0:25   ` Jessica Zhang
2023-06-30  0:48   ` Dmitry Baryshkov
2023-06-30  0:48     ` Dmitry Baryshkov
2023-06-30 23:41     ` Jessica Zhang
2023-06-30 23:41       ` Jessica Zhang
2023-06-30  0:25 ` [PATCH RFC v4 5/7] drm/msm/dpu: Add solid fill and pixel source properties Jessica Zhang
2023-06-30  0:25   ` Jessica Zhang
2023-06-30  0:49   ` Dmitry Baryshkov
2023-06-30  0:49     ` Dmitry Baryshkov
2023-06-30 23:41     ` Jessica Zhang
2023-06-30 23:41       ` Jessica Zhang
2023-06-30  0:25 ` [PATCH RFC v4 6/7] drm/msm/dpu: Allow NULL FBs in atomic commit Jessica Zhang
2023-06-30  0:25   ` Jessica Zhang
2023-06-30  0:52   ` Dmitry Baryshkov
2023-06-30  0:52     ` Dmitry Baryshkov
2023-06-30  8:21     ` Pekka Paalanen
2023-06-30  8:21       ` Pekka Paalanen
2023-07-01  1:14       ` Jessica Zhang
2023-07-01  1:14         ` Jessica Zhang
2023-06-30  0:25 ` [PATCH RFC v4 7/7] drm/msm/dpu: Use DRM solid_fill property Jessica Zhang
2023-06-30  0:25   ` Jessica Zhang
2023-06-30  0:59   ` Dmitry Baryshkov
2023-06-30  0:59     ` Dmitry Baryshkov
2023-07-01  1:26     ` Jessica Zhang
2023-07-01  1:26       ` Jessica Zhang
2023-06-30  8:26   ` Pekka Paalanen
2023-06-30  8:26     ` Pekka Paalanen
2023-07-03  7:42     ` Pekka Paalanen
2023-07-03  7:42       ` Pekka Paalanen
2023-07-12  0:01       ` Jessica Zhang
2023-07-12  0:01         ` Jessica Zhang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.