[V7 07/45] drm/colorop: Add 1D Curve subtype
Louis Chauvet
louis.chauvet at bootlin.com
Fri Feb 28 09:24:12 UTC 2025
Le 28/02/2025 à 02:07, Alex Hung a écrit :
>
>
> On 2/25/25 03:13, Louis Chauvet wrote:
>>
>>
>> Le 20/12/2024 à 05:33, Alex Hung a écrit :
>>> From: Harry Wentland <harry.wentland at amd.com>
>>>
>>> Add a new drm_colorop with DRM_COLOROP_1D_CURVE with two subtypes:
>>> DRM_COLOROP_1D_CURVE_SRGB_EOTF and DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF.
>>>
>>> Signed-off-by: Harry Wentland <harry.wentland at amd.com>
>>> Co-developed-by: Alex Hung <alex.hung at amd.com>
>>> Signed-off-by: Alex Hung <alex.hung at amd.com>
>>> ---
>>> v5:
>>> - Add drm_get_colorop_curve_1d_type_name in header
>>> - Add drm_colorop_init
>>> - Set default curve
>>> - Add kernel docs
>>>
>>> v4:
>>> - Use drm_colorop_curve_1d_type_enum_list to get name (Pekka)
>>> - Create separate init function for 1D curve
>>> - Pass supported TFs into 1D curve init function
>>>
>>> drivers/gpu/drm/drm_atomic_uapi.c | 18 ++--
>>> drivers/gpu/drm/drm_colorop.c | 134 ++++++++++++++++++++++++++++++
>>> include/drm/drm_colorop.h | 60 +++++++++++++
>>> 3 files changed, 207 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/
>>> drm_atomic_uapi.c
>>> index 59fc25b59100..9a5dbf0a1306 100644
>>> --- a/drivers/gpu/drm/drm_atomic_uapi.c
>>> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
>>> @@ -648,11 +648,17 @@ 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)
>>> {
>>> - drm_dbg_atomic(colorop->dev,
>>> - "[COLOROP:%d] unknown property [PROP:%d:%s]]\n",
>>> - colorop->base.id,
>>> - property->base.id, property->name);
>>> - return -EINVAL;
>>> + if (property == colorop->curve_1d_type_property) {
>>> + state->curve_1d_type = val;
>>> + } else {
>>> + drm_dbg_atomic(colorop->dev,
>>> + "[COLOROP:%d:%d] unknown property [PROP:%d:%s]]\n",
>>> + colorop->base.id, colorop->type,
>>> + property->base.id, property->name);
>>> + return -EINVAL;
>>> + }
>>> +
>>> + return 0;
>>> }
>>> static int
>>> @@ -662,6 +668,8 @@ drm_atomic_colorop_get_property(struct drm_colorop
>>> *colorop,
>>> {
>>> if (property == colorop->type_property) {
>>> *val = colorop->type;
>>> + } else if (property == colorop->curve_1d_type_property) {
>>> + *val = state->curve_1d_type;
>>> } else {
>>> return -EINVAL;
>>> }
>>> diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/
>>> drm_colorop.c
>>> index 1459a28c7e7b..a42de0aa48e1 100644
>>> --- a/drivers/gpu/drm/drm_colorop.c
>>> +++ b/drivers/gpu/drm/drm_colorop.c
>>> @@ -31,6 +31,123 @@
>>> #include "drm_crtc_internal.h"
>>> +static const struct drm_prop_enum_list drm_colorop_type_enum_list[] = {
>>> + { DRM_COLOROP_1D_CURVE, "1D Curve" },
>>> +};
>>> +
>>> +static const char * const colorop_curve_1d_type_names[] = {
>>> + [DRM_COLOROP_1D_CURVE_SRGB_EOTF] = "sRGB EOTF",
>>> + [DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF] = "sRGB Inverse EOTF",
>>> +};
>>> +
>>> +
>>> +/* Init Helpers */
>>> +
>>> +static int drm_colorop_init(struct drm_device *dev, struct
>>> drm_colorop *colorop,
>>> + struct drm_plane *plane, enum drm_colorop_type type)
>>> +{
>>> + struct drm_mode_config *config = &dev->mode_config;
>>> + struct drm_property *prop;
>>> + int ret = 0;
>>> +
>>> + ret = drm_mode_object_add(dev, &colorop->base,
>>> DRM_MODE_OBJECT_COLOROP);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + colorop->base.properties = &colorop->properties;
>>> + colorop->dev = dev;
>>> + colorop->type = type;
>>> + colorop->plane = plane;
>>> +
>>> + list_add_tail(&colorop->head, &config->colorop_list);
>>> + colorop->index = config->num_colorop++;
>>> +
>>> + /* add properties */
>>> +
>>> + /* type */
>>> + prop = drm_property_create_enum(dev,
>>> + DRM_MODE_PROP_IMMUTABLE,
>>> + "TYPE", drm_colorop_type_enum_list,
>>> + ARRAY_SIZE(drm_colorop_type_enum_list));
>>
>> I think this function belongs to the previous patch "Add TYPE property".
>
> This function is only called by the first colorop. Some pieces of the
> code in this function are introduced with the first colorop (1D curve)
> so it makes sense to include it here.
True! I did not saw it, you can keep it here indeed
>>
>>> +
>>> + if (!prop)
>>> + return -ENOMEM;
>>> +
>>> + colorop->type_property = prop;
>>> +
>>> + drm_object_attach_property(&colorop->base,
>>> + colorop->type_property,
>>> + colorop->type);
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +/**
>>> + * drm_colorop_curve_1d_init - Initialize a DRM_COLOROP_1D_CURVE
>>> + *
>>> + * @dev: DRM device
>>> + * @colorop: The drm_colorop object to initialize
>>> + * @plane: The associated drm_plane
>>> + * @supported_tfs: A bitfield of supported drm_colorop_curve_1d_init
>>> enum values,
>>> + * created using BIT(curve_type) and combined with
>>> the OR '|'
>>> + * operator.
>>> + * @return zero on success, -E value on failure
>>> + */
>>> +int drm_colorop_curve_1d_init(struct drm_device *dev, struct
>>> drm_colorop *colorop,
>>> + struct drm_plane *plane, u64 supported_tfs)
>>> +{
>>> + struct drm_prop_enum_list enum_list[DRM_COLOROP_1D_CURVE_COUNT];
>>> + int i, len;
>>> +
>>> + struct drm_property *prop;
>>> + int ret;
>>> +
>>> + if (!supported_tfs) {
>>> + drm_err(dev,
>>> + "No supported TFs for new 1D curve colorop on [PLANE:%d:
>>> %s]\n",
>>> + plane->base.id, plane->name);
>>> + return -EINVAL;
>>> + }
>>> +
>>> + if ((supported_tfs & -BIT(DRM_COLOROP_1D_CURVE_COUNT)) != 0) {
>>> + drm_err(dev, "Unknown TF provided on [PLANE:%d:%s]\n",
>>> + plane->base.id, plane->name);
>>> + return -EINVAL;
>>> + }
>>> +
>>> + ret = drm_colorop_init(dev, colorop, plane, DRM_COLOROP_1D_CURVE);
>>> + if (ret)
>>> + return ret;
>>> +
>>> + len = 0;
>>> + for (i = 0; i < DRM_COLOROP_1D_CURVE_COUNT; i++) {
>>> + if ((supported_tfs & BIT(i)) == 0)
>>> + continue;
>>> +
>>> + enum_list[len].type = i;
>>> + enum_list[len].name = colorop_curve_1d_type_names[i];
>>> + len++;
>>> + }
>>> +
>>> + if (WARN_ON(len <= 0))
>>> + return -EINVAL;
>>> +
>>> +
>>> + /* initialize 1D curve only attribute */
>>> + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ATOMIC,
>>> "CURVE_1D_TYPE",
>>> + enum_list, len);
>>> + if (!prop)
>>> + return -ENOMEM;
>>> +
>>> + colorop->curve_1d_type_property = prop;
>>> + drm_object_attach_property(&colorop->base, colorop-
>>>> curve_1d_type_property,
>>> + enum_list[0].type);
>>> + drm_colorop_reset(colorop);
>>> +
>>> + return 0;
>>> +}
>>> +EXPORT_SYMBOL(drm_colorop_curve_1d_init);
>>> +
>>> static void __drm_atomic_helper_colorop_duplicate_state(struct
>>> drm_colorop *colorop,
>>> struct drm_colorop_state *state)
>>> {
>>> @@ -70,7 +187,16 @@ void drm_colorop_atomic_destroy_state(struct
>>> drm_colorop *colorop,
>>> static void __drm_colorop_state_reset(struct drm_colorop_state
>>> *colorop_state,
>>> struct drm_colorop *colorop)
>>> {
>>> + u64 val;
>>> +
>>> colorop_state->colorop = colorop;
>>> +
>>> + if (colorop->curve_1d_type_property) {
>>> + drm_object_property_get_default_value(&colorop->base,
>>> + colorop->curve_1d_type_property,
>>> + &val);
>>> + colorop_state->curve_1d_type = val;
>>> + }
>>> }
>>> /**
>>> @@ -114,3 +240,11 @@ const char *drm_get_colorop_type_name(enum
>>> drm_colorop_type type
>>> return colorop_type_name[type];
>>
>> Probably a dumb question: can't we use drm_colorop_type_enum_list
>> instead of colorop_type_name in the drm_get_colorop_type_name function?
>> So we will avoid duplicating the string "1D Curve".
>
> Using drm_colorop_type_enum_list in drm_get_colorop_type_name needs
> enumerating the list every time (extra CPU cycles) unlike using
> colorop_type_name[].
Why do you want to iterate over the list? See [1]/[2], it seems to be a
common patter to simply order the enum list and use the index in it.
Furthermore, I don't expect this function to be called often, so a list
enumeration doesn't seem expensive (maybe called almost never? The only
usage I found in your series is __drm_state_dump).
I don't have a strong opinion on this, so:
Reviewed-by: Louis Chauvet <louis.chauvet at bootlin.com>
Thanks!
Louis Chauvet
[1]:https://elixir.bootlin.com/linux/v6.13.4/source/drivers/gpu/drm/drm_connector.c#L1238-L1259
[2]:https://elixir.bootlin.com/linux/v6.13.4/source/drivers/gpu/drm/drm_connector.c#L972-L994
>>
>>> }
>>
>> Thanks,
>> Louis Chauvet
>>
>> [...]
>>
>
--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
More information about the dri-devel
mailing list