The GEM shadow-plane helpers only expose reset functions
(drm_gem_reset_shadow_plane and __drm_gem_reset_shadow_plane) that
handle both the initial state allocation and the reset path. The new
atomic_create_state hook requires a function that only allocates and
initializes a pristine state without any side effect.

Create __drm_gem_shadow_plane_state_init() to initialize a
pre-allocated shadow plane state, and
drm_gem_create_shadow_plane_state() to allocate and initialize one
from scratch.

Signed-off-by: Maxime Ripard <[email protected]>
---
 drivers/gpu/drm/drm_gem_atomic_helper.c | 42 +++++++++++++++++++++++++++++++++
 include/drm/drm_gem_atomic_helper.h     |  3 +++
 2 files changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c 
b/drivers/gpu/drm/drm_gem_atomic_helper.c
index abef865c5f2c..7ef67c2d77ce 100644
--- a/drivers/gpu/drm/drm_gem_atomic_helper.c
+++ b/drivers/gpu/drm/drm_gem_atomic_helper.c
@@ -178,10 +178,52 @@ EXPORT_SYMBOL_GPL(drm_gem_plane_helper_prepare_fb);
 
 /*
  * Shadow-buffered Planes
  */
 
+/**
+ * __drm_gem_shadow_plane_state_init - initializes shadow-buffered plane state
+ * @plane: the plane
+ * @shadow_plane_state: the shadow-buffered plane state
+ *
+ * This function initializes a pre-allocated shadow-buffered plane state.
+ * Helpful for drivers that subclass struct drm_shadow_plane_state.
+ */
+void __drm_gem_shadow_plane_state_init(struct drm_plane *plane,
+                                      struct drm_shadow_plane_state 
*shadow_plane_state)
+{
+       __drm_atomic_helper_plane_state_init(&shadow_plane_state->base, plane);
+       drm_format_conv_state_init(&shadow_plane_state->fmtcnv_state);
+}
+EXPORT_SYMBOL(__drm_gem_shadow_plane_state_init);
+
+/**
+ * drm_gem_create_shadow_plane_state - creates a shadow-buffered plane state
+ * @plane: the plane
+ *
+ * This function implements struct &drm_plane_funcs.atomic_create_state for
+ * shadow-buffered planes. It assumes the new state to be of type
+ * struct drm_shadow_plane_state.
+ *
+ * Returns:
+ * A pointer to a new plane state on success, or an ERR_PTR()-encoded
+ * error code otherwise.
+ */
+struct drm_plane_state *drm_gem_create_shadow_plane_state(struct drm_plane 
*plane)
+{
+       struct drm_shadow_plane_state *shadow_plane_state;
+
+       shadow_plane_state = kzalloc_obj(*shadow_plane_state);
+       if (!shadow_plane_state)
+               return ERR_PTR(-ENOMEM);
+
+       __drm_gem_shadow_plane_state_init(plane, shadow_plane_state);
+
+       return &shadow_plane_state->base;
+}
+EXPORT_SYMBOL(drm_gem_create_shadow_plane_state);
+
 /**
  * __drm_gem_duplicate_shadow_plane_state - duplicates shadow-buffered plane 
state
  * @plane: the plane
  * @new_shadow_plane_state: the new shadow-buffered plane state
  *
diff --git a/include/drm/drm_gem_atomic_helper.h 
b/include/drm/drm_gem_atomic_helper.h
index 3e01c619a25e..43657d8fb1c8 100644
--- a/include/drm/drm_gem_atomic_helper.h
+++ b/include/drm/drm_gem_atomic_helper.h
@@ -93,10 +93,13 @@ void __drm_gem_duplicate_shadow_plane_state(struct 
drm_plane *plane,
 void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state 
*shadow_plane_state);
 void __drm_gem_reset_shadow_plane(struct drm_plane *plane,
                                  struct drm_shadow_plane_state 
*shadow_plane_state);
 
 void drm_gem_reset_shadow_plane(struct drm_plane *plane);
+void __drm_gem_shadow_plane_state_init(struct drm_plane *plane,
+                                      struct drm_shadow_plane_state 
*shadow_plane_state);
+struct drm_plane_state *drm_gem_create_shadow_plane_state(struct drm_plane 
*plane);
 struct drm_plane_state *drm_gem_duplicate_shadow_plane_state(struct drm_plane 
*plane);
 void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane,
                                        struct drm_plane_state *plane_state);
 
 /**

-- 
2.54.0

Reply via email to