Hi Laurent, On 17/12/2017 01:17, Laurent Pinchart wrote: > Color keying is the action of replacing pixels matching a given color > (or range of colors) with transparent pixels in an overlay when > performing blitting. Depending on the hardware capabilities, the > matching pixel can either become fully transparent, or gain a > programmable alpha value. > > Color keying is found in a large number of devices whose capabilities > often differ, but they still have enough common features in range to > standardize color key properties. This commit adds four properties > related to color keying named colorkey.min, colorkey.max, colorkey.alpha > and colorkey.mode. Additional properties can be defined by drivers to > expose device-specific features. > > Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@xxxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/drm_atomic.c | 16 +++++++ > drivers/gpu/drm/drm_blend.c | 108 +++++++++++++++++++++++++++++++++++++++++++ > include/drm/drm_blend.h | 4 ++ > include/drm/drm_plane.h | 28 ++++++++++- > 4 files changed, 155 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index 37445d50816a..4f57ec25e04d 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -756,6 +756,14 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, > state->rotation = val; > } else if (property == plane->zpos_property) { > state->zpos = val; > + } else if (property == plane->colorkey.mode_property) { > + state->colorkey.mode = val; > + } else if (property == plane->colorkey.min_property) { > + state->colorkey.min = val; > + } else if (property == plane->colorkey.max_property) { > + state->colorkey.max = val; > + } else if (property == plane->colorkey.value_property) { > + state->colorkey.value = val; > } else if (plane->funcs->atomic_set_property) { > return plane->funcs->atomic_set_property(plane, state, > property, val); > @@ -815,6 +823,14 @@ drm_atomic_plane_get_property(struct drm_plane *plane, > *val = state->rotation; > } else if (property == plane->zpos_property) { > *val = state->zpos; > + } else if (property == plane->colorkey.mode_property) { > + *val = state->colorkey.mode; > + } else if (property == plane->colorkey.min_property) { > + *val = state->colorkey.min; > + } else if (property == plane->colorkey.max_property) { > + *val = state->colorkey.max; > + } else if (property == plane->colorkey.value_property) { > + *val = state->colorkey.value; > } else if (plane->funcs->atomic_get_property) { > return plane->funcs->atomic_get_property(plane, state, property, val); > } else { > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c > index 2e5e089dd912..79da7d8a22e2 100644 > --- a/drivers/gpu/drm/drm_blend.c > +++ b/drivers/gpu/drm/drm_blend.c > @@ -98,6 +98,10 @@ > * planes. Without this property the primary plane is always below the cursor > * plane, and ordering between all other planes is undefined. > * > + * - Color keying is set up with drm_plane_create_colorkey_properties(). It adds > + * support for replacing a range of colors with a transparent color in the > + * 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). > @@ -405,3 +409,107 @@ int drm_atomic_normalize_zpos(struct drm_device *dev, > return 0; > } > EXPORT_SYMBOL(drm_atomic_normalize_zpos); > + > +/** > + * drm_plane_create_colorkey_properties - create colorkey properties > + * @plane: drm plane > + * @modes: array of supported color keying modes > + * @num_modes: number of modes in the modes array > + * @replace: if true create the colorkey.replacement property > + * > + * This function creates the generic color keying properties and attach them to > + * the plane to enable color keying control for blending operations. > + * > + * Color keying is controlled through four properties: > + * > + * colorkey.mode: > + * The mode is an enumerated property that controls how color keying > + * operates. Modes are driver-specific, except for a "disabled" mode that > + * disables color keying and is guaranteed to exist if color keying is > + * supported. > + * > + * colorkey.min, colorkey.max: > + * Those two properties specify the colors that are replaced by transparent > + * pixels. Pixel whose values are in the [min, max] range are replaced, all > + * other pixels are left untouched. The minimum and maximum values are > + * expressed as a 64-bit integer in AXYZ16161616 format, where A is the > + * alpha value and X, Y and Z correspond to the color components of the > + * plane's pixel format. In most cases XYZ will be either RGB or YUV. > + * > + * When a single color key is supported instead of a range, userspace shall > + * set the min and max properties to the same value, and drivers return an > + * error from their plane atomic check when the min and max values differ. > + * > + * Note that depending on the selected mode, not all components might be > + * used for comparison. For instance a device could support color keying in > + * YUV format using luma (Y) matching only, ignoring the chroma components. > + * This behaviour is driver-specific. > + * > + * colorkey.value: > + * This property specifies the color value that replaces pixels matching > + * the [min, max] range. The value is expressed in AXYZ16161616 format as > + * the min and max properties. > + * > + * This property is optional and only present when the device supports > + * configurable color replacement for matching pixels in the plane. If > + * color keying capabilities of the device are limited to making the > + * matching pixels fully transparent the colorkey.value property won't be > + * created. > + * > + * Note that depending on the device, or the selected mode, not all > + * components might be used for value replacement. For instance a device > + * could support replacing the alpha value of the matching pixels but not > + * its color components. This behaviour is driver-specific. > + * > + * The @modes parameter points to an array of all color keying modes supported > + * by the plane. The first mode has to be named "disabled" and have value 0. All > + * other modes are driver-specific, and at least one mode has to be provided in > + * addition to the "disabled" mode. > + * > + * Returns: > + * Zero on success, negative errno on failure. > + */ > +int drm_plane_create_colorkey_properties(struct drm_plane *plane, > + const struct drm_prop_enum_list *modes, > + unsigned int num_modes, bool replace) > +{ > +#define CREATE_COLORKEY_PROP(plane, name, type, args...) ({ \ > + prop = drm_property_create_##type(plane->dev, 0, "colorkey." #name, \ > + args); \ > + if (prop) { \ > + drm_object_attach_property(&plane->base, prop, 0); \ > + plane->colorkey.name##_property = prop; \ > + } \ > + prop; \ > +}) > + > + struct drm_property *prop; > + > + /* > + * A minimum of two modes are required, with the first mode must named > + * "disabled". > + */ > + if (!modes || num_modes == 0 || strcmp(modes[0].name, "disabled")) > + return -EINVAL; > + > + prop = CREATE_COLORKEY_PROP(plane, mode, enum, modes, num_modes); > + if (!prop) > + return -ENOMEM; > + > + prop = CREATE_COLORKEY_PROP(plane, min, range, 0, U64_MAX); > + if (!prop) > + return -ENOMEM; > + > + prop = CREATE_COLORKEY_PROP(plane, max, range, 0, U64_MAX); > + if (!prop) > + return -ENOMEM; > + > + if (replace) { > + prop = CREATE_COLORKEY_PROP(plane, value, range, 0, U64_MAX); > + if (!prop) > + return -ENOMEM; > + } #undef CREATE_COLORKEY_PROP ? > + > + return 0; > +} > +EXPORT_SYMBOL(drm_plane_create_colorkey_properties); > diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h > index 17606026590b..1d4c965dd5e2 100644 > --- a/include/drm/drm_blend.h > +++ b/include/drm/drm_blend.h > @@ -49,4 +49,8 @@ int drm_plane_create_zpos_immutable_property(struct drm_plane *plane, > unsigned int zpos); > int drm_atomic_normalize_zpos(struct drm_device *dev, > struct drm_atomic_state *state); > + > +int drm_plane_create_colorkey_properties(struct drm_plane *plane, > + const struct drm_prop_enum_list *modes, > + unsigned int num_modes, bool replace); > #endif > diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h > index 8185e3468a23..a5804a4ea5c3 100644 > --- a/include/drm/drm_plane.h > +++ b/include/drm/drm_plane.h > @@ -52,6 +52,13 @@ struct drm_modeset_acquire_ctx; > * where N is the number of active planes for given crtc. Note that > * the driver must call drm_atomic_normalize_zpos() to update this before > * it can be trusted. > + * @colorkey.mode: color key mode. 0 disabled color keying, other values are > + * driver-specific. > + * @colorkey.min: color key range minimum. The value is stored in AXYZ16161616 > + * format, where A is the alpha value and X, Y and Z correspond to the > + * color components of the plane's pixel format (usually RGB or YUV). > + * @colorkey.max: color key range maximum (in AXYZ16161616 format) > + * @colorkey.value: color key replacement value (in in AXYZ16161616 format) > * @src: clipped source coordinates of the plane (in 16.16) > * @dst: clipped destination coordinates of the plane > * @state: backpointer to global drm_atomic_state > @@ -112,6 +119,14 @@ struct drm_plane_state { > unsigned int zpos; > unsigned int normalized_zpos; > > + /* Plane colorkey */ > + struct { > + unsigned int mode; > + u64 min; > + u64 max; > + u64 value; > + } colorkey; > + > /* Clipped coordinates */ > struct drm_rect src, dst; > > @@ -481,9 +496,13 @@ enum drm_plane_type { > * @funcs: helper functions > * @properties: property tracking for this plane > * @type: type of plane (overlay, primary, cursor) > + * @helper_private: mid-layer private data > * @zpos_property: zpos property for this plane > * @rotation_property: rotation property for this plane > - * @helper_private: mid-layer private data > + * @colorkey.mode_property: color key mode property > + * @colorkey.min_property: color key range minimum property > + * @colorkey.max_property: color key range maximum property > + * @colorkey.value_property: color key replacement value property > */ > struct drm_plane { > struct drm_device *dev; > @@ -558,6 +577,13 @@ struct drm_plane { > > struct drm_property *zpos_property; > struct drm_property *rotation_property; > + > + struct { > + struct drm_property *mode_property; > + struct drm_property *min_property; > + struct drm_property *max_property; > + struct drm_property *value_property; > + } colorkey; > }; > > #define obj_to_plane(x) container_of(x, struct drm_plane, base) > Apart from that, Reviewed-by: Neil Armstrong <narmstrong@xxxxxxxxxxxx>