On 2026-03-18 12:12, Melissa Wen wrote:
> As we do for CRTC color mgmt properties, use color_mgmt_changed flag to
> track any value changes in the color pipeline of a given plane, so that
> drivers can update color blocks as soon as plane color pipeline or
> individual colorop values change.
> 
> Signed-off-by: Melissa Wen <[email protected]>

Reviewed-by: Harry Wentland <[email protected]>

Harry

> ---
>  drivers/gpu/drm/drm_atomic_uapi.c | 53 ++++++++++++++++++++++++-------
>  include/drm/drm_atomic_uapi.h     |  2 +-
>  2 files changed, 43 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c 
> b/drivers/gpu/drm/drm_atomic_uapi.c
> index 87de41fb4459..713fa9e81732 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -265,13 +265,19 @@ EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
>   *
>   * Helper function to select the color pipeline on a plane by setting
>   * it to the first drm_colorop element of the pipeline.
> + *
> + * Return: true if plane color pipeline value changed, false otherwise.
>   */
> -void
> +bool
>  drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
>                                struct drm_colorop *colorop)
>  {
>       struct drm_plane *plane = plane_state->plane;
>  
> +     /* Color pipeline didn't change */
> +     if (plane_state->color_pipeline == colorop)
> +             return false;
> +
>       if (colorop)
>               drm_dbg_atomic(plane->dev,
>                              "Set [COLOROP:%d] for [PLANE:%d:%s] state %p\n",
> @@ -283,6 +289,8 @@ drm_atomic_set_colorop_for_plane(struct drm_plane_state 
> *plane_state,
>                              plane->base.id, plane->name, plane_state);
>  
>       plane_state->color_pipeline = colorop;
> +
> +     return true;
>  }
>  EXPORT_SYMBOL(drm_atomic_set_colorop_for_plane);
>  
> @@ -600,7 +608,7 @@ static int drm_atomic_plane_set_property(struct drm_plane 
> *plane,
>               if (val && !colorop)
>                       return -EACCES;
>  
> -             drm_atomic_set_colorop_for_plane(state, colorop);
> +             state->color_mgmt_changed |= 
> drm_atomic_set_colorop_for_plane(state, colorop);
>       } else if (property == config->prop_fb_damage_clips) {
>               ret = drm_property_replace_blob_from_id(dev,
>                                       &state->fb_damage_clips,
> @@ -709,11 +717,11 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
>  static int drm_atomic_color_set_data_property(struct drm_colorop *colorop,
>                                             struct drm_colorop_state *state,
>                                             struct drm_property *property,
> -                                           uint64_t val)
> +                                           uint64_t val,
> +                                           bool *replaced)
>  {
>       ssize_t elem_size = -1;
>       ssize_t size = -1;
> -     bool replaced = false;
>  
>       switch (colorop->type) {
>       case DRM_COLOROP_1D_LUT:
> @@ -735,28 +743,39 @@ static int drm_atomic_color_set_data_property(struct 
> drm_colorop *colorop,
>                                                &state->data,
>                                                val,
>                                                -1, size, elem_size,
> -                                              &replaced);
> +                                              replaced);
>  }
>  
>  static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
>                                          struct drm_colorop_state *state,
>                                          struct drm_file *file_priv,
>                                          struct drm_property *property,
> -                                        uint64_t val)
> +                                        uint64_t val,
> +                                        bool *replaced)
>  {
>       if (property == colorop->bypass_property) {
> -             state->bypass = val;
> +             if (state->bypass != val) {
> +                     state->bypass = val;
> +                     *replaced = true;
> +             }
>       } else if (property == colorop->lut1d_interpolation_property) {
>               colorop->lut1d_interpolation = val;
>       } else if (property == colorop->curve_1d_type_property) {
> -             state->curve_1d_type = val;
> +             if (state->curve_1d_type != val) {
> +                     state->curve_1d_type = val;
> +                     *replaced = true;
> +             }
>       } else if (property == colorop->multiplier_property) {
> -             state->multiplier = val;
> +             if (state->multiplier != val) {
> +                     state->multiplier = val;
> +                     *replaced = true;
> +             }
>       } else if (property == colorop->lut3d_interpolation_property) {
>               colorop->lut3d_interpolation = val;
>       } else if (property == colorop->data_property) {
>               return drm_atomic_color_set_data_property(colorop, state,
> -                                                       property, val);
> +                                                       property, val,
> +                                                       replaced);
>       } else {
>               drm_dbg_atomic(colorop->dev,
>                              "[COLOROP:%d:%d] unknown property 
> [PROP:%d:%s]\n",
> @@ -1273,6 +1292,8 @@ int drm_atomic_set_property(struct drm_atomic_state 
> *state,
>       case DRM_MODE_OBJECT_COLOROP: {
>               struct drm_colorop *colorop = obj_to_colorop(obj);
>               struct drm_colorop_state *colorop_state;
> +             struct drm_plane_state *plane_state;
> +             bool replaced = false;
>  
>               colorop_state = drm_atomic_get_colorop_state(state, colorop);
>               if (IS_ERR(colorop_state)) {
> @@ -1281,7 +1302,17 @@ int drm_atomic_set_property(struct drm_atomic_state 
> *state,
>               }
>  
>               ret = drm_atomic_colorop_set_property(colorop, colorop_state,
> -                                                   file_priv, prop, 
> prop_value);
> +                                                   file_priv, prop, 
> prop_value,
> +                                                   &replaced);
> +             if (ret || !replaced)
> +                     break;
> +
> +             plane_state = drm_atomic_get_plane_state(state, colorop->plane);
> +             if (IS_ERR(plane_state)) {
> +                     ret = PTR_ERR(plane_state);
> +                     break;
> +             }
> +             plane_state->color_mgmt_changed = true;
>               break;
>       }
>       default:
> diff --git a/include/drm/drm_atomic_uapi.h b/include/drm/drm_atomic_uapi.h
> index 436315523326..2016b6ca0f3e 100644
> --- a/include/drm/drm_atomic_uapi.h
> +++ b/include/drm/drm_atomic_uapi.h
> @@ -50,7 +50,7 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state 
> *plane_state,
>                             struct drm_crtc *crtc);
>  void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
>                                struct drm_framebuffer *fb);
> -void drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
> +bool drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
>                                     struct drm_colorop *colorop);
>  int __must_check
>  drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,

Reply via email to