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
