From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com ([192.55.52.120]:32164 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1165183AbeE1NPI (ORCPT ); Mon, 28 May 2018 09:15:08 -0400 Date: Mon, 28 May 2018 16:15:01 +0300 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= To: Dmitry Osipenko Cc: Laurent Pinchart , Thierry Reding , Neil Armstrong , Maxime Ripard , dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Alexandru Gheorghe , Russell King , Ben Skeggs , Sinclair Yeh , Thomas Hellstrom , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH v2 1/2] drm: Add generic colorkey properties Message-ID: <20180528131501.GK23723@intel.com> References: <20180526155623.12610-1-digetx@gmail.com> <20180526155623.12610-2-digetx@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20180526155623.12610-2-digetx@gmail.com> Sender: linux-renesas-soc-owner@vger.kernel.org List-ID: On Sat, May 26, 2018 at 06:56:22PM +0300, Dmitry Osipenko 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 adjustment > of the pixels component values. > > 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 nine generic DRM plane > properties related to the color keying to cover various HW capabilities. > > This patch is based on the initial work done by Laurent Pinchart, most of > credits for this patch goes to him. > > Signed-off-by: Dmitry Osipenko > --- > drivers/gpu/drm/drm_atomic.c | 36 ++++++ > drivers/gpu/drm/drm_blend.c | 229 +++++++++++++++++++++++++++++++++++ > include/drm/drm_blend.h | 3 + > include/drm/drm_plane.h | 77 ++++++++++++ > 4 files changed, 345 insertions(+) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index 895741e9cd7d..5b808cb68654 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -799,6 +799,24 @@ 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.format_property) { > + state->colorkey.format = val; > + } else if (property == plane->colorkey.mask_property) { > + state->colorkey.mask = val; > + } else if (property == plane->colorkey.inverted_match_property) { > + state->colorkey.inverted_match = val; > + } else if (property == plane->colorkey.replacement_mask_property) { > + state->colorkey.replacement_mask = val; > + } else if (property == plane->colorkey.replacement_value_property) { > + state->colorkey.replacement_value = val; > + } else if (property == plane->colorkey.replacement_format_property) { > + state->colorkey.replacement_format = val; > } else if (property == plane->color_encoding_property) { > state->color_encoding = val; > } else if (property == plane->color_range_property) { > @@ -864,6 +882,24 @@ 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.format_property) { > + *val = state->colorkey.format; > + } else if (property == plane->colorkey.mask_property) { > + *val = state->colorkey.mask; > + } else if (property == plane->colorkey.inverted_match_property) { > + *val = state->colorkey.inverted_match; > + } else if (property == plane->colorkey.replacement_mask_property) { > + *val = state->colorkey.replacement_mask; > + } else if (property == plane->colorkey.replacement_value_property) { > + *val = state->colorkey.replacement_value; > + } else if (property == plane->colorkey.replacement_format_property) { > + *val = state->colorkey.replacement_format; > } else if (property == plane->color_encoding_property) { > *val = state->color_encoding; > } else if (property == plane->color_range_property) { > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c > index a16a74d7e15e..05e5632ce375 100644 > --- a/drivers/gpu/drm/drm_blend.c > +++ b/drivers/gpu/drm/drm_blend.c > @@ -107,6 +107,11 @@ > * planes. Without this property the primary plane is always below the cursor > * plane, and ordering between all other planes is undefined. > * > + * colorkey: > + * 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). > @@ -448,3 +453,227 @@ int drm_atomic_normalize_zpos(struct drm_device *dev, > return 0; > } > EXPORT_SYMBOL(drm_atomic_normalize_zpos); > + > +static const char * const plane_colorkey_mode_name[] = { > + [DRM_PLANE_COLORKEY_MODE_DISABLED] = "disabled", > + [DRM_PLANE_COLORKEY_MODE_SRC] = "src-match-src-replace", > + [DRM_PLANE_COLORKEY_MODE_DST] = "dst-match-src-replace", This list seems way more limited than I was expecting, at least when compared to all the different props you're proposing to add. > +}; > + > +/** > + * drm_plane_create_colorkey_properties - create colorkey properties > + * @plane: drm plane > + * @supported_modes: bitmask of supported color keying modes > + * > + * 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 nine properties: > + * > + * colorkey.mode: > + * The mode is an enumerated property that controls how color keying > + * operates. The "disabled" mode that disables color keying and is > + * very likely to exist if color keying is supported, it should be the > + * default mode. > + * > + * colorkey.min, colorkey.max: > + * These two properties specify the colors that are treated as the color > + * key. Pixel whose value is in the [min, max] range is the color key > + * matching pixel. 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 colorkey.format. > + * In most cases XYZ will be either RGB or YUV. > + * > + * When a single color key is desired instead of a range, userspace shall > + * set the min and max properties to the same value. > + * > + * Drivers return an error from their plane atomic check if range can't be > + * handled. > + * > + * colorkey.format: > + * This property specifies the pixel format for the colorkey.min / max > + * properties. The format is given in a form of DRM fourcc code. Umm. Why we do even need this? This seems incompatible with your earlier "min/max are specified in 16bpc format" statement. > + * > + * Drivers return an error from their plane atomic check if pixel format > + * is unsupported. > + * > + * colorkey.mask: > + * This property specifies the pixel components mask. Unmasked pixel > + * components are not participating in the matching. This mask value is > + * applied to colorkey.min / max values. The mask value is given in a > + * form of DRM fourcc code corresponding to the colorkey.format property. > + * > + * For example: userspace shall set the colorkey.mask to 0x0000ff00 > + * to match only the green component if colorkey.format is set to > + * DRM_FORMAT_XRGB8888. > + * > + * Drivers return an error from their plane atomic check if mask value > + * can't be handled. > + * > + * colorkey.inverted-match: > + * This property specifies whether the matching min-max range should > + * be inverted, i.e. pixels outside of the given color range become > + * the color key match. > + * > + * Drivers return an error from their plane atomic check if inversion > + * mode can't be handled. Hmm. I'm trying to figure out what this means for the src vs. dst colorkey modes. Those pretty much already have an inverted meaning when compared to each other. So I can't figure out from these docs whether you're supposed to use this when you want a normal dst ckey or normal src key semantics. > + * > + * colorkey.replacement-value: > + * This property specifies the color value that replaces pixels matching > + * the color key. The value is expressed in AXYZ16161616 format, where A > + * is the alpha value and X, Y and Z correspond to the color components > + * of the colorkey.replacement-format. > + * > + * Drivers return an error from their plane atomic check if replacement > + * value can't be handled. > + * > + * colorkey.replacement-format: > + * This property specifies the pixel format for the > + * colorkey.replacement-value property. The format is given in a form of > + * DRM fourcc code. Again this seems at odds with the 16bpc replacement-value. > + * > + * Drivers return an error from their plane atomic check if replacement > + * pixel format is unsupported. > + * > + * colorkey.replacement-mask: > + * This property specifies the pixel components mask that defines > + * what components of the colorkey.replacement-value will participate in > + * replacement of the pixels color. Unmasked pixel components are not > + * participating in the replacement. Does that mean that the data for the unmasked bits will be coming from the source? > The mask value is given in a form of > + * DRM fourcc code corresponding to the colorkey.replacement-format > + * property. > + * > + * For example: userspace shall set the colorkey.replacement-mask to > + * 0x0000ff00 to replace only the green component if > + * colorkey.replacement-format is set to DRM_FORMAT_XRGB8888. > + * > + * Userspace shall set colorkey.replacement-mask to 0 to disable the color > + * replacement. In this case matching pixels become transparent. > + * > + * Drivers return an error from their plane atomic check if replacement > + * mask value can't be handled. > + * > + * Returns: > + * Zero on success, negative errno on failure. > + */ > +int drm_plane_create_colorkey_properties(struct drm_plane *plane, > + u32 supported_modes) > +{ > + struct drm_prop_enum_list modes_list[DRM_PLANE_COLORKEY_MODES_NUM]; > + struct drm_property *replacement_format_prop; > + struct drm_property *replacement_value_prop; > + struct drm_property *replacement_mask_prop; > + struct drm_property *inverted_match_prop; > + struct drm_property *format_prop; > + struct drm_property *mask_prop; > + struct drm_property *mode_prop; > + struct drm_property *min_prop; > + struct drm_property *max_prop; > + unsigned int modes_num = 0; > + unsigned int i; > + > + /* at least two modes should be supported */ > + if (!supported_modes) > + return -EINVAL; > + > + /* modes are driver-specific, build the list of supported modes */ > + for (i = 0; i < DRM_PLANE_COLORKEY_MODES_NUM; i++) { > + if (!(supported_modes & BIT(i))) > + continue; > + > + modes_list[modes_num].name = plane_colorkey_mode_name[i]; > + modes_list[modes_num].type = i; > + modes_num++; > + } > + > + mode_prop = drm_property_create_enum(plane->dev, 0, "colorkey.mode", > + modes_list, modes_num); > + if (!mode_prop) > + return -ENOMEM; > + > + mask_prop = drm_property_create_range(plane->dev, 0, "colorkey.mask", > + 0, U64_MAX); > + if (!mask_prop) > + goto err_destroy_mode_prop; > + > + min_prop = drm_property_create_range(plane->dev, 0, "colorkey.min", > + 0, U64_MAX); > + if (!min_prop) > + goto err_destroy_mask_prop; > + > + max_prop = drm_property_create_range(plane->dev, 0, "colorkey.max", > + 0, U64_MAX); > + if (!max_prop) > + goto err_destroy_min_prop; > + > + format_prop = drm_property_create_range(plane->dev, 0, > + "colorkey.format", > + 0, U32_MAX); > + if (!format_prop) > + goto err_destroy_max_prop; > + > + inverted_match_prop = drm_property_create_bool(plane->dev, 0, > + "colorkey.inverted-match"); > + if (!inverted_match_prop) > + goto err_destroy_format_prop; > + > + replacement_mask_prop = drm_property_create_range(plane->dev, 0, > + "colorkey.replacement-mask", > + 0, U64_MAX); > + if (!replacement_mask_prop) > + goto err_destroy_inverted_match_prop; > + > + replacement_value_prop = drm_property_create_range(plane->dev, 0, > + "colorkey.replacement-value", > + 0, U64_MAX); > + if (!replacement_value_prop) > + goto err_destroy_replacement_mask_prop; > + > + replacement_format_prop = drm_property_create_range(plane->dev, 0, > + "colorkey.replacement-format", > + 0, U64_MAX); > + if (!replacement_format_prop) > + goto err_destroy_replacement_value_prop; I don't think we want to add all these props for every driver/hardware. IMO the set of props we expose should depend on the supported set of colorkeying modes. > + > + drm_object_attach_property(&plane->base, min_prop, 0); > + drm_object_attach_property(&plane->base, max_prop, 0); > + drm_object_attach_property(&plane->base, mode_prop, 0); > + drm_object_attach_property(&plane->base, mask_prop, 0); > + drm_object_attach_property(&plane->base, format_prop, 0); > + drm_object_attach_property(&plane->base, inverted_match_prop, 0); > + drm_object_attach_property(&plane->base, replacement_mask_prop, 0); > + drm_object_attach_property(&plane->base, replacement_value_prop, 0); > + drm_object_attach_property(&plane->base, replacement_format_prop, 0); > + > + plane->colorkey.min_property = min_prop; > + plane->colorkey.max_property = max_prop; > + plane->colorkey.mode_property = mode_prop; > + plane->colorkey.mask_property = mask_prop; > + plane->colorkey.format_property = format_prop; > + plane->colorkey.inverted_match_property = inverted_match_prop; > + plane->colorkey.replacement_mask_property = replacement_mask_prop; > + plane->colorkey.replacement_value_property = replacement_value_prop; > + plane->colorkey.replacement_format_property = replacement_format_prop; > + > + return 0; > + > +err_destroy_replacement_value_prop: > + drm_property_destroy(plane->dev, replacement_value_prop); > +err_destroy_replacement_mask_prop: > + drm_property_destroy(plane->dev, replacement_mask_prop); > +err_destroy_inverted_match_prop: > + drm_property_destroy(plane->dev, inverted_match_prop); > +err_destroy_format_prop: > + drm_property_destroy(plane->dev, format_prop); > +err_destroy_max_prop: > + drm_property_destroy(plane->dev, max_prop); > +err_destroy_min_prop: > + drm_property_destroy(plane->dev, min_prop); > +err_destroy_mask_prop: > + drm_property_destroy(plane->dev, mask_prop); > +err_destroy_mode_prop: > + drm_property_destroy(plane->dev, mode_prop); > + > + return -ENOMEM; > +} > +EXPORT_SYMBOL(drm_plane_create_colorkey_properties); > diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h > index 330c561c4c11..8e80d33b643e 100644 > --- a/include/drm/drm_blend.h > +++ b/include/drm/drm_blend.h > @@ -52,4 +52,7 @@ 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, > + u32 supported_modes); > #endif > diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h > index 26fa50c2a50e..ff7f5ebe2b79 100644 > --- a/include/drm/drm_plane.h > +++ b/include/drm/drm_plane.h > @@ -32,6 +32,42 @@ struct drm_crtc; > struct drm_printer; > struct drm_modeset_acquire_ctx; > > +/** > + * enum drm_plane_colorkey_mode - uapi plane colorkey mode enumeration > + */ > +enum drm_plane_colorkey_mode { > + /** > + * @DRM_PLANE_COLORKEY_MODE_DISABLED: > + * > + * No color matching performed in this mode. This is the default > + * common mode. > + */ > + DRM_PLANE_COLORKEY_MODE_DISABLED, > + > + /** > + * @DRM_PLANE_COLORKEY_MODE_SRC: > + * > + * In this mode color matching is performed with the pixels of > + * the given plane and the matched pixels are fully (or partially) > + * replaced with the replacement color or become completely > + * transparent. > + */ > + DRM_PLANE_COLORKEY_MODE_SRC, > + > + /** > + * @DRM_PLANE_COLORKEY_MODE_DST: > + * > + * In this mode color matching is performed with the pixels of the > + * planes z-positioned under the given plane and the pixels of the > + * hovering plane that are xy-positioned as the underlying > + * color-matched pixels are fully (or partially) replaced with the > + * replacement color or become completely transparent. > + */ > + DRM_PLANE_COLORKEY_MODE_DST, > + > + DRM_PLANE_COLORKEY_MODES_NUM, > +}; > + > /** > * struct drm_plane_state - mutable plane state > * @plane: backpointer to the plane > @@ -54,6 +90,21 @@ struct drm_modeset_acquire_ctx; > * where N is the number of active planes for given crtc. Note that > * the driver must set drm_mode_config.normalize_zpos or call > * drm_atomic_normalize_zpos() to update this before it can be trusted. > + * @colorkey.mode: color key mode > + * @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.mask: color key mask value (in AXYZ16161616 format) > + * @colorkey.format: color key min/max/mask values pixel format (in > + * DRM_FORMAT_AXYZ16161616 form) > + * @colorkey.inverted_match: color key min-max matching range is inverted > + * @colorkey.replacement_mask: color key replacement mask value (in > + * AXYZ16161616 format) > + * @colorkey.replacement_value: color key replacement value (in > + * AXYZ16161616 format) > + * @colorkey.replacement_format: color key replacement value / mask > + * pixel format (in DRM_FORMAT_AXYZ16161616 form) > * @src: clipped source coordinates of the plane (in 16.16) > * @dst: clipped destination coordinates of the plane > * @state: backpointer to global drm_atomic_state > @@ -124,6 +175,19 @@ struct drm_plane_state { > unsigned int zpos; > unsigned int normalized_zpos; > > + /* Plane colorkey */ > + struct { > + enum drm_plane_colorkey_mode mode; > + u64 min; > + u64 max; > + u64 mask; > + u32 format; > + bool inverted_match; > + u64 replacement_mask; > + u64 replacement_value; > + u32 replacement_format; > + } colorkey; > + > /** > * @color_encoding: > * > @@ -510,6 +574,7 @@ enum drm_plane_type { > * @alpha_property: alpha property for this plane > * @zpos_property: zpos property for this plane > * @rotation_property: rotation property for this plane > + * @colorkey: colorkey properties for this plane > * @helper_private: mid-layer private data > */ > struct drm_plane { > @@ -587,6 +652,18 @@ struct drm_plane { > struct drm_property *zpos_property; > struct drm_property *rotation_property; > > + struct { > + struct drm_property *min_property; > + struct drm_property *max_property; > + struct drm_property *mode_property; > + struct drm_property *mask_property; > + struct drm_property *format_property; > + struct drm_property *inverted_match_property; > + struct drm_property *replacement_mask_property; > + struct drm_property *replacement_value_property; > + struct drm_property *replacement_format_property; > + } colorkey; > + > /** > * @color_encoding_property: > * > -- > 2.17.0 -- Ville Syrj�l� Intel From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= Subject: Re: [RFC PATCH v2 1/2] drm: Add generic colorkey properties Date: Mon, 28 May 2018 16:15:01 +0300 Message-ID: <20180528131501.GK23723@intel.com> References: <20180526155623.12610-1-digetx@gmail.com> <20180526155623.12610-2-digetx@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Content-Disposition: inline In-Reply-To: <20180526155623.12610-2-digetx@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Dmitry Osipenko Cc: Thomas Hellstrom , Laurent Pinchart , Neil Armstrong , Russell King , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-tegra@vger.kernel.org, Thierry Reding , Ben Skeggs , Rodrigo Vivi , Maxime Ripard , Alexandru Gheorghe , linux-media@vger.kernel.org List-Id: linux-tegra@vger.kernel.org T24gU2F0LCBNYXkgMjYsIDIwMTggYXQgMDY6NTY6MjJQTSArMDMwMCwgRG1pdHJ5IE9zaXBlbmtv IHdyb3RlOgo+IENvbG9yIGtleWluZyBpcyB0aGUgYWN0aW9uIG9mIHJlcGxhY2luZyBwaXhlbHMg bWF0Y2hpbmcgYSBnaXZlbiBjb2xvcgo+IChvciByYW5nZSBvZiBjb2xvcnMpIHdpdGggdHJhbnNw YXJlbnQgcGl4ZWxzIGluIGFuIG92ZXJsYXkgd2hlbgo+IHBlcmZvcm1pbmcgYmxpdHRpbmcuIERl cGVuZGluZyBvbiB0aGUgaGFyZHdhcmUgY2FwYWJpbGl0aWVzLCB0aGUKPiBtYXRjaGluZyBwaXhl bCBjYW4gZWl0aGVyIGJlY29tZSBmdWxseSB0cmFuc3BhcmVudCBvciBnYWluIGFkanVzdG1lbnQK PiBvZiB0aGUgcGl4ZWxzIGNvbXBvbmVudCB2YWx1ZXMuCj4gCj4gQ29sb3Iga2V5aW5nIGlzIGZv dW5kIGluIGEgbGFyZ2UgbnVtYmVyIG9mIGRldmljZXMgd2hvc2UgY2FwYWJpbGl0aWVzCj4gb2Z0 ZW4gZGlmZmVyLCBidXQgdGhleSBzdGlsbCBoYXZlIGVub3VnaCBjb21tb24gZmVhdHVyZXMgaW4g cmFuZ2UgdG8KPiBzdGFuZGFyZGl6ZSBjb2xvciBrZXkgcHJvcGVydGllcy4gVGhpcyBjb21taXQg YWRkcyBuaW5lIGdlbmVyaWMgRFJNIHBsYW5lCj4gcHJvcGVydGllcyByZWxhdGVkIHRvIHRoZSBj b2xvciBrZXlpbmcgdG8gY292ZXIgdmFyaW91cyBIVyBjYXBhYmlsaXRpZXMuCj4gCj4gVGhpcyBw YXRjaCBpcyBiYXNlZCBvbiB0aGUgaW5pdGlhbCB3b3JrIGRvbmUgYnkgTGF1cmVudCBQaW5jaGFy dCwgbW9zdCBvZgo+IGNyZWRpdHMgZm9yIHRoaXMgcGF0Y2ggZ29lcyB0byBoaW0uCj4gCj4gU2ln bmVkLW9mZi1ieTogRG1pdHJ5IE9zaXBlbmtvIDxkaWdldHhAZ21haWwuY29tPgo+IC0tLQo+ICBk cml2ZXJzL2dwdS9kcm0vZHJtX2F0b21pYy5jIHwgIDM2ICsrKysrKwo+ICBkcml2ZXJzL2dwdS9k cm0vZHJtX2JsZW5kLmMgIHwgMjI5ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr Cj4gIGluY2x1ZGUvZHJtL2RybV9ibGVuZC5oICAgICAgfCAgIDMgKwo+ICBpbmNsdWRlL2RybS9k cm1fcGxhbmUuaCAgICAgIHwgIDc3ICsrKysrKysrKysrKwo+ICA0IGZpbGVzIGNoYW5nZWQsIDM0 NSBpbnNlcnRpb25zKCspCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fYXRv bWljLmMgYi9kcml2ZXJzL2dwdS9kcm0vZHJtX2F0b21pYy5jCj4gaW5kZXggODk1NzQxZTljZDdk Li41YjgwOGNiNjg2NTQgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2RybV9hdG9taWMu Ywo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fYXRvbWljLmMKPiBAQCAtNzk5LDYgKzc5OSwy NCBAQCBzdGF0aWMgaW50IGRybV9hdG9taWNfcGxhbmVfc2V0X3Byb3BlcnR5KHN0cnVjdCBkcm1f cGxhbmUgKnBsYW5lLAo+ICAJCXN0YXRlLT5yb3RhdGlvbiA9IHZhbDsKPiAgCX0gZWxzZSBpZiAo cHJvcGVydHkgPT0gcGxhbmUtPnpwb3NfcHJvcGVydHkpIHsKPiAgCQlzdGF0ZS0+enBvcyA9IHZh bDsKPiArCX0gZWxzZSBpZiAocHJvcGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5Lm1vZGVfcHJvcGVy dHkpIHsKPiArCQlzdGF0ZS0+Y29sb3JrZXkubW9kZSA9IHZhbDsKPiArCX0gZWxzZSBpZiAocHJv cGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5Lm1pbl9wcm9wZXJ0eSkgewo+ICsJCXN0YXRlLT5jb2xv cmtleS5taW4gPSB2YWw7Cj4gKwl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcmtl eS5tYXhfcHJvcGVydHkpIHsKPiArCQlzdGF0ZS0+Y29sb3JrZXkubWF4ID0gdmFsOwo+ICsJfSBl bHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkuZm9ybWF0X3Byb3BlcnR5KSB7Cj4g KwkJc3RhdGUtPmNvbG9ya2V5LmZvcm1hdCA9IHZhbDsKPiArCX0gZWxzZSBpZiAocHJvcGVydHkg PT0gcGxhbmUtPmNvbG9ya2V5Lm1hc2tfcHJvcGVydHkpIHsKPiArCQlzdGF0ZS0+Y29sb3JrZXku bWFzayA9IHZhbDsKPiArCX0gZWxzZSBpZiAocHJvcGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5Lmlu dmVydGVkX21hdGNoX3Byb3BlcnR5KSB7Cj4gKwkJc3RhdGUtPmNvbG9ya2V5LmludmVydGVkX21h dGNoID0gdmFsOwo+ICsJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkucmVw bGFjZW1lbnRfbWFza19wcm9wZXJ0eSkgewo+ICsJCXN0YXRlLT5jb2xvcmtleS5yZXBsYWNlbWVu dF9tYXNrID0gdmFsOwo+ICsJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXku cmVwbGFjZW1lbnRfdmFsdWVfcHJvcGVydHkpIHsKPiArCQlzdGF0ZS0+Y29sb3JrZXkucmVwbGFj ZW1lbnRfdmFsdWUgPSB2YWw7Cj4gKwl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xv cmtleS5yZXBsYWNlbWVudF9mb3JtYXRfcHJvcGVydHkpIHsKPiArCQlzdGF0ZS0+Y29sb3JrZXku cmVwbGFjZW1lbnRfZm9ybWF0ID0gdmFsOwo+ICAJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFu ZS0+Y29sb3JfZW5jb2RpbmdfcHJvcGVydHkpIHsKPiAgCQlzdGF0ZS0+Y29sb3JfZW5jb2Rpbmcg PSB2YWw7Cj4gIAl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcl9yYW5nZV9wcm9w ZXJ0eSkgewo+IEBAIC04NjQsNiArODgyLDI0IEBAIGRybV9hdG9taWNfcGxhbmVfZ2V0X3Byb3Bl cnR5KHN0cnVjdCBkcm1fcGxhbmUgKnBsYW5lLAo+ICAJCSp2YWwgPSBzdGF0ZS0+cm90YXRpb247 Cj4gIAl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT56cG9zX3Byb3BlcnR5KSB7Cj4gIAkJ KnZhbCA9IHN0YXRlLT56cG9zOwo+ICsJfSBlbHNlIGlmIChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29s b3JrZXkubW9kZV9wcm9wZXJ0eSkgewo+ICsJCSp2YWwgPSBzdGF0ZS0+Y29sb3JrZXkubW9kZTsK PiArCX0gZWxzZSBpZiAocHJvcGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5Lm1pbl9wcm9wZXJ0eSkg ewo+ICsJCSp2YWwgPSBzdGF0ZS0+Y29sb3JrZXkubWluOwo+ICsJfSBlbHNlIGlmIChwcm9wZXJ0 eSA9PSBwbGFuZS0+Y29sb3JrZXkubWF4X3Byb3BlcnR5KSB7Cj4gKwkJKnZhbCA9IHN0YXRlLT5j b2xvcmtleS5tYXg7Cj4gKwl9IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcmtleS5m b3JtYXRfcHJvcGVydHkpIHsKPiArCQkqdmFsID0gc3RhdGUtPmNvbG9ya2V5LmZvcm1hdDsKPiAr CX0gZWxzZSBpZiAocHJvcGVydHkgPT0gcGxhbmUtPmNvbG9ya2V5Lm1hc2tfcHJvcGVydHkpIHsK PiArCQkqdmFsID0gc3RhdGUtPmNvbG9ya2V5Lm1hc2s7Cj4gKwl9IGVsc2UgaWYgKHByb3BlcnR5 ID09IHBsYW5lLT5jb2xvcmtleS5pbnZlcnRlZF9tYXRjaF9wcm9wZXJ0eSkgewo+ICsJCSp2YWwg PSBzdGF0ZS0+Y29sb3JrZXkuaW52ZXJ0ZWRfbWF0Y2g7Cj4gKwl9IGVsc2UgaWYgKHByb3BlcnR5 ID09IHBsYW5lLT5jb2xvcmtleS5yZXBsYWNlbWVudF9tYXNrX3Byb3BlcnR5KSB7Cj4gKwkJKnZh bCA9IHN0YXRlLT5jb2xvcmtleS5yZXBsYWNlbWVudF9tYXNrOwo+ICsJfSBlbHNlIGlmIChwcm9w ZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkucmVwbGFjZW1lbnRfdmFsdWVfcHJvcGVydHkpIHsKPiAr CQkqdmFsID0gc3RhdGUtPmNvbG9ya2V5LnJlcGxhY2VtZW50X3ZhbHVlOwo+ICsJfSBlbHNlIGlm IChwcm9wZXJ0eSA9PSBwbGFuZS0+Y29sb3JrZXkucmVwbGFjZW1lbnRfZm9ybWF0X3Byb3BlcnR5 KSB7Cj4gKwkJKnZhbCA9IHN0YXRlLT5jb2xvcmtleS5yZXBsYWNlbWVudF9mb3JtYXQ7Cj4gIAl9 IGVsc2UgaWYgKHByb3BlcnR5ID09IHBsYW5lLT5jb2xvcl9lbmNvZGluZ19wcm9wZXJ0eSkgewo+ ICAJCSp2YWwgPSBzdGF0ZS0+Y29sb3JfZW5jb2Rpbmc7Cj4gIAl9IGVsc2UgaWYgKHByb3BlcnR5 ID09IHBsYW5lLT5jb2xvcl9yYW5nZV9wcm9wZXJ0eSkgewo+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vZHJtX2JsZW5kLmMgYi9kcml2ZXJzL2dwdS9kcm0vZHJtX2JsZW5kLmMKPiBpbmRl eCBhMTZhNzRkN2UxNWUuLjA1ZTU2MzJjZTM3NSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2dwdS9k cm0vZHJtX2JsZW5kLmMKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vZHJtX2JsZW5kLmMKPiBAQCAt MTA3LDYgKzEwNywxMSBAQAo+ICAgKglwbGFuZXMuIFdpdGhvdXQgdGhpcyBwcm9wZXJ0eSB0aGUg cHJpbWFyeSBwbGFuZSBpcyBhbHdheXMgYmVsb3cgdGhlIGN1cnNvcgo+ICAgKglwbGFuZSwgYW5k IG9yZGVyaW5nIGJldHdlZW4gYWxsIG90aGVyIHBsYW5lcyBpcyB1bmRlZmluZWQuCj4gICAqCj4g KyAqIGNvbG9ya2V5Ogo+ICsgKglDb2xvciBrZXlpbmcgaXMgc2V0IHVwIHdpdGggZHJtX3BsYW5l X2NyZWF0ZV9jb2xvcmtleV9wcm9wZXJ0aWVzKCkuCj4gKyAqCUl0IGFkZHMgc3VwcG9ydCBmb3Ig cmVwbGFjaW5nIGEgcmFuZ2Ugb2YgY29sb3JzIHdpdGggYSB0cmFuc3BhcmVudAo+ICsgKgljb2xv ciBpbiB0aGUgcGxhbmUuCj4gKyAqCj4gICAqIE5vdGUgdGhhdCBhbGwgdGhlIHByb3BlcnR5IGV4 dGVuc2lvbnMgZGVzY3JpYmVkIGhlcmUgYXBwbHkgZWl0aGVyIHRvIHRoZQo+ICAgKiBwbGFuZSBv ciB0aGUgQ1JUQyAoZS5nLiBmb3IgdGhlIGJhY2tncm91bmQgY29sb3IsIHdoaWNoIGN1cnJlbnRs eSBpcyBub3QKPiAgICogZXhwb3NlZCBhbmQgYXNzdW1lZCB0byBiZSBibGFjaykuCj4gQEAgLTQ0 OCwzICs0NTMsMjI3IEBAIGludCBkcm1fYXRvbWljX25vcm1hbGl6ZV96cG9zKHN0cnVjdCBkcm1f ZGV2aWNlICpkZXYsCj4gIAlyZXR1cm4gMDsKPiAgfQo+ICBFWFBPUlRfU1lNQk9MKGRybV9hdG9t aWNfbm9ybWFsaXplX3pwb3MpOwo+ICsKPiArc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBwbGFu ZV9jb2xvcmtleV9tb2RlX25hbWVbXSA9IHsKPiArCVtEUk1fUExBTkVfQ09MT1JLRVlfTU9ERV9E SVNBQkxFRF0gPSAiZGlzYWJsZWQiLAo+ICsJW0RSTV9QTEFORV9DT0xPUktFWV9NT0RFX1NSQ10g PSAic3JjLW1hdGNoLXNyYy1yZXBsYWNlIiwKPiArCVtEUk1fUExBTkVfQ09MT1JLRVlfTU9ERV9E U1RdID0gImRzdC1tYXRjaC1zcmMtcmVwbGFjZSIsCgpUaGlzIGxpc3Qgc2VlbXMgd2F5IG1vcmUg bGltaXRlZCB0aGFuIEkgd2FzIGV4cGVjdGluZywgYXQgbGVhc3Qgd2hlbgpjb21wYXJlZCB0byBh bGwgdGhlIGRpZmZlcmVudCBwcm9wcyB5b3UncmUgcHJvcG9zaW5nIHRvIGFkZC4KCj4gK307Cj4g Kwo+ICsvKioKPiArICogZHJtX3BsYW5lX2NyZWF0ZV9jb2xvcmtleV9wcm9wZXJ0aWVzIC0gY3Jl YXRlIGNvbG9ya2V5IHByb3BlcnRpZXMKPiArICogQHBsYW5lOiBkcm0gcGxhbmUKPiArICogQHN1 cHBvcnRlZF9tb2RlczogYml0bWFzayBvZiBzdXBwb3J0ZWQgY29sb3Iga2V5aW5nIG1vZGVzCj4g KyAqCj4gKyAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyB0aGUgZ2VuZXJpYyBjb2xvciBrZXlpbmcg cHJvcGVydGllcyBhbmQgYXR0YWNoIHRoZW0gdG8KPiArICogdGhlIHBsYW5lIHRvIGVuYWJsZSBj b2xvciBrZXlpbmcgY29udHJvbCBmb3IgYmxlbmRpbmcgb3BlcmF0aW9ucy4KPiArICoKPiArICog Q29sb3Iga2V5aW5nIGlzIGNvbnRyb2xsZWQgdGhyb3VnaCBuaW5lIHByb3BlcnRpZXM6Cj4gKyAq Cj4gKyAqIGNvbG9ya2V5Lm1vZGU6Cj4gKyAqCVRoZSBtb2RlIGlzIGFuIGVudW1lcmF0ZWQgcHJv cGVydHkgdGhhdCBjb250cm9scyBob3cgY29sb3Iga2V5aW5nCj4gKyAqCW9wZXJhdGVzLiBUaGUg ImRpc2FibGVkIiBtb2RlIHRoYXQgZGlzYWJsZXMgY29sb3Iga2V5aW5nIGFuZCBpcwo+ICsgKgl2 ZXJ5IGxpa2VseSB0byBleGlzdCBpZiBjb2xvciBrZXlpbmcgaXMgc3VwcG9ydGVkLCBpdCBzaG91 bGQgYmUgdGhlCj4gKyAqCWRlZmF1bHQgbW9kZS4KPiArICoKPiArICogY29sb3JrZXkubWluLCBj b2xvcmtleS5tYXg6Cj4gKyAqCVRoZXNlIHR3byBwcm9wZXJ0aWVzIHNwZWNpZnkgdGhlIGNvbG9y cyB0aGF0IGFyZSB0cmVhdGVkIGFzIHRoZSBjb2xvcgo+ICsgKglrZXkuIFBpeGVsIHdob3NlIHZh bHVlIGlzIGluIHRoZSBbbWluLCBtYXhdIHJhbmdlIGlzIHRoZSBjb2xvciBrZXkKPiArICoJbWF0 Y2hpbmcgcGl4ZWwuIFRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlcyBhcmUgZXhwcmVzc2Vk IGFzIGEKPiArICoJNjQtYml0IGludGVnZXIgaW4gQVhZWjE2MTYxNjE2IGZvcm1hdCwgd2hlcmUg QSBpcyB0aGUgYWxwaGEgdmFsdWUgYW5kCj4gKyAqCVgsIFkgYW5kIFogY29ycmVzcG9uZCB0byB0 aGUgY29sb3IgY29tcG9uZW50cyBvZiB0aGUgY29sb3JrZXkuZm9ybWF0Lgo+ICsgKglJbiBtb3N0 IGNhc2VzIFhZWiB3aWxsIGJlIGVpdGhlciBSR0Igb3IgWVVWLgo+ICsgKgo+ICsgKglXaGVuIGEg c2luZ2xlIGNvbG9yIGtleSBpcyBkZXNpcmVkIGluc3RlYWQgb2YgYSByYW5nZSwgdXNlcnNwYWNl IHNoYWxsCj4gKyAqCXNldCB0aGUgbWluIGFuZCBtYXggcHJvcGVydGllcyB0byB0aGUgc2FtZSB2 YWx1ZS4KPiArICoKPiArICoJRHJpdmVycyByZXR1cm4gYW4gZXJyb3IgZnJvbSB0aGVpciBwbGFu ZSBhdG9taWMgY2hlY2sgaWYgcmFuZ2UgY2FuJ3QgYmUKPiArICoJaGFuZGxlZC4KPiArICoKPiAr ICogY29sb3JrZXkuZm9ybWF0Ogo+ICsgKglUaGlzIHByb3BlcnR5IHNwZWNpZmllcyB0aGUgcGl4 ZWwgZm9ybWF0IGZvciB0aGUgY29sb3JrZXkubWluIC8gbWF4Cj4gKyAqCXByb3BlcnRpZXMuIFRo ZSBmb3JtYXQgaXMgZ2l2ZW4gaW4gYSBmb3JtIG9mIERSTSBmb3VyY2MgY29kZS4KClVtbS4gV2h5 IHdlIGRvIGV2ZW4gbmVlZCB0aGlzPyBUaGlzIHNlZW1zIGluY29tcGF0aWJsZSB3aXRoIHlvdXIg ZWFybGllcgoibWluL21heCBhcmUgc3BlY2lmaWVkIGluIDE2YnBjIGZvcm1hdCIgc3RhdGVtZW50 LgoKPiArICoKPiArICoJRHJpdmVycyByZXR1cm4gYW4gZXJyb3IgZnJvbSB0aGVpciBwbGFuZSBh dG9taWMgY2hlY2sgaWYgcGl4ZWwgZm9ybWF0Cj4gKyAqCWlzIHVuc3VwcG9ydGVkLgo+ICsgKgo+ ICsgKiBjb2xvcmtleS5tYXNrOgo+ICsgKglUaGlzIHByb3BlcnR5IHNwZWNpZmllcyB0aGUgcGl4 ZWwgY29tcG9uZW50cyBtYXNrLiBVbm1hc2tlZCBwaXhlbAo+ICsgKgljb21wb25lbnRzIGFyZSBu b3QgcGFydGljaXBhdGluZyBpbiB0aGUgbWF0Y2hpbmcuIFRoaXMgbWFzayB2YWx1ZSBpcwo+ICsg KglhcHBsaWVkIHRvIGNvbG9ya2V5Lm1pbiAvIG1heCB2YWx1ZXMuIFRoZSBtYXNrIHZhbHVlIGlz IGdpdmVuIGluIGEKPiArICoJZm9ybSBvZiBEUk0gZm91cmNjIGNvZGUgY29ycmVzcG9uZGluZyB0 byB0aGUgY29sb3JrZXkuZm9ybWF0IHByb3BlcnR5Lgo+ICsgKgo+ICsgKglGb3IgZXhhbXBsZTog dXNlcnNwYWNlIHNoYWxsIHNldCB0aGUgY29sb3JrZXkubWFzayB0byAweDAwMDBmZjAwCj4gKyAq CXRvIG1hdGNoIG9ubHkgdGhlIGdyZWVuIGNvbXBvbmVudCBpZiBjb2xvcmtleS5mb3JtYXQgaXMg c2V0IHRvCj4gKyAqCURSTV9GT1JNQVRfWFJHQjg4ODguCj4gKyAqCj4gKyAqCURyaXZlcnMgcmV0 dXJuIGFuIGVycm9yIGZyb20gdGhlaXIgcGxhbmUgYXRvbWljIGNoZWNrIGlmIG1hc2sgdmFsdWUK PiArICoJY2FuJ3QgYmUgaGFuZGxlZC4KPiArICoKPiArICogY29sb3JrZXkuaW52ZXJ0ZWQtbWF0 Y2g6Cj4gKyAqCVRoaXMgcHJvcGVydHkgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIG1hdGNoaW5nIG1p bi1tYXggcmFuZ2Ugc2hvdWxkCj4gKyAqCWJlIGludmVydGVkLCBpLmUuIHBpeGVscyBvdXRzaWRl IG9mIHRoZSBnaXZlbiBjb2xvciByYW5nZSBiZWNvbWUKPiArICoJdGhlIGNvbG9yIGtleSBtYXRj aC4KPiArICoKPiArICoJRHJpdmVycyByZXR1cm4gYW4gZXJyb3IgZnJvbSB0aGVpciBwbGFuZSBh dG9taWMgY2hlY2sgaWYgaW52ZXJzaW9uCj4gKyAqCW1vZGUgY2FuJ3QgYmUgaGFuZGxlZC4KCkht bS4gSSdtIHRyeWluZyB0byBmaWd1cmUgb3V0IHdoYXQgdGhpcyBtZWFucyBmb3IgdGhlIHNyYyB2 cy4gZHN0CmNvbG9ya2V5IG1vZGVzLiBUaG9zZSBwcmV0dHkgbXVjaCBhbHJlYWR5IGhhdmUgYW4g aW52ZXJ0ZWQgbWVhbmluZyB3aGVuCmNvbXBhcmVkIHRvIGVhY2ggb3RoZXIuIFNvIEkgY2FuJ3Qg ZmlndXJlIG91dCBmcm9tIHRoZXNlIGRvY3Mgd2hldGhlciAKeW91J3JlIHN1cHBvc2VkIHRvIHVz ZSB0aGlzIHdoZW4geW91IHdhbnQgYSBub3JtYWwgZHN0IGNrZXkgb3Igbm9ybWFsCnNyYyBrZXkg c2VtYW50aWNzLgoKPiArICoKPiArICogY29sb3JrZXkucmVwbGFjZW1lbnQtdmFsdWU6Cj4gKyAq CVRoaXMgcHJvcGVydHkgc3BlY2lmaWVzIHRoZSBjb2xvciB2YWx1ZSB0aGF0IHJlcGxhY2VzIHBp eGVscyBtYXRjaGluZwo+ICsgKgl0aGUgY29sb3Iga2V5LiBUaGUgdmFsdWUgaXMgZXhwcmVzc2Vk IGluIEFYWVoxNjE2MTYxNiBmb3JtYXQsIHdoZXJlIEEKPiArICoJaXMgdGhlIGFscGhhIHZhbHVl IGFuZCBYLCBZIGFuZCBaIGNvcnJlc3BvbmQgdG8gdGhlIGNvbG9yIGNvbXBvbmVudHMKPiArICoJ b2YgdGhlIGNvbG9ya2V5LnJlcGxhY2VtZW50LWZvcm1hdC4KPiArICoKPiArICoJRHJpdmVycyBy ZXR1cm4gYW4gZXJyb3IgZnJvbSB0aGVpciBwbGFuZSBhdG9taWMgY2hlY2sgaWYgcmVwbGFjZW1l bnQKPiArICoJdmFsdWUgY2FuJ3QgYmUgaGFuZGxlZC4KPiArICoKPiArICogY29sb3JrZXkucmVw bGFjZW1lbnQtZm9ybWF0Ogo+ICsgKglUaGlzIHByb3BlcnR5IHNwZWNpZmllcyB0aGUgcGl4ZWwg Zm9ybWF0IGZvciB0aGUKPiArICoJY29sb3JrZXkucmVwbGFjZW1lbnQtdmFsdWUgcHJvcGVydHku IFRoZSBmb3JtYXQgaXMgZ2l2ZW4gaW4gYSBmb3JtIG9mCj4gKyAqCURSTSBmb3VyY2MgY29kZS4K CkFnYWluIHRoaXMgc2VlbXMgYXQgb2RkcyB3aXRoIHRoZSAxNmJwYyByZXBsYWNlbWVudC12YWx1 ZS4KCj4gKyAqCj4gKyAqCURyaXZlcnMgcmV0dXJuIGFuIGVycm9yIGZyb20gdGhlaXIgcGxhbmUg YXRvbWljIGNoZWNrIGlmIHJlcGxhY2VtZW50Cj4gKyAqCXBpeGVsIGZvcm1hdCBpcyB1bnN1cHBv cnRlZC4KPiArICoKPiArICogY29sb3JrZXkucmVwbGFjZW1lbnQtbWFzazoKPiArICoJVGhpcyBw cm9wZXJ0eSBzcGVjaWZpZXMgdGhlIHBpeGVsIGNvbXBvbmVudHMgbWFzayB0aGF0IGRlZmluZXMK PiArICoJd2hhdCBjb21wb25lbnRzIG9mIHRoZSBjb2xvcmtleS5yZXBsYWNlbWVudC12YWx1ZSB3 aWxsIHBhcnRpY2lwYXRlIGluCj4gKyAqCXJlcGxhY2VtZW50IG9mIHRoZSBwaXhlbHMgY29sb3Iu IFVubWFza2VkIHBpeGVsIGNvbXBvbmVudHMgYXJlIG5vdAo+ICsgKglwYXJ0aWNpcGF0aW5nIGlu IHRoZSByZXBsYWNlbWVudC4KCkRvZXMgdGhhdCBtZWFuIHRoYXQgdGhlIGRhdGEgZm9yIHRoZSB1 bm1hc2tlZCBiaXRzIHdpbGwgYmUgY29taW5nCmZyb20gdGhlIHNvdXJjZT8KCj4gVGhlIG1hc2sg dmFsdWUgaXMgZ2l2ZW4gaW4gYSBmb3JtIG9mCj4gKyAqCURSTSBmb3VyY2MgY29kZSBjb3JyZXNw b25kaW5nIHRvIHRoZSBjb2xvcmtleS5yZXBsYWNlbWVudC1mb3JtYXQKPiArICoJcHJvcGVydHku Cj4gKyAqCj4gKyAqCUZvciBleGFtcGxlOiB1c2Vyc3BhY2Ugc2hhbGwgc2V0IHRoZSBjb2xvcmtl eS5yZXBsYWNlbWVudC1tYXNrIHRvCj4gKyAqCTB4MDAwMGZmMDAgdG8gcmVwbGFjZSBvbmx5IHRo ZSBncmVlbiBjb21wb25lbnQgaWYKPiArICoJY29sb3JrZXkucmVwbGFjZW1lbnQtZm9ybWF0IGlz IHNldCB0byBEUk1fRk9STUFUX1hSR0I4ODg4Lgo+ICsgKgo+ICsgKglVc2Vyc3BhY2Ugc2hhbGwg c2V0IGNvbG9ya2V5LnJlcGxhY2VtZW50LW1hc2sgdG8gMCB0byBkaXNhYmxlIHRoZSBjb2xvcgo+ ICsgKglyZXBsYWNlbWVudC4gSW4gdGhpcyBjYXNlIG1hdGNoaW5nIHBpeGVscyBiZWNvbWUgdHJh bnNwYXJlbnQuCj4gKyAqCj4gKyAqCURyaXZlcnMgcmV0dXJuIGFuIGVycm9yIGZyb20gdGhlaXIg cGxhbmUgYXRvbWljIGNoZWNrIGlmIHJlcGxhY2VtZW50Cj4gKyAqCW1hc2sgdmFsdWUgY2FuJ3Qg YmUgaGFuZGxlZC4KPiArICoKPiArICogUmV0dXJuczoKPiArICogWmVybyBvbiBzdWNjZXNzLCBu ZWdhdGl2ZSBlcnJubyBvbiBmYWlsdXJlLgo+ICsgKi8KPiAraW50IGRybV9wbGFuZV9jcmVhdGVf Y29sb3JrZXlfcHJvcGVydGllcyhzdHJ1Y3QgZHJtX3BsYW5lICpwbGFuZSwKPiArCQkJCQkgdTMy IHN1cHBvcnRlZF9tb2RlcykKPiArewo+ICsJc3RydWN0IGRybV9wcm9wX2VudW1fbGlzdCBtb2Rl c19saXN0W0RSTV9QTEFORV9DT0xPUktFWV9NT0RFU19OVU1dOwo+ICsJc3RydWN0IGRybV9wcm9w ZXJ0eSAqcmVwbGFjZW1lbnRfZm9ybWF0X3Byb3A7Cj4gKwlzdHJ1Y3QgZHJtX3Byb3BlcnR5ICpy ZXBsYWNlbWVudF92YWx1ZV9wcm9wOwo+ICsJc3RydWN0IGRybV9wcm9wZXJ0eSAqcmVwbGFjZW1l bnRfbWFza19wcm9wOwo+ICsJc3RydWN0IGRybV9wcm9wZXJ0eSAqaW52ZXJ0ZWRfbWF0Y2hfcHJv cDsKPiArCXN0cnVjdCBkcm1fcHJvcGVydHkgKmZvcm1hdF9wcm9wOwo+ICsJc3RydWN0IGRybV9w cm9wZXJ0eSAqbWFza19wcm9wOwo+ICsJc3RydWN0IGRybV9wcm9wZXJ0eSAqbW9kZV9wcm9wOwo+ ICsJc3RydWN0IGRybV9wcm9wZXJ0eSAqbWluX3Byb3A7Cj4gKwlzdHJ1Y3QgZHJtX3Byb3BlcnR5 ICptYXhfcHJvcDsKPiArCXVuc2lnbmVkIGludCBtb2Rlc19udW0gPSAwOwo+ICsJdW5zaWduZWQg aW50IGk7Cj4gKwo+ICsJLyogYXQgbGVhc3QgdHdvIG1vZGVzIHNob3VsZCBiZSBzdXBwb3J0ZWQg Ki8KPiArCWlmICghc3VwcG9ydGVkX21vZGVzKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiAr CS8qIG1vZGVzIGFyZSBkcml2ZXItc3BlY2lmaWMsIGJ1aWxkIHRoZSBsaXN0IG9mIHN1cHBvcnRl ZCBtb2RlcyAqLwo+ICsJZm9yIChpID0gMDsgaSA8IERSTV9QTEFORV9DT0xPUktFWV9NT0RFU19O VU07IGkrKykgewo+ICsJCWlmICghKHN1cHBvcnRlZF9tb2RlcyAmIEJJVChpKSkpCj4gKwkJCWNv bnRpbnVlOwo+ICsKPiArCQltb2Rlc19saXN0W21vZGVzX251bV0ubmFtZSA9IHBsYW5lX2NvbG9y a2V5X21vZGVfbmFtZVtpXTsKPiArCQltb2Rlc19saXN0W21vZGVzX251bV0udHlwZSA9IGk7Cj4g KwkJbW9kZXNfbnVtKys7Cj4gKwl9Cj4gKwo+ICsJbW9kZV9wcm9wID0gZHJtX3Byb3BlcnR5X2Ny ZWF0ZV9lbnVtKHBsYW5lLT5kZXYsIDAsICJjb2xvcmtleS5tb2RlIiwKPiArCQkJCQkgICAgIG1v ZGVzX2xpc3QsIG1vZGVzX251bSk7Cj4gKwlpZiAoIW1vZGVfcHJvcCkKPiArCQlyZXR1cm4gLUVO T01FTTsKPiArCj4gKwltYXNrX3Byb3AgPSBkcm1fcHJvcGVydHlfY3JlYXRlX3JhbmdlKHBsYW5l LT5kZXYsIDAsICJjb2xvcmtleS5tYXNrIiwKPiArCQkJCQkgICAgICAwLCBVNjRfTUFYKTsKPiAr CWlmICghbWFza19wcm9wKQo+ICsJCWdvdG8gZXJyX2Rlc3Ryb3lfbW9kZV9wcm9wOwo+ICsKPiAr CW1pbl9wcm9wID0gZHJtX3Byb3BlcnR5X2NyZWF0ZV9yYW5nZShwbGFuZS0+ZGV2LCAwLCAiY29s b3JrZXkubWluIiwKPiArCQkJCQkgICAgIDAsIFU2NF9NQVgpOwo+ICsJaWYgKCFtaW5fcHJvcCkK PiArCQlnb3RvIGVycl9kZXN0cm95X21hc2tfcHJvcDsKPiArCj4gKwltYXhfcHJvcCA9IGRybV9w cm9wZXJ0eV9jcmVhdGVfcmFuZ2UocGxhbmUtPmRldiwgMCwgImNvbG9ya2V5Lm1heCIsCj4gKwkJ CQkJICAgICAwLCBVNjRfTUFYKTsKPiArCWlmICghbWF4X3Byb3ApCj4gKwkJZ290byBlcnJfZGVz dHJveV9taW5fcHJvcDsKPiArCj4gKwlmb3JtYXRfcHJvcCA9IGRybV9wcm9wZXJ0eV9jcmVhdGVf cmFuZ2UocGxhbmUtPmRldiwgMCwKPiArCQkJCQkiY29sb3JrZXkuZm9ybWF0IiwKPiArCQkJCQkw LCBVMzJfTUFYKTsKPiArCWlmICghZm9ybWF0X3Byb3ApCj4gKwkJZ290byBlcnJfZGVzdHJveV9t YXhfcHJvcDsKPiArCj4gKwlpbnZlcnRlZF9tYXRjaF9wcm9wID0gZHJtX3Byb3BlcnR5X2NyZWF0 ZV9ib29sKHBsYW5lLT5kZXYsIDAsCj4gKwkJCQkJImNvbG9ya2V5LmludmVydGVkLW1hdGNoIik7 Cj4gKwlpZiAoIWludmVydGVkX21hdGNoX3Byb3ApCj4gKwkJZ290byBlcnJfZGVzdHJveV9mb3Jt YXRfcHJvcDsKPiArCj4gKwlyZXBsYWNlbWVudF9tYXNrX3Byb3AgPSBkcm1fcHJvcGVydHlfY3Jl YXRlX3JhbmdlKHBsYW5lLT5kZXYsIDAsCj4gKwkJCQkJImNvbG9ya2V5LnJlcGxhY2VtZW50LW1h c2siLAo+ICsJCQkJCTAsIFU2NF9NQVgpOwo+ICsJaWYgKCFyZXBsYWNlbWVudF9tYXNrX3Byb3Ap Cj4gKwkJZ290byBlcnJfZGVzdHJveV9pbnZlcnRlZF9tYXRjaF9wcm9wOwo+ICsKPiArCXJlcGxh Y2VtZW50X3ZhbHVlX3Byb3AgPSBkcm1fcHJvcGVydHlfY3JlYXRlX3JhbmdlKHBsYW5lLT5kZXYs IDAsCj4gKwkJCQkJImNvbG9ya2V5LnJlcGxhY2VtZW50LXZhbHVlIiwKPiArCQkJCQkwLCBVNjRf TUFYKTsKPiArCWlmICghcmVwbGFjZW1lbnRfdmFsdWVfcHJvcCkKPiArCQlnb3RvIGVycl9kZXN0 cm95X3JlcGxhY2VtZW50X21hc2tfcHJvcDsKPiArCj4gKwlyZXBsYWNlbWVudF9mb3JtYXRfcHJv cCA9IGRybV9wcm9wZXJ0eV9jcmVhdGVfcmFuZ2UocGxhbmUtPmRldiwgMCwKPiArCQkJCQkiY29s b3JrZXkucmVwbGFjZW1lbnQtZm9ybWF0IiwKPiArCQkJCQkwLCBVNjRfTUFYKTsKPiArCWlmICgh cmVwbGFjZW1lbnRfZm9ybWF0X3Byb3ApCj4gKwkJZ290byBlcnJfZGVzdHJveV9yZXBsYWNlbWVu dF92YWx1ZV9wcm9wOwoKSSBkb24ndCB0aGluayB3ZSB3YW50IHRvIGFkZCBhbGwgdGhlc2UgcHJv cHMgZm9yIGV2ZXJ5IGRyaXZlci9oYXJkd2FyZS4KSU1PIHRoZSBzZXQgb2YgcHJvcHMgd2UgZXhw b3NlIHNob3VsZCBkZXBlbmQgb24gdGhlIHN1cHBvcnRlZCBzZXQgb2YKY29sb3JrZXlpbmcgbW9k ZXMuCgo+ICsKPiArCWRybV9vYmplY3RfYXR0YWNoX3Byb3BlcnR5KCZwbGFuZS0+YmFzZSwgbWlu X3Byb3AsIDApOwo+ICsJZHJtX29iamVjdF9hdHRhY2hfcHJvcGVydHkoJnBsYW5lLT5iYXNlLCBt YXhfcHJvcCwgMCk7Cj4gKwlkcm1fb2JqZWN0X2F0dGFjaF9wcm9wZXJ0eSgmcGxhbmUtPmJhc2Us IG1vZGVfcHJvcCwgMCk7Cj4gKwlkcm1fb2JqZWN0X2F0dGFjaF9wcm9wZXJ0eSgmcGxhbmUtPmJh c2UsIG1hc2tfcHJvcCwgMCk7Cj4gKwlkcm1fb2JqZWN0X2F0dGFjaF9wcm9wZXJ0eSgmcGxhbmUt PmJhc2UsIGZvcm1hdF9wcm9wLCAwKTsKPiArCWRybV9vYmplY3RfYXR0YWNoX3Byb3BlcnR5KCZw bGFuZS0+YmFzZSwgaW52ZXJ0ZWRfbWF0Y2hfcHJvcCwgMCk7Cj4gKwlkcm1fb2JqZWN0X2F0dGFj aF9wcm9wZXJ0eSgmcGxhbmUtPmJhc2UsIHJlcGxhY2VtZW50X21hc2tfcHJvcCwgMCk7Cj4gKwlk cm1fb2JqZWN0X2F0dGFjaF9wcm9wZXJ0eSgmcGxhbmUtPmJhc2UsIHJlcGxhY2VtZW50X3ZhbHVl X3Byb3AsIDApOwo+ICsJZHJtX29iamVjdF9hdHRhY2hfcHJvcGVydHkoJnBsYW5lLT5iYXNlLCBy ZXBsYWNlbWVudF9mb3JtYXRfcHJvcCwgMCk7Cj4gKwo+ICsJcGxhbmUtPmNvbG9ya2V5Lm1pbl9w cm9wZXJ0eSA9IG1pbl9wcm9wOwo+ICsJcGxhbmUtPmNvbG9ya2V5Lm1heF9wcm9wZXJ0eSA9IG1h eF9wcm9wOwo+ICsJcGxhbmUtPmNvbG9ya2V5Lm1vZGVfcHJvcGVydHkgPSBtb2RlX3Byb3A7Cj4g KwlwbGFuZS0+Y29sb3JrZXkubWFza19wcm9wZXJ0eSA9IG1hc2tfcHJvcDsKPiArCXBsYW5lLT5j b2xvcmtleS5mb3JtYXRfcHJvcGVydHkgPSBmb3JtYXRfcHJvcDsKPiArCXBsYW5lLT5jb2xvcmtl eS5pbnZlcnRlZF9tYXRjaF9wcm9wZXJ0eSA9IGludmVydGVkX21hdGNoX3Byb3A7Cj4gKwlwbGFu ZS0+Y29sb3JrZXkucmVwbGFjZW1lbnRfbWFza19wcm9wZXJ0eSA9IHJlcGxhY2VtZW50X21hc2tf cHJvcDsKPiArCXBsYW5lLT5jb2xvcmtleS5yZXBsYWNlbWVudF92YWx1ZV9wcm9wZXJ0eSA9IHJl cGxhY2VtZW50X3ZhbHVlX3Byb3A7Cj4gKwlwbGFuZS0+Y29sb3JrZXkucmVwbGFjZW1lbnRfZm9y bWF0X3Byb3BlcnR5ID0gcmVwbGFjZW1lbnRfZm9ybWF0X3Byb3A7Cj4gKwo+ICsJcmV0dXJuIDA7 Cj4gKwo+ICtlcnJfZGVzdHJveV9yZXBsYWNlbWVudF92YWx1ZV9wcm9wOgo+ICsJZHJtX3Byb3Bl cnR5X2Rlc3Ryb3kocGxhbmUtPmRldiwgcmVwbGFjZW1lbnRfdmFsdWVfcHJvcCk7Cj4gK2Vycl9k ZXN0cm95X3JlcGxhY2VtZW50X21hc2tfcHJvcDoKPiArCWRybV9wcm9wZXJ0eV9kZXN0cm95KHBs YW5lLT5kZXYsIHJlcGxhY2VtZW50X21hc2tfcHJvcCk7Cj4gK2Vycl9kZXN0cm95X2ludmVydGVk X21hdGNoX3Byb3A6Cj4gKwlkcm1fcHJvcGVydHlfZGVzdHJveShwbGFuZS0+ZGV2LCBpbnZlcnRl ZF9tYXRjaF9wcm9wKTsKPiArZXJyX2Rlc3Ryb3lfZm9ybWF0X3Byb3A6Cj4gKwlkcm1fcHJvcGVy dHlfZGVzdHJveShwbGFuZS0+ZGV2LCBmb3JtYXRfcHJvcCk7Cj4gK2Vycl9kZXN0cm95X21heF9w cm9wOgo+ICsJZHJtX3Byb3BlcnR5X2Rlc3Ryb3kocGxhbmUtPmRldiwgbWF4X3Byb3ApOwo+ICtl cnJfZGVzdHJveV9taW5fcHJvcDoKPiArCWRybV9wcm9wZXJ0eV9kZXN0cm95KHBsYW5lLT5kZXYs IG1pbl9wcm9wKTsKPiArZXJyX2Rlc3Ryb3lfbWFza19wcm9wOgo+ICsJZHJtX3Byb3BlcnR5X2Rl c3Ryb3kocGxhbmUtPmRldiwgbWFza19wcm9wKTsKPiArZXJyX2Rlc3Ryb3lfbW9kZV9wcm9wOgo+ ICsJZHJtX3Byb3BlcnR5X2Rlc3Ryb3kocGxhbmUtPmRldiwgbW9kZV9wcm9wKTsKPiArCj4gKwly ZXR1cm4gLUVOT01FTTsKPiArfQo+ICtFWFBPUlRfU1lNQk9MKGRybV9wbGFuZV9jcmVhdGVfY29s b3JrZXlfcHJvcGVydGllcyk7Cj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvZHJtL2RybV9ibGVuZC5o IGIvaW5jbHVkZS9kcm0vZHJtX2JsZW5kLmgKPiBpbmRleCAzMzBjNTYxYzRjMTEuLjhlODBkMzNi NjQzZSAxMDA2NDQKPiAtLS0gYS9pbmNsdWRlL2RybS9kcm1fYmxlbmQuaAo+ICsrKyBiL2luY2x1 ZGUvZHJtL2RybV9ibGVuZC5oCj4gQEAgLTUyLDQgKzUyLDcgQEAgaW50IGRybV9wbGFuZV9jcmVh dGVfenBvc19pbW11dGFibGVfcHJvcGVydHkoc3RydWN0IGRybV9wbGFuZSAqcGxhbmUsCj4gIAkJ CQkJICAgICB1bnNpZ25lZCBpbnQgenBvcyk7Cj4gIGludCBkcm1fYXRvbWljX25vcm1hbGl6ZV96 cG9zKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCj4gIAkJCSAgICAgIHN0cnVjdCBkcm1fYXRvbWlj X3N0YXRlICpzdGF0ZSk7Cj4gKwo+ICtpbnQgZHJtX3BsYW5lX2NyZWF0ZV9jb2xvcmtleV9wcm9w ZXJ0aWVzKHN0cnVjdCBkcm1fcGxhbmUgKnBsYW5lLAo+ICsJCQkJCSB1MzIgc3VwcG9ydGVkX21v ZGVzKTsKPiAgI2VuZGlmCj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvZHJtL2RybV9wbGFuZS5oIGIv aW5jbHVkZS9kcm0vZHJtX3BsYW5lLmgKPiBpbmRleCAyNmZhNTBjMmE1MGUuLmZmN2Y1ZWJlMmI3 OSAxMDA2NDQKPiAtLS0gYS9pbmNsdWRlL2RybS9kcm1fcGxhbmUuaAo+ICsrKyBiL2luY2x1ZGUv ZHJtL2RybV9wbGFuZS5oCj4gQEAgLTMyLDYgKzMyLDQyIEBAIHN0cnVjdCBkcm1fY3J0YzsKPiAg c3RydWN0IGRybV9wcmludGVyOwo+ICBzdHJ1Y3QgZHJtX21vZGVzZXRfYWNxdWlyZV9jdHg7Cj4g IAo+ICsvKioKPiArICogZW51bSBkcm1fcGxhbmVfY29sb3JrZXlfbW9kZSAtIHVhcGkgcGxhbmUg Y29sb3JrZXkgbW9kZSBlbnVtZXJhdGlvbgo+ICsgKi8KPiArZW51bSBkcm1fcGxhbmVfY29sb3Jr ZXlfbW9kZSB7Cj4gKwkvKioKPiArCSAqIEBEUk1fUExBTkVfQ09MT1JLRVlfTU9ERV9ESVNBQkxF RDoKPiArCSAqCj4gKwkgKiBObyBjb2xvciBtYXRjaGluZyBwZXJmb3JtZWQgaW4gdGhpcyBtb2Rl LiBUaGlzIGlzIHRoZSBkZWZhdWx0Cj4gKwkgKiBjb21tb24gbW9kZS4KPiArCSAqLwo+ICsJRFJN X1BMQU5FX0NPTE9SS0VZX01PREVfRElTQUJMRUQsCj4gKwo+ICsJLyoqCj4gKwkgKiBARFJNX1BM QU5FX0NPTE9SS0VZX01PREVfU1JDOgo+ICsJICoKPiArCSAqIEluIHRoaXMgbW9kZSBjb2xvciBt YXRjaGluZyBpcyBwZXJmb3JtZWQgd2l0aCB0aGUgcGl4ZWxzIG9mCj4gKwkgKiB0aGUgZ2l2ZW4g cGxhbmUgYW5kIHRoZSBtYXRjaGVkIHBpeGVscyBhcmUgZnVsbHkgKG9yIHBhcnRpYWxseSkKPiAr CSAqIHJlcGxhY2VkIHdpdGggdGhlIHJlcGxhY2VtZW50IGNvbG9yIG9yIGJlY29tZSBjb21wbGV0 ZWx5Cj4gKwkgKiB0cmFuc3BhcmVudC4KPiArCSAqLwo+ICsJRFJNX1BMQU5FX0NPTE9SS0VZX01P REVfU1JDLAo+ICsKPiArCS8qKgo+ICsJICogQERSTV9QTEFORV9DT0xPUktFWV9NT0RFX0RTVDoK PiArCSAqCj4gKwkgKiBJbiB0aGlzIG1vZGUgY29sb3IgbWF0Y2hpbmcgaXMgcGVyZm9ybWVkIHdp dGggdGhlIHBpeGVscyBvZiB0aGUKPiArCSAqIHBsYW5lcyB6LXBvc2l0aW9uZWQgdW5kZXIgdGhl IGdpdmVuIHBsYW5lIGFuZCB0aGUgcGl4ZWxzIG9mIHRoZQo+ICsJICogaG92ZXJpbmcgcGxhbmUg dGhhdCBhcmUgeHktcG9zaXRpb25lZCBhcyB0aGUgdW5kZXJseWluZwo+ICsJICogY29sb3ItbWF0 Y2hlZCBwaXhlbHMgYXJlIGZ1bGx5IChvciBwYXJ0aWFsbHkpIHJlcGxhY2VkIHdpdGggdGhlCj4g KwkgKiByZXBsYWNlbWVudCBjb2xvciBvciBiZWNvbWUgY29tcGxldGVseSB0cmFuc3BhcmVudC4K PiArCSAqLwo+ICsJRFJNX1BMQU5FX0NPTE9SS0VZX01PREVfRFNULAo+ICsKPiArCURSTV9QTEFO RV9DT0xPUktFWV9NT0RFU19OVU0sCj4gK307Cj4gKwo+ICAvKioKPiAgICogc3RydWN0IGRybV9w bGFuZV9zdGF0ZSAtIG11dGFibGUgcGxhbmUgc3RhdGUKPiAgICogQHBsYW5lOiBiYWNrcG9pbnRl ciB0byB0aGUgcGxhbmUKPiBAQCAtNTQsNiArOTAsMjEgQEAgc3RydWN0IGRybV9tb2Rlc2V0X2Fj cXVpcmVfY3R4Owo+ICAgKgl3aGVyZSBOIGlzIHRoZSBudW1iZXIgb2YgYWN0aXZlIHBsYW5lcyBm b3IgZ2l2ZW4gY3J0Yy4gTm90ZSB0aGF0Cj4gICAqCXRoZSBkcml2ZXIgbXVzdCBzZXQgZHJtX21v ZGVfY29uZmlnLm5vcm1hbGl6ZV96cG9zIG9yIGNhbGwKPiAgICoJZHJtX2F0b21pY19ub3JtYWxp emVfenBvcygpIHRvIHVwZGF0ZSB0aGlzIGJlZm9yZSBpdCBjYW4gYmUgdHJ1c3RlZC4KPiArICog QGNvbG9ya2V5Lm1vZGU6IGNvbG9yIGtleSBtb2RlCj4gKyAqIEBjb2xvcmtleS5taW46IGNvbG9y IGtleSByYW5nZSBtaW5pbXVtLiBUaGUgdmFsdWUgaXMgc3RvcmVkIGluIEFYWVoxNjE2MTYxNgo+ ICsgKglmb3JtYXQsIHdoZXJlIEEgaXMgdGhlIGFscGhhIHZhbHVlIGFuZCBYLCBZIGFuZCBaIGNv cnJlc3BvbmQgdG8gdGhlCj4gKyAqCWNvbG9yIGNvbXBvbmVudHMgb2YgdGhlIHBsYW5lJ3MgcGl4 ZWwgZm9ybWF0ICh1c3VhbGx5IFJHQiBvciBZVVYpCj4gKyAqIEBjb2xvcmtleS5tYXg6IGNvbG9y IGtleSByYW5nZSBtYXhpbXVtIChpbiBBWFlaMTYxNjE2MTYgZm9ybWF0KQo+ICsgKiBAY29sb3Jr ZXkubWFzazogY29sb3Iga2V5IG1hc2sgdmFsdWUgKGluIEFYWVoxNjE2MTYxNiBmb3JtYXQpCj4g KyAqIEBjb2xvcmtleS5mb3JtYXQ6IGNvbG9yIGtleSBtaW4vbWF4L21hc2sgdmFsdWVzIHBpeGVs IGZvcm1hdCAoaW4KPiArICogCURSTV9GT1JNQVRfQVhZWjE2MTYxNjE2IGZvcm0pCj4gKyAqIEBj b2xvcmtleS5pbnZlcnRlZF9tYXRjaDogY29sb3Iga2V5IG1pbi1tYXggbWF0Y2hpbmcgcmFuZ2Ug aXMgaW52ZXJ0ZWQKPiArICogQGNvbG9ya2V5LnJlcGxhY2VtZW50X21hc2s6IGNvbG9yIGtleSBy ZXBsYWNlbWVudCBtYXNrIHZhbHVlIChpbgo+ICsgKiAJQVhZWjE2MTYxNjE2IGZvcm1hdCkKPiAr ICogQGNvbG9ya2V5LnJlcGxhY2VtZW50X3ZhbHVlOiBjb2xvciBrZXkgcmVwbGFjZW1lbnQgdmFs dWUgKGluCj4gKyAqIAlBWFlaMTYxNjE2MTYgZm9ybWF0KQo+ICsgKiBAY29sb3JrZXkucmVwbGFj ZW1lbnRfZm9ybWF0OiBjb2xvciBrZXkgcmVwbGFjZW1lbnQgdmFsdWUgLyBtYXNrCj4gKyAqCXBp eGVsIGZvcm1hdCAoaW4gRFJNX0ZPUk1BVF9BWFlaMTYxNjE2MTYgZm9ybSkKPiAgICogQHNyYzog Y2xpcHBlZCBzb3VyY2UgY29vcmRpbmF0ZXMgb2YgdGhlIHBsYW5lIChpbiAxNi4xNikKPiAgICog QGRzdDogY2xpcHBlZCBkZXN0aW5hdGlvbiBjb29yZGluYXRlcyBvZiB0aGUgcGxhbmUKPiAgICog QHN0YXRlOiBiYWNrcG9pbnRlciB0byBnbG9iYWwgZHJtX2F0b21pY19zdGF0ZQo+IEBAIC0xMjQs NiArMTc1LDE5IEBAIHN0cnVjdCBkcm1fcGxhbmVfc3RhdGUgewo+ICAJdW5zaWduZWQgaW50IHpw b3M7Cj4gIAl1bnNpZ25lZCBpbnQgbm9ybWFsaXplZF96cG9zOwo+ICAKPiArCS8qIFBsYW5lIGNv bG9ya2V5ICovCj4gKwlzdHJ1Y3Qgewo+ICsJCWVudW0gZHJtX3BsYW5lX2NvbG9ya2V5X21vZGUg bW9kZTsKPiArCQl1NjQgbWluOwo+ICsJCXU2NCBtYXg7Cj4gKwkJdTY0IG1hc2s7Cj4gKwkJdTMy IGZvcm1hdDsKPiArCQlib29sIGludmVydGVkX21hdGNoOwo+ICsJCXU2NCByZXBsYWNlbWVudF9t YXNrOwo+ICsJCXU2NCByZXBsYWNlbWVudF92YWx1ZTsKPiArCQl1MzIgcmVwbGFjZW1lbnRfZm9y bWF0Owo+ICsJfSBjb2xvcmtleTsKPiArCj4gIAkvKioKPiAgCSAqIEBjb2xvcl9lbmNvZGluZzoK PiAgCSAqCj4gQEAgLTUxMCw2ICs1NzQsNyBAQCBlbnVtIGRybV9wbGFuZV90eXBlIHsKPiAgICog QGFscGhhX3Byb3BlcnR5OiBhbHBoYSBwcm9wZXJ0eSBmb3IgdGhpcyBwbGFuZQo+ICAgKiBAenBv c19wcm9wZXJ0eTogenBvcyBwcm9wZXJ0eSBmb3IgdGhpcyBwbGFuZQo+ICAgKiBAcm90YXRpb25f cHJvcGVydHk6IHJvdGF0aW9uIHByb3BlcnR5IGZvciB0aGlzIHBsYW5lCj4gKyAqIEBjb2xvcmtl eTogY29sb3JrZXkgcHJvcGVydGllcyBmb3IgdGhpcyBwbGFuZQo+ICAgKiBAaGVscGVyX3ByaXZh dGU6IG1pZC1sYXllciBwcml2YXRlIGRhdGEKPiAgICovCj4gIHN0cnVjdCBkcm1fcGxhbmUgewo+ IEBAIC01ODcsNiArNjUyLDE4IEBAIHN0cnVjdCBkcm1fcGxhbmUgewo+ICAJc3RydWN0IGRybV9w cm9wZXJ0eSAqenBvc19wcm9wZXJ0eTsKPiAgCXN0cnVjdCBkcm1fcHJvcGVydHkgKnJvdGF0aW9u X3Byb3BlcnR5Owo+ICAKPiArCXN0cnVjdCB7Cj4gKwkJc3RydWN0IGRybV9wcm9wZXJ0eSAqbWlu X3Byb3BlcnR5Owo+ICsJCXN0cnVjdCBkcm1fcHJvcGVydHkgKm1heF9wcm9wZXJ0eTsKPiArCQlz dHJ1Y3QgZHJtX3Byb3BlcnR5ICptb2RlX3Byb3BlcnR5Owo+ICsJCXN0cnVjdCBkcm1fcHJvcGVy dHkgKm1hc2tfcHJvcGVydHk7Cj4gKwkJc3RydWN0IGRybV9wcm9wZXJ0eSAqZm9ybWF0X3Byb3Bl cnR5Owo+ICsJCXN0cnVjdCBkcm1fcHJvcGVydHkgKmludmVydGVkX21hdGNoX3Byb3BlcnR5Owo+ ICsJCXN0cnVjdCBkcm1fcHJvcGVydHkgKnJlcGxhY2VtZW50X21hc2tfcHJvcGVydHk7Cj4gKwkJ c3RydWN0IGRybV9wcm9wZXJ0eSAqcmVwbGFjZW1lbnRfdmFsdWVfcHJvcGVydHk7Cj4gKwkJc3Ry dWN0IGRybV9wcm9wZXJ0eSAqcmVwbGFjZW1lbnRfZm9ybWF0X3Byb3BlcnR5Owo+ICsJfSBjb2xv cmtleTsKPiArCj4gIAkvKioKPiAgCSAqIEBjb2xvcl9lbmNvZGluZ19wcm9wZXJ0eToKPiAgCSAq Cj4gLS0gCj4gMi4xNy4wCgotLSAKVmlsbGUgU3lyasOkbMOkCkludGVsCl9fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QK ZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9w Lm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mga04.intel.com ([192.55.52.120]:32164 "EHLO mga04.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1165183AbeE1NPI (ORCPT ); Mon, 28 May 2018 09:15:08 -0400 Date: Mon, 28 May 2018 16:15:01 +0300 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= To: Dmitry Osipenko Cc: Laurent Pinchart , Thierry Reding , Neil Armstrong , Maxime Ripard , dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Alexandru Gheorghe , Russell King , Ben Skeggs , Sinclair Yeh , Thomas Hellstrom , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH v2 1/2] drm: Add generic colorkey properties Message-ID: <20180528131501.GK23723@intel.com> References: <20180526155623.12610-1-digetx@gmail.com> <20180526155623.12610-2-digetx@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20180526155623.12610-2-digetx@gmail.com> Sender: linux-media-owner@vger.kernel.org List-ID: On Sat, May 26, 2018 at 06:56:22PM +0300, Dmitry Osipenko 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 adjustment > of the pixels component values. > > 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 nine generic DRM plane > properties related to the color keying to cover various HW capabilities. > > This patch is based on the initial work done by Laurent Pinchart, most of > credits for this patch goes to him. > > Signed-off-by: Dmitry Osipenko > --- > drivers/gpu/drm/drm_atomic.c | 36 ++++++ > drivers/gpu/drm/drm_blend.c | 229 +++++++++++++++++++++++++++++++++++ > include/drm/drm_blend.h | 3 + > include/drm/drm_plane.h | 77 ++++++++++++ > 4 files changed, 345 insertions(+) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index 895741e9cd7d..5b808cb68654 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -799,6 +799,24 @@ 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.format_property) { > + state->colorkey.format = val; > + } else if (property == plane->colorkey.mask_property) { > + state->colorkey.mask = val; > + } else if (property == plane->colorkey.inverted_match_property) { > + state->colorkey.inverted_match = val; > + } else if (property == plane->colorkey.replacement_mask_property) { > + state->colorkey.replacement_mask = val; > + } else if (property == plane->colorkey.replacement_value_property) { > + state->colorkey.replacement_value = val; > + } else if (property == plane->colorkey.replacement_format_property) { > + state->colorkey.replacement_format = val; > } else if (property == plane->color_encoding_property) { > state->color_encoding = val; > } else if (property == plane->color_range_property) { > @@ -864,6 +882,24 @@ 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.format_property) { > + *val = state->colorkey.format; > + } else if (property == plane->colorkey.mask_property) { > + *val = state->colorkey.mask; > + } else if (property == plane->colorkey.inverted_match_property) { > + *val = state->colorkey.inverted_match; > + } else if (property == plane->colorkey.replacement_mask_property) { > + *val = state->colorkey.replacement_mask; > + } else if (property == plane->colorkey.replacement_value_property) { > + *val = state->colorkey.replacement_value; > + } else if (property == plane->colorkey.replacement_format_property) { > + *val = state->colorkey.replacement_format; > } else if (property == plane->color_encoding_property) { > *val = state->color_encoding; > } else if (property == plane->color_range_property) { > diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c > index a16a74d7e15e..05e5632ce375 100644 > --- a/drivers/gpu/drm/drm_blend.c > +++ b/drivers/gpu/drm/drm_blend.c > @@ -107,6 +107,11 @@ > * planes. Without this property the primary plane is always below the cursor > * plane, and ordering between all other planes is undefined. > * > + * colorkey: > + * 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). > @@ -448,3 +453,227 @@ int drm_atomic_normalize_zpos(struct drm_device *dev, > return 0; > } > EXPORT_SYMBOL(drm_atomic_normalize_zpos); > + > +static const char * const plane_colorkey_mode_name[] = { > + [DRM_PLANE_COLORKEY_MODE_DISABLED] = "disabled", > + [DRM_PLANE_COLORKEY_MODE_SRC] = "src-match-src-replace", > + [DRM_PLANE_COLORKEY_MODE_DST] = "dst-match-src-replace", This list seems way more limited than I was expecting, at least when compared to all the different props you're proposing to add. > +}; > + > +/** > + * drm_plane_create_colorkey_properties - create colorkey properties > + * @plane: drm plane > + * @supported_modes: bitmask of supported color keying modes > + * > + * 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 nine properties: > + * > + * colorkey.mode: > + * The mode is an enumerated property that controls how color keying > + * operates. The "disabled" mode that disables color keying and is > + * very likely to exist if color keying is supported, it should be the > + * default mode. > + * > + * colorkey.min, colorkey.max: > + * These two properties specify the colors that are treated as the color > + * key. Pixel whose value is in the [min, max] range is the color key > + * matching pixel. 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 colorkey.format. > + * In most cases XYZ will be either RGB or YUV. > + * > + * When a single color key is desired instead of a range, userspace shall > + * set the min and max properties to the same value. > + * > + * Drivers return an error from their plane atomic check if range can't be > + * handled. > + * > + * colorkey.format: > + * This property specifies the pixel format for the colorkey.min / max > + * properties. The format is given in a form of DRM fourcc code. Umm. Why we do even need this? This seems incompatible with your earlier "min/max are specified in 16bpc format" statement. > + * > + * Drivers return an error from their plane atomic check if pixel format > + * is unsupported. > + * > + * colorkey.mask: > + * This property specifies the pixel components mask. Unmasked pixel > + * components are not participating in the matching. This mask value is > + * applied to colorkey.min / max values. The mask value is given in a > + * form of DRM fourcc code corresponding to the colorkey.format property. > + * > + * For example: userspace shall set the colorkey.mask to 0x0000ff00 > + * to match only the green component if colorkey.format is set to > + * DRM_FORMAT_XRGB8888. > + * > + * Drivers return an error from their plane atomic check if mask value > + * can't be handled. > + * > + * colorkey.inverted-match: > + * This property specifies whether the matching min-max range should > + * be inverted, i.e. pixels outside of the given color range become > + * the color key match. > + * > + * Drivers return an error from their plane atomic check if inversion > + * mode can't be handled. Hmm. I'm trying to figure out what this means for the src vs. dst colorkey modes. Those pretty much already have an inverted meaning when compared to each other. So I can't figure out from these docs whether you're supposed to use this when you want a normal dst ckey or normal src key semantics. > + * > + * colorkey.replacement-value: > + * This property specifies the color value that replaces pixels matching > + * the color key. The value is expressed in AXYZ16161616 format, where A > + * is the alpha value and X, Y and Z correspond to the color components > + * of the colorkey.replacement-format. > + * > + * Drivers return an error from their plane atomic check if replacement > + * value can't be handled. > + * > + * colorkey.replacement-format: > + * This property specifies the pixel format for the > + * colorkey.replacement-value property. The format is given in a form of > + * DRM fourcc code. Again this seems at odds with the 16bpc replacement-value. > + * > + * Drivers return an error from their plane atomic check if replacement > + * pixel format is unsupported. > + * > + * colorkey.replacement-mask: > + * This property specifies the pixel components mask that defines > + * what components of the colorkey.replacement-value will participate in > + * replacement of the pixels color. Unmasked pixel components are not > + * participating in the replacement. Does that mean that the data for the unmasked bits will be coming from the source? > The mask value is given in a form of > + * DRM fourcc code corresponding to the colorkey.replacement-format > + * property. > + * > + * For example: userspace shall set the colorkey.replacement-mask to > + * 0x0000ff00 to replace only the green component if > + * colorkey.replacement-format is set to DRM_FORMAT_XRGB8888. > + * > + * Userspace shall set colorkey.replacement-mask to 0 to disable the color > + * replacement. In this case matching pixels become transparent. > + * > + * Drivers return an error from their plane atomic check if replacement > + * mask value can't be handled. > + * > + * Returns: > + * Zero on success, negative errno on failure. > + */ > +int drm_plane_create_colorkey_properties(struct drm_plane *plane, > + u32 supported_modes) > +{ > + struct drm_prop_enum_list modes_list[DRM_PLANE_COLORKEY_MODES_NUM]; > + struct drm_property *replacement_format_prop; > + struct drm_property *replacement_value_prop; > + struct drm_property *replacement_mask_prop; > + struct drm_property *inverted_match_prop; > + struct drm_property *format_prop; > + struct drm_property *mask_prop; > + struct drm_property *mode_prop; > + struct drm_property *min_prop; > + struct drm_property *max_prop; > + unsigned int modes_num = 0; > + unsigned int i; > + > + /* at least two modes should be supported */ > + if (!supported_modes) > + return -EINVAL; > + > + /* modes are driver-specific, build the list of supported modes */ > + for (i = 0; i < DRM_PLANE_COLORKEY_MODES_NUM; i++) { > + if (!(supported_modes & BIT(i))) > + continue; > + > + modes_list[modes_num].name = plane_colorkey_mode_name[i]; > + modes_list[modes_num].type = i; > + modes_num++; > + } > + > + mode_prop = drm_property_create_enum(plane->dev, 0, "colorkey.mode", > + modes_list, modes_num); > + if (!mode_prop) > + return -ENOMEM; > + > + mask_prop = drm_property_create_range(plane->dev, 0, "colorkey.mask", > + 0, U64_MAX); > + if (!mask_prop) > + goto err_destroy_mode_prop; > + > + min_prop = drm_property_create_range(plane->dev, 0, "colorkey.min", > + 0, U64_MAX); > + if (!min_prop) > + goto err_destroy_mask_prop; > + > + max_prop = drm_property_create_range(plane->dev, 0, "colorkey.max", > + 0, U64_MAX); > + if (!max_prop) > + goto err_destroy_min_prop; > + > + format_prop = drm_property_create_range(plane->dev, 0, > + "colorkey.format", > + 0, U32_MAX); > + if (!format_prop) > + goto err_destroy_max_prop; > + > + inverted_match_prop = drm_property_create_bool(plane->dev, 0, > + "colorkey.inverted-match"); > + if (!inverted_match_prop) > + goto err_destroy_format_prop; > + > + replacement_mask_prop = drm_property_create_range(plane->dev, 0, > + "colorkey.replacement-mask", > + 0, U64_MAX); > + if (!replacement_mask_prop) > + goto err_destroy_inverted_match_prop; > + > + replacement_value_prop = drm_property_create_range(plane->dev, 0, > + "colorkey.replacement-value", > + 0, U64_MAX); > + if (!replacement_value_prop) > + goto err_destroy_replacement_mask_prop; > + > + replacement_format_prop = drm_property_create_range(plane->dev, 0, > + "colorkey.replacement-format", > + 0, U64_MAX); > + if (!replacement_format_prop) > + goto err_destroy_replacement_value_prop; I don't think we want to add all these props for every driver/hardware. IMO the set of props we expose should depend on the supported set of colorkeying modes. > + > + drm_object_attach_property(&plane->base, min_prop, 0); > + drm_object_attach_property(&plane->base, max_prop, 0); > + drm_object_attach_property(&plane->base, mode_prop, 0); > + drm_object_attach_property(&plane->base, mask_prop, 0); > + drm_object_attach_property(&plane->base, format_prop, 0); > + drm_object_attach_property(&plane->base, inverted_match_prop, 0); > + drm_object_attach_property(&plane->base, replacement_mask_prop, 0); > + drm_object_attach_property(&plane->base, replacement_value_prop, 0); > + drm_object_attach_property(&plane->base, replacement_format_prop, 0); > + > + plane->colorkey.min_property = min_prop; > + plane->colorkey.max_property = max_prop; > + plane->colorkey.mode_property = mode_prop; > + plane->colorkey.mask_property = mask_prop; > + plane->colorkey.format_property = format_prop; > + plane->colorkey.inverted_match_property = inverted_match_prop; > + plane->colorkey.replacement_mask_property = replacement_mask_prop; > + plane->colorkey.replacement_value_property = replacement_value_prop; > + plane->colorkey.replacement_format_property = replacement_format_prop; > + > + return 0; > + > +err_destroy_replacement_value_prop: > + drm_property_destroy(plane->dev, replacement_value_prop); > +err_destroy_replacement_mask_prop: > + drm_property_destroy(plane->dev, replacement_mask_prop); > +err_destroy_inverted_match_prop: > + drm_property_destroy(plane->dev, inverted_match_prop); > +err_destroy_format_prop: > + drm_property_destroy(plane->dev, format_prop); > +err_destroy_max_prop: > + drm_property_destroy(plane->dev, max_prop); > +err_destroy_min_prop: > + drm_property_destroy(plane->dev, min_prop); > +err_destroy_mask_prop: > + drm_property_destroy(plane->dev, mask_prop); > +err_destroy_mode_prop: > + drm_property_destroy(plane->dev, mode_prop); > + > + return -ENOMEM; > +} > +EXPORT_SYMBOL(drm_plane_create_colorkey_properties); > diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h > index 330c561c4c11..8e80d33b643e 100644 > --- a/include/drm/drm_blend.h > +++ b/include/drm/drm_blend.h > @@ -52,4 +52,7 @@ 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, > + u32 supported_modes); > #endif > diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h > index 26fa50c2a50e..ff7f5ebe2b79 100644 > --- a/include/drm/drm_plane.h > +++ b/include/drm/drm_plane.h > @@ -32,6 +32,42 @@ struct drm_crtc; > struct drm_printer; > struct drm_modeset_acquire_ctx; > > +/** > + * enum drm_plane_colorkey_mode - uapi plane colorkey mode enumeration > + */ > +enum drm_plane_colorkey_mode { > + /** > + * @DRM_PLANE_COLORKEY_MODE_DISABLED: > + * > + * No color matching performed in this mode. This is the default > + * common mode. > + */ > + DRM_PLANE_COLORKEY_MODE_DISABLED, > + > + /** > + * @DRM_PLANE_COLORKEY_MODE_SRC: > + * > + * In this mode color matching is performed with the pixels of > + * the given plane and the matched pixels are fully (or partially) > + * replaced with the replacement color or become completely > + * transparent. > + */ > + DRM_PLANE_COLORKEY_MODE_SRC, > + > + /** > + * @DRM_PLANE_COLORKEY_MODE_DST: > + * > + * In this mode color matching is performed with the pixels of the > + * planes z-positioned under the given plane and the pixels of the > + * hovering plane that are xy-positioned as the underlying > + * color-matched pixels are fully (or partially) replaced with the > + * replacement color or become completely transparent. > + */ > + DRM_PLANE_COLORKEY_MODE_DST, > + > + DRM_PLANE_COLORKEY_MODES_NUM, > +}; > + > /** > * struct drm_plane_state - mutable plane state > * @plane: backpointer to the plane > @@ -54,6 +90,21 @@ struct drm_modeset_acquire_ctx; > * where N is the number of active planes for given crtc. Note that > * the driver must set drm_mode_config.normalize_zpos or call > * drm_atomic_normalize_zpos() to update this before it can be trusted. > + * @colorkey.mode: color key mode > + * @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.mask: color key mask value (in AXYZ16161616 format) > + * @colorkey.format: color key min/max/mask values pixel format (in > + * DRM_FORMAT_AXYZ16161616 form) > + * @colorkey.inverted_match: color key min-max matching range is inverted > + * @colorkey.replacement_mask: color key replacement mask value (in > + * AXYZ16161616 format) > + * @colorkey.replacement_value: color key replacement value (in > + * AXYZ16161616 format) > + * @colorkey.replacement_format: color key replacement value / mask > + * pixel format (in DRM_FORMAT_AXYZ16161616 form) > * @src: clipped source coordinates of the plane (in 16.16) > * @dst: clipped destination coordinates of the plane > * @state: backpointer to global drm_atomic_state > @@ -124,6 +175,19 @@ struct drm_plane_state { > unsigned int zpos; > unsigned int normalized_zpos; > > + /* Plane colorkey */ > + struct { > + enum drm_plane_colorkey_mode mode; > + u64 min; > + u64 max; > + u64 mask; > + u32 format; > + bool inverted_match; > + u64 replacement_mask; > + u64 replacement_value; > + u32 replacement_format; > + } colorkey; > + > /** > * @color_encoding: > * > @@ -510,6 +574,7 @@ enum drm_plane_type { > * @alpha_property: alpha property for this plane > * @zpos_property: zpos property for this plane > * @rotation_property: rotation property for this plane > + * @colorkey: colorkey properties for this plane > * @helper_private: mid-layer private data > */ > struct drm_plane { > @@ -587,6 +652,18 @@ struct drm_plane { > struct drm_property *zpos_property; > struct drm_property *rotation_property; > > + struct { > + struct drm_property *min_property; > + struct drm_property *max_property; > + struct drm_property *mode_property; > + struct drm_property *mask_property; > + struct drm_property *format_property; > + struct drm_property *inverted_match_property; > + struct drm_property *replacement_mask_property; > + struct drm_property *replacement_value_property; > + struct drm_property *replacement_format_property; > + } colorkey; > + > /** > * @color_encoding_property: > * > -- > 2.17.0 -- Ville Syrjälä Intel