From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932556AbcDYODY (ORCPT ); Mon, 25 Apr 2016 10:03:24 -0400 Received: from smtp.domeneshop.no ([194.63.252.55]:42330 "EHLO smtp.domeneshop.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751708AbcDYODW (ORCPT ); Mon, 25 Apr 2016 10:03:22 -0400 Subject: Re: [PATCH v2 1/8] drm/rect: Add some drm_clip_rect utility functions To: =?UTF-8?B?VmlsbGUgU3lyasOkbMOk?= References: <1461530942-22485-1-git-send-email-noralf@tronnes.org> <1461530942-22485-2-git-send-email-noralf@tronnes.org> <20160425123907.GY4329@intel.com> <571E13D8.4060100@tronnes.org> <20160425130229.GZ4329@intel.com> Cc: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com, linux-kernel@vger.kernel.org From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Message-ID: <571E23A1.2040100@tronnes.org> Date: Mon, 25 Apr 2016 16:03:13 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.7.1 MIME-Version: 1.0 In-Reply-To: <20160425130229.GZ4329@intel.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Den 25.04.2016 15:02, skrev Ville Syrjälä: > On Mon, Apr 25, 2016 at 02:55:52PM +0200, Noralf Trønnes wrote: >> Den 25.04.2016 14:39, skrev Ville Syrjälä: >>> On Sun, Apr 24, 2016 at 10:48:55PM +0200, Noralf Trønnes wrote: >>>> Add some utility functions for struct drm_clip_rect. >>> Looks like mostly you're just duplicating the drm_rect stuff. Why can't >>> you use what's there already? >> That's because the framebuffer flushing uses drm_clip_rect and not drm_rect: > Converting to drm_rect is not an option? That's difficult or at least verbose to do because clips is an array. I could use drm_rect on the calling side (fbdev) since it's only one clip which the changes are merged into, and then convert it when I call dirty(). But the driver can get zero or more clips from the dirty ioctl so I don't see a clean way to convert this array to drm_rect without more code than this proposal has. Here's the driver side: static int mipi_dbi_dirtyfb(struct drm_framebuffer *fb, void *vmem, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips) { struct tinydrm_device *tdev = fb->dev->dev_private; struct lcdreg *reg = tdev->lcdreg; struct drm_clip_rect full_clip = { .x1 = 0, .x2 = fb->width, .y1 = 0, .y2 = fb->height, }; struct drm_clip_rect clip; int ret; drm_clip_rect_reset(&clip); drm_clip_rect_merge(&clip, clips, num_clips, flags, fb->width, fb->height); if (!drm_clip_rect_intersect(&clip, &full_clip)) { DRM_DEBUG_KMS("Empty clip\n"); return -EINVAL; } [...] >> struct drm_framebuffer_funcs { >> [...] >> int (*dirty)(struct drm_framebuffer *framebuffer, >> struct drm_file *file_priv, unsigned flags, >> unsigned color, struct drm_clip_rect *clips, >> unsigned num_clips); >> }; >> >>>> Signed-off-by: Noralf Trønnes >>>> --- >>>> drivers/gpu/drm/drm_rect.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ >>>> include/drm/drm_rect.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++ >>>> 2 files changed, 136 insertions(+) >>>> >>>> diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c >>>> index a8e2c86..a9fb1a8 100644 >>>> --- a/drivers/gpu/drm/drm_rect.c >>>> +++ b/drivers/gpu/drm/drm_rect.c >>>> @@ -434,3 +434,70 @@ void drm_rect_rotate_inv(struct drm_rect *r, >>>> } >>>> } >>>> EXPORT_SYMBOL(drm_rect_rotate_inv); >>>> + >>>> +/** >>>> + * drm_clip_rect_intersect - intersect two clip rectangles >>>> + * @r1: first clip rectangle >>>> + * @r2: second clip rectangle >>>> + * >>>> + * Calculate the intersection of clip rectangles @r1 and @r2. >>>> + * @r1 will be overwritten with the intersection. >>>> + * >>>> + * RETURNS: >>>> + * %true if rectangle @r1 is still visible after the operation, >>>> + * %false otherwise. >>>> + */ >>>> +bool drm_clip_rect_intersect(struct drm_clip_rect *r1, >>>> + const struct drm_clip_rect *r2) >>>> +{ >>>> + r1->x1 = max(r1->x1, r2->x1); >>>> + r1->y1 = max(r1->y1, r2->y1); >>>> + r1->x2 = min(r1->x2, r2->x2); >>>> + r1->y2 = min(r1->y2, r2->y2); >>>> + >>>> + return drm_clip_rect_visible(r1); >>>> +} >>>> +EXPORT_SYMBOL(drm_clip_rect_intersect); >>>> + >>>> +/** >>>> + * drm_clip_rect_merge - Merge clip rectangles >>>> + * @dst: destination clip rectangle >>>> + * @src: source clip rectangle(s), can be NULL >>>> + * @num_clips: number of source clip rectangles >>>> + * @flags: drm_mode_fb_dirty_cmd flags (DRM_MODE_FB_DIRTY_ANNOTATE_COPY) >>>> + * @width: width of clip rectangle if @src is NULL >>>> + * @height: height of clip rectangle if @src is NULL >>>> + * >>>> + * The dirtyfb ioctl allows for a NULL clip rectangle to be passed in, >>>> + * so if @src is NULL, width and height is used to set a full clip rectangle. >>>> + * @dst takes part in the merge unless it is empty {0,0,0,0}. >>>> + */ >>>> +void drm_clip_rect_merge(struct drm_clip_rect *dst, >>>> + struct drm_clip_rect *src, unsigned num_clips, >>>> + unsigned flags, u32 width, u32 height) >>>> +{ >>>> + int i; >>>> + >>>> + if (!src || !num_clips) { >>>> + dst->x1 = 0; >>>> + dst->x2 = width; >>>> + dst->y1 = 0; >>>> + dst->y2 = height; >>>> + return; >>>> + } >>>> + >>>> + if (drm_clip_rect_is_empty(dst)) { >>>> + dst->x1 = ~0; >>>> + dst->y1 = ~0; >>>> + } >>>> + >>>> + for (i = 0; i < num_clips; i++) { >>>> + if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) >>>> + i++; >>>> + dst->x1 = min(dst->x1, src[i].x1); >>>> + dst->x2 = max(dst->x2, src[i].x2); >>>> + dst->y1 = min(dst->y1, src[i].y1); >>>> + dst->y2 = max(dst->y2, src[i].y2); >>>> + } >>>> +} >>>> +EXPORT_SYMBOL(drm_clip_rect_merge); >>>> diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h >>>> index 83bb156..936ad8d 100644 >>>> --- a/include/drm/drm_rect.h >>>> +++ b/include/drm/drm_rect.h >>>> @@ -24,6 +24,8 @@ >>>> #ifndef DRM_RECT_H >>>> #define DRM_RECT_H >>>> >>>> +#include >>>> + >>>> /** >>>> * DOC: rect utils >>>> * >>>> @@ -171,4 +173,71 @@ void drm_rect_rotate_inv(struct drm_rect *r, >>>> int width, int height, >>>> unsigned int rotation); >>>> >>>> +/** >>>> + * drm_clip_rect_width - determine the clip rectangle width >>>> + * @r: clip rectangle whose width is returned >>>> + * >>>> + * RETURNS: >>>> + * The width of the clip rectangle. >>>> + */ >>>> +static inline int drm_clip_rect_width(const struct drm_clip_rect *r) >>>> +{ >>>> + return r->x2 - r->x1; >>>> +} >>>> + >>>> +/** >>>> + * drm_clip_rect_height - determine the clip rectangle height >>>> + * @r: clip rectangle whose height is returned >>>> + * >>>> + * RETURNS: >>>> + * The height of the clip rectangle. >>>> + */ >>>> +static inline int drm_clip_rect_height(const struct drm_clip_rect *r) >>>> +{ >>>> + return r->y2 - r->y1; >>>> +} >>>> + >>>> +/** >>>> + * drm_clip_rect_visible - determine if the the clip rectangle is visible >>>> + * @r: clip rectangle whose visibility is returned >>>> + * >>>> + * RETURNS: >>>> + * %true if the clip rectangle is visible, %false otherwise. >>>> + */ >>>> +static inline bool drm_clip_rect_visible(const struct drm_clip_rect *r) >>>> +{ >>>> + return drm_clip_rect_width(r) > 0 && drm_clip_rect_height(r) > 0; >>>> +} >>>> + >>>> +/** >>>> + * drm_clip_rect_reset - Reset clip rectangle >>>> + * @clip: clip rectangle >>>> + * >>>> + * Sets clip rectangle to {0,0,0,0}. >>>> + */ >>>> +static inline void drm_clip_rect_reset(struct drm_clip_rect *clip) >>>> +{ >>>> + clip->x1 = 0; >>>> + clip->x2 = 0; >>>> + clip->y1 = 0; >>>> + clip->y2 = 0; >>>> +} >>>> + >>>> +/** >>>> + * drm_clip_rect_is_empty - Is clip rectangle empty? >>>> + * @clip: clip rectangle >>>> + * >>>> + * Returns true if clip rectangle is {0,0,0,0}. >>>> + */ >>>> +static inline bool drm_clip_rect_is_empty(struct drm_clip_rect *clip) >>>> +{ >>>> + return (!clip->x1 && !clip->x2 && !clip->y1 && !clip->y2); >>>> +} >>>> + >>>> +bool drm_clip_rect_intersect(struct drm_clip_rect *r1, >>>> + const struct drm_clip_rect *r2); >>>> +void drm_clip_rect_merge(struct drm_clip_rect *dst, >>>> + struct drm_clip_rect *src, unsigned num_clips, >>>> + unsigned flags, u32 width, u32 height); >>>> + >>>> #endif >>>> -- >>>> 2.2.2 >>>> >>>> _______________________________________________ >>>> dri-devel mailing list >>>> dri-devel@lists.freedesktop.org >>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Date: Mon, 25 Apr 2016 14:03:13 +0000 Subject: Re: [PATCH v2 1/8] drm/rect: Add some drm_clip_rect utility functions Message-Id: <571E23A1.2040100@tronnes.org> List-Id: References: <1461530942-22485-1-git-send-email-noralf@tronnes.org> <1461530942-22485-2-git-send-email-noralf@tronnes.org> <20160425123907.GY4329@intel.com> <571E13D8.4060100@tronnes.org> <20160425130229.GZ4329@intel.com> In-Reply-To: <20160425130229.GZ4329@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: =?UTF-8?B?VmlsbGUgU3lyasOkbMOk?= Cc: linux-fbdev@vger.kernel.org, tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Den 25.04.2016 15:02, skrev Ville Syrj=E4l=E4: > On Mon, Apr 25, 2016 at 02:55:52PM +0200, Noralf Tr=F8nnes wrote: >> Den 25.04.2016 14:39, skrev Ville Syrj=E4l=E4: >>> On Sun, Apr 24, 2016 at 10:48:55PM +0200, Noralf Tr=F8nnes wrote: >>>> Add some utility functions for struct drm_clip_rect. >>> Looks like mostly you're just duplicating the drm_rect stuff. Why can't >>> you use what's there already? >> That's because the framebuffer flushing uses drm_clip_rect and not drm_r= ect: > Converting to drm_rect is not an option? That's difficult or at least verbose to do because clips is an array. I could use drm_rect on the calling side (fbdev) since it's only one clip which the changes are merged into, and then convert it when I call dirty(). But the driver can get zero or more clips from the dirty ioctl so I don't see a clean way to convert this array to drm_rect without more code than this proposal has. Here's the driver side: static int mipi_dbi_dirtyfb(struct drm_framebuffer *fb, void *vmem, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips) { struct tinydrm_device *tdev =3D fb->dev->dev_private; struct lcdreg *reg =3D tdev->lcdreg; struct drm_clip_rect full_clip =3D { .x1 =3D 0, .x2 =3D fb->width, .y1 =3D 0, .y2 =3D fb->height, }; struct drm_clip_rect clip; int ret; drm_clip_rect_reset(&clip); drm_clip_rect_merge(&clip, clips, num_clips, flags, fb->width, fb->height); if (!drm_clip_rect_intersect(&clip, &full_clip)) { DRM_DEBUG_KMS("Empty clip\n"); return -EINVAL; } [...] >> struct drm_framebuffer_funcs { >> [...] >> int (*dirty)(struct drm_framebuffer *framebuffer, >> struct drm_file *file_priv, unsigned flags, >> unsigned color, struct drm_clip_rect *clips, >> unsigned num_clips); >> }; >> >>>> Signed-off-by: Noralf Tr=F8nnes >>>> --- >>>> drivers/gpu/drm/drm_rect.c | 67 +++++++++++++++++++++++++++++++++++= +++++++++ >>>> include/drm/drm_rect.h | 69 +++++++++++++++++++++++++++++++++++= +++++++++++ >>>> 2 files changed, 136 insertions(+) >>>> >>>> diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c >>>> index a8e2c86..a9fb1a8 100644 >>>> --- a/drivers/gpu/drm/drm_rect.c >>>> +++ b/drivers/gpu/drm/drm_rect.c >>>> @@ -434,3 +434,70 @@ void drm_rect_rotate_inv(struct drm_rect *r, >>>> } >>>> } >>>> EXPORT_SYMBOL(drm_rect_rotate_inv); >>>> + >>>> +/** >>>> + * drm_clip_rect_intersect - intersect two clip rectangles >>>> + * @r1: first clip rectangle >>>> + * @r2: second clip rectangle >>>> + * >>>> + * Calculate the intersection of clip rectangles @r1 and @r2. >>>> + * @r1 will be overwritten with the intersection. >>>> + * >>>> + * RETURNS: >>>> + * %true if rectangle @r1 is still visible after the operation, >>>> + * %false otherwise. >>>> + */ >>>> +bool drm_clip_rect_intersect(struct drm_clip_rect *r1, >>>> + const struct drm_clip_rect *r2) >>>> +{ >>>> + r1->x1 =3D max(r1->x1, r2->x1); >>>> + r1->y1 =3D max(r1->y1, r2->y1); >>>> + r1->x2 =3D min(r1->x2, r2->x2); >>>> + r1->y2 =3D min(r1->y2, r2->y2); >>>> + >>>> + return drm_clip_rect_visible(r1); >>>> +} >>>> +EXPORT_SYMBOL(drm_clip_rect_intersect); >>>> + >>>> +/** >>>> + * drm_clip_rect_merge - Merge clip rectangles >>>> + * @dst: destination clip rectangle >>>> + * @src: source clip rectangle(s), can be NULL >>>> + * @num_clips: number of source clip rectangles >>>> + * @flags: drm_mode_fb_dirty_cmd flags (DRM_MODE_FB_DIRTY_ANNOTATE_CO= PY) >>>> + * @width: width of clip rectangle if @src is NULL >>>> + * @height: height of clip rectangle if @src is NULL >>>> + * >>>> + * The dirtyfb ioctl allows for a NULL clip rectangle to be passed in, >>>> + * so if @src is NULL, width and height is used to set a full clip re= ctangle. >>>> + * @dst takes part in the merge unless it is empty {0,0,0,0}. >>>> + */ >>>> +void drm_clip_rect_merge(struct drm_clip_rect *dst, >>>> + struct drm_clip_rect *src, unsigned num_clips, >>>> + unsigned flags, u32 width, u32 height) >>>> +{ >>>> + int i; >>>> + >>>> + if (!src || !num_clips) { >>>> + dst->x1 =3D 0; >>>> + dst->x2 =3D width; >>>> + dst->y1 =3D 0; >>>> + dst->y2 =3D height; >>>> + return; >>>> + } >>>> + >>>> + if (drm_clip_rect_is_empty(dst)) { >>>> + dst->x1 =3D ~0; >>>> + dst->y1 =3D ~0; >>>> + } >>>> + >>>> + for (i =3D 0; i < num_clips; i++) { >>>> + if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) >>>> + i++; >>>> + dst->x1 =3D min(dst->x1, src[i].x1); >>>> + dst->x2 =3D max(dst->x2, src[i].x2); >>>> + dst->y1 =3D min(dst->y1, src[i].y1); >>>> + dst->y2 =3D max(dst->y2, src[i].y2); >>>> + } >>>> +} >>>> +EXPORT_SYMBOL(drm_clip_rect_merge); >>>> diff --git a/include/drm/drm_rect.h b/include/drm/drm_rect.h >>>> index 83bb156..936ad8d 100644 >>>> --- a/include/drm/drm_rect.h >>>> +++ b/include/drm/drm_rect.h >>>> @@ -24,6 +24,8 @@ >>>> #ifndef DRM_RECT_H >>>> #define DRM_RECT_H >>>> =20 >>>> +#include >>>> + >>>> /** >>>> * DOC: rect utils >>>> * >>>> @@ -171,4 +173,71 @@ void drm_rect_rotate_inv(struct drm_rect *r, >>>> int width, int height, >>>> unsigned int rotation); >>>> =20 >>>> +/** >>>> + * drm_clip_rect_width - determine the clip rectangle width >>>> + * @r: clip rectangle whose width is returned >>>> + * >>>> + * RETURNS: >>>> + * The width of the clip rectangle. >>>> + */ >>>> +static inline int drm_clip_rect_width(const struct drm_clip_rect *r) >>>> +{ >>>> + return r->x2 - r->x1; >>>> +} >>>> + >>>> +/** >>>> + * drm_clip_rect_height - determine the clip rectangle height >>>> + * @r: clip rectangle whose height is returned >>>> + * >>>> + * RETURNS: >>>> + * The height of the clip rectangle. >>>> + */ >>>> +static inline int drm_clip_rect_height(const struct drm_clip_rect *r) >>>> +{ >>>> + return r->y2 - r->y1; >>>> +} >>>> + >>>> +/** >>>> + * drm_clip_rect_visible - determine if the the clip rectangle is vis= ible >>>> + * @r: clip rectangle whose visibility is returned >>>> + * >>>> + * RETURNS: >>>> + * %true if the clip rectangle is visible, %false otherwise. >>>> + */ >>>> +static inline bool drm_clip_rect_visible(const struct drm_clip_rect *= r) >>>> +{ >>>> + return drm_clip_rect_width(r) > 0 && drm_clip_rect_height(r) > 0; >>>> +} >>>> + >>>> +/** >>>> + * drm_clip_rect_reset - Reset clip rectangle >>>> + * @clip: clip rectangle >>>> + * >>>> + * Sets clip rectangle to {0,0,0,0}. >>>> + */ >>>> +static inline void drm_clip_rect_reset(struct drm_clip_rect *clip) >>>> +{ >>>> + clip->x1 =3D 0; >>>> + clip->x2 =3D 0; >>>> + clip->y1 =3D 0; >>>> + clip->y2 =3D 0; >>>> +} >>>> + >>>> +/** >>>> + * drm_clip_rect_is_empty - Is clip rectangle empty? >>>> + * @clip: clip rectangle >>>> + * >>>> + * Returns true if clip rectangle is {0,0,0,0}. >>>> + */ >>>> +static inline bool drm_clip_rect_is_empty(struct drm_clip_rect *clip) >>>> +{ >>>> + return (!clip->x1 && !clip->x2 && !clip->y1 && !clip->y2); >>>> +} >>>> + >>>> +bool drm_clip_rect_intersect(struct drm_clip_rect *r1, >>>> + const struct drm_clip_rect *r2); >>>> +void drm_clip_rect_merge(struct drm_clip_rect *dst, >>>> + struct drm_clip_rect *src, unsigned num_clips, >>>> + unsigned flags, u32 width, u32 height); >>>> + >>>> #endif >>>> --=20 >>>> 2.2.2 >>>> >>>> _______________________________________________ >>>> dri-devel mailing list >>>> dri-devel@lists.freedesktop.org >>>> https://lists.freedesktop.org/mailman/listinfo/dri-devel From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= Subject: Re: [PATCH v2 1/8] drm/rect: Add some drm_clip_rect utility functions Date: Mon, 25 Apr 2016 16:03:13 +0200 Message-ID: <571E23A1.2040100@tronnes.org> References: <1461530942-22485-1-git-send-email-noralf@tronnes.org> <1461530942-22485-2-git-send-email-noralf@tronnes.org> <20160425123907.GY4329@intel.com> <571E13D8.4060100@tronnes.org> <20160425130229.GZ4329@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: Received: from smtp.domeneshop.no (smtp.domeneshop.no [IPv6:2a01:5b40:0:3005::1]) by gabe.freedesktop.org (Postfix) with ESMTPS id 037976E60A for ; Mon, 25 Apr 2016 14:03:23 +0000 (UTC) In-Reply-To: <20160425130229.GZ4329@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: =?UTF-8?B?VmlsbGUgU3lyasOkbMOk?= Cc: linux-fbdev@vger.kernel.org, tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org CkRlbiAyNS4wNC4yMDE2IDE1OjAyLCBza3JldiBWaWxsZSBTeXJqw6Rsw6Q6Cj4gT24gTW9uLCBB cHIgMjUsIDIwMTYgYXQgMDI6NTU6NTJQTSArMDIwMCwgTm9yYWxmIFRyw7hubmVzIHdyb3RlOgo+ PiBEZW4gMjUuMDQuMjAxNiAxNDozOSwgc2tyZXYgVmlsbGUgU3lyasOkbMOkOgo+Pj4gT24gU3Vu LCBBcHIgMjQsIDIwMTYgYXQgMTA6NDg6NTVQTSArMDIwMCwgTm9yYWxmIFRyw7hubmVzIHdyb3Rl Ogo+Pj4+IEFkZCBzb21lIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBzdHJ1Y3QgZHJtX2NsaXBfcmVj dC4KPj4+IExvb2tzIGxpa2UgbW9zdGx5IHlvdSdyZSBqdXN0IGR1cGxpY2F0aW5nIHRoZSBkcm1f cmVjdCBzdHVmZi4gV2h5IGNhbid0Cj4+PiB5b3UgdXNlIHdoYXQncyB0aGVyZSBhbHJlYWR5Pwo+ PiBUaGF0J3MgYmVjYXVzZSB0aGUgZnJhbWVidWZmZXIgZmx1c2hpbmcgdXNlcyBkcm1fY2xpcF9y ZWN0IGFuZCBub3QgZHJtX3JlY3Q6Cj4gQ29udmVydGluZyB0byBkcm1fcmVjdCBpcyBub3QgYW4g b3B0aW9uPwoKVGhhdCdzIGRpZmZpY3VsdCBvciBhdCBsZWFzdCB2ZXJib3NlIHRvIGRvIGJlY2F1 c2UgY2xpcHMgaXMgYW4gYXJyYXkuCkkgY291bGQgdXNlIGRybV9yZWN0IG9uIHRoZSBjYWxsaW5n IHNpZGUgKGZiZGV2KSBzaW5jZSBpdCdzIG9ubHkgb25lIGNsaXAKd2hpY2ggdGhlIGNoYW5nZXMg YXJlIG1lcmdlZCBpbnRvLCBhbmQgdGhlbiBjb252ZXJ0IGl0IHdoZW4gSSBjYWxsIGRpcnR5KCku CkJ1dCB0aGUgZHJpdmVyIGNhbiBnZXQgemVybyBvciBtb3JlIGNsaXBzIGZyb20gdGhlIGRpcnR5 IGlvY3RsIHNvIEkgZG9uJ3QKc2VlIGEgY2xlYW4gd2F5IHRvIGNvbnZlcnQgdGhpcyBhcnJheSB0 byBkcm1fcmVjdCB3aXRob3V0IG1vcmUgY29kZSB0aGFuCnRoaXMgcHJvcG9zYWwgaGFzLgoKSGVy ZSdzIHRoZSBkcml2ZXIgc2lkZToKCnN0YXRpYyBpbnQgbWlwaV9kYmlfZGlydHlmYihzdHJ1Y3Qg ZHJtX2ZyYW1lYnVmZmVyICpmYiwgdm9pZCAqdm1lbSwKICAgICAgICAgICAgICAgICB1bnNpZ25l ZCBmbGFncywgdW5zaWduZWQgY29sb3IsCiAgICAgICAgICAgICAgICAgc3RydWN0IGRybV9jbGlw X3JlY3QgKmNsaXBzLCB1bnNpZ25lZCBudW1fY2xpcHMpCnsKICAgICBzdHJ1Y3QgdGlueWRybV9k ZXZpY2UgKnRkZXYgPSBmYi0+ZGV2LT5kZXZfcHJpdmF0ZTsKICAgICBzdHJ1Y3QgbGNkcmVnICpy ZWcgPSB0ZGV2LT5sY2RyZWc7CiAgICAgc3RydWN0IGRybV9jbGlwX3JlY3QgZnVsbF9jbGlwID0g ewogICAgICAgICAueDEgPSAwLAogICAgICAgICAueDIgPSBmYi0+d2lkdGgsCiAgICAgICAgIC55 MSA9IDAsCiAgICAgICAgIC55MiA9IGZiLT5oZWlnaHQsCiAgICAgfTsKICAgICBzdHJ1Y3QgZHJt X2NsaXBfcmVjdCBjbGlwOwogICAgIGludCByZXQ7CgogICAgIGRybV9jbGlwX3JlY3RfcmVzZXQo JmNsaXApOwogICAgIGRybV9jbGlwX3JlY3RfbWVyZ2UoJmNsaXAsIGNsaXBzLCBudW1fY2xpcHMs IGZsYWdzLAogICAgICAgICAgICAgICAgIGZiLT53aWR0aCwgZmItPmhlaWdodCk7CiAgICAgaWYg KCFkcm1fY2xpcF9yZWN0X2ludGVyc2VjdCgmY2xpcCwgJmZ1bGxfY2xpcCkpIHsKICAgICAgICAg RFJNX0RFQlVHX0tNUygiRW1wdHkgY2xpcFxuIik7CiAgICAgICAgIHJldHVybiAtRUlOVkFMOwog ICAgIH0KWy4uLl0KCj4+IHN0cnVjdCBkcm1fZnJhbWVidWZmZXJfZnVuY3Mgewo+PiBbLi4uXQo+ PiAgICAgICAgICAgaW50ICgqZGlydHkpKHN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZyYW1lYnVm ZmVyLAo+PiAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkcm1fZmlsZSAqZmlsZV9wcml2 LCB1bnNpZ25lZCBmbGFncywKPj4gICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjb2xv ciwgc3RydWN0IGRybV9jbGlwX3JlY3QgKmNsaXBzLAo+PiAgICAgICAgICAgICAgICAgICAgICAg IHVuc2lnbmVkIG51bV9jbGlwcyk7Cj4+IH07Cj4+Cj4+Pj4gU2lnbmVkLW9mZi1ieTogTm9yYWxm IFRyw7hubmVzIDxub3JhbGZAdHJvbm5lcy5vcmc+Cj4+Pj4gLS0tCj4+Pj4gICAgZHJpdmVycy9n cHUvZHJtL2RybV9yZWN0LmMgfCA2NyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKwo+Pj4+ICAgIGluY2x1ZGUvZHJtL2RybV9yZWN0LmggICAgIHwgNjkgKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+Pj4+ICAgIDIgZmlsZXMg Y2hhbmdlZCwgMTM2IGluc2VydGlvbnMoKykKPj4+Pgo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vZHJtX3JlY3QuYyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fcmVjdC5jCj4+Pj4gaW5k ZXggYThlMmM4Ni4uYTlmYjFhOCAxMDA2NDQKPj4+PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vZHJt X3JlY3QuYwo+Pj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fcmVjdC5jCj4+Pj4gQEAgLTQz NCwzICs0MzQsNzAgQEAgdm9pZCBkcm1fcmVjdF9yb3RhdGVfaW52KHN0cnVjdCBkcm1fcmVjdCAq ciwKPj4+PiAgICAJfQo+Pj4+ICAgIH0KPj4+PiAgICBFWFBPUlRfU1lNQk9MKGRybV9yZWN0X3Jv dGF0ZV9pbnYpOwo+Pj4+ICsKPj4+PiArLyoqCj4+Pj4gKyAqIGRybV9jbGlwX3JlY3RfaW50ZXJz ZWN0IC0gaW50ZXJzZWN0IHR3byBjbGlwIHJlY3RhbmdsZXMKPj4+PiArICogQHIxOiBmaXJzdCBj bGlwIHJlY3RhbmdsZQo+Pj4+ICsgKiBAcjI6IHNlY29uZCBjbGlwIHJlY3RhbmdsZQo+Pj4+ICsg Kgo+Pj4+ICsgKiBDYWxjdWxhdGUgdGhlIGludGVyc2VjdGlvbiBvZiBjbGlwIHJlY3RhbmdsZXMg QHIxIGFuZCBAcjIuCj4+Pj4gKyAqIEByMSB3aWxsIGJlIG92ZXJ3cml0dGVuIHdpdGggdGhlIGlu dGVyc2VjdGlvbi4KPj4+PiArICoKPj4+PiArICogUkVUVVJOUzoKPj4+PiArICogJXRydWUgaWYg cmVjdGFuZ2xlIEByMSBpcyBzdGlsbCB2aXNpYmxlIGFmdGVyIHRoZSBvcGVyYXRpb24sCj4+Pj4g KyAqICVmYWxzZSBvdGhlcndpc2UuCj4+Pj4gKyAqLwo+Pj4+ICtib29sIGRybV9jbGlwX3JlY3Rf aW50ZXJzZWN0KHN0cnVjdCBkcm1fY2xpcF9yZWN0ICpyMSwKPj4+PiArCQkJICAgICBjb25zdCBz dHJ1Y3QgZHJtX2NsaXBfcmVjdCAqcjIpCj4+Pj4gK3sKPj4+PiArCXIxLT54MSA9IG1heChyMS0+ eDEsIHIyLT54MSk7Cj4+Pj4gKwlyMS0+eTEgPSBtYXgocjEtPnkxLCByMi0+eTEpOwo+Pj4+ICsJ cjEtPngyID0gbWluKHIxLT54MiwgcjItPngyKTsKPj4+PiArCXIxLT55MiA9IG1pbihyMS0+eTIs IHIyLT55Mik7Cj4+Pj4gKwo+Pj4+ICsJcmV0dXJuIGRybV9jbGlwX3JlY3RfdmlzaWJsZShyMSk7 Cj4+Pj4gK30KPj4+PiArRVhQT1JUX1NZTUJPTChkcm1fY2xpcF9yZWN0X2ludGVyc2VjdCk7Cj4+ Pj4gKwo+Pj4+ICsvKioKPj4+PiArICogZHJtX2NsaXBfcmVjdF9tZXJnZSAtIE1lcmdlIGNsaXAg cmVjdGFuZ2xlcwo+Pj4+ICsgKiBAZHN0OiBkZXN0aW5hdGlvbiBjbGlwIHJlY3RhbmdsZQo+Pj4+ ICsgKiBAc3JjOiBzb3VyY2UgY2xpcCByZWN0YW5nbGUocyksIGNhbiBiZSBOVUxMCj4+Pj4gKyAq IEBudW1fY2xpcHM6IG51bWJlciBvZiBzb3VyY2UgY2xpcCByZWN0YW5nbGVzCj4+Pj4gKyAqIEBm bGFnczogZHJtX21vZGVfZmJfZGlydHlfY21kIGZsYWdzIChEUk1fTU9ERV9GQl9ESVJUWV9BTk5P VEFURV9DT1BZKQo+Pj4+ICsgKiBAd2lkdGg6IHdpZHRoIG9mIGNsaXAgcmVjdGFuZ2xlIGlmIEBz cmMgaXMgTlVMTAo+Pj4+ICsgKiBAaGVpZ2h0OiBoZWlnaHQgb2YgY2xpcCByZWN0YW5nbGUgaWYg QHNyYyBpcyBOVUxMCj4+Pj4gKyAqCj4+Pj4gKyAqIFRoZSBkaXJ0eWZiIGlvY3RsIGFsbG93cyBm b3IgYSBOVUxMIGNsaXAgcmVjdGFuZ2xlIHRvIGJlIHBhc3NlZCBpbiwKPj4+PiArICogc28gaWYg QHNyYyBpcyBOVUxMLCB3aWR0aCBhbmQgaGVpZ2h0IGlzIHVzZWQgdG8gc2V0IGEgZnVsbCBjbGlw IHJlY3RhbmdsZS4KPj4+PiArICogQGRzdCB0YWtlcyBwYXJ0IGluIHRoZSBtZXJnZSB1bmxlc3Mg aXQgaXMgZW1wdHkgezAsMCwwLDB9Lgo+Pj4+ICsgKi8KPj4+PiArdm9pZCBkcm1fY2xpcF9yZWN0 X21lcmdlKHN0cnVjdCBkcm1fY2xpcF9yZWN0ICpkc3QsCj4+Pj4gKwkJCSBzdHJ1Y3QgZHJtX2Ns aXBfcmVjdCAqc3JjLCB1bnNpZ25lZCBudW1fY2xpcHMsCj4+Pj4gKwkJCSB1bnNpZ25lZCBmbGFn cywgdTMyIHdpZHRoLCB1MzIgaGVpZ2h0KQo+Pj4+ICt7Cj4+Pj4gKwlpbnQgaTsKPj4+PiArCj4+ Pj4gKwlpZiAoIXNyYyB8fCAhbnVtX2NsaXBzKSB7Cj4+Pj4gKwkJZHN0LT54MSA9IDA7Cj4+Pj4g KwkJZHN0LT54MiA9IHdpZHRoOwo+Pj4+ICsJCWRzdC0+eTEgPSAwOwo+Pj4+ICsJCWRzdC0+eTIg PSBoZWlnaHQ7Cj4+Pj4gKwkJcmV0dXJuOwo+Pj4+ICsJfQo+Pj4+ICsKPj4+PiArCWlmIChkcm1f Y2xpcF9yZWN0X2lzX2VtcHR5KGRzdCkpIHsKPj4+PiArCQlkc3QtPngxID0gfjA7Cj4+Pj4gKwkJ ZHN0LT55MSA9IH4wOwo+Pj4+ICsJfQo+Pj4+ICsKPj4+PiArCWZvciAoaSA9IDA7IGkgPCBudW1f Y2xpcHM7IGkrKykgewo+Pj4+ICsJCWlmIChmbGFncyAmIERSTV9NT0RFX0ZCX0RJUlRZX0FOTk9U QVRFX0NPUFkpCj4+Pj4gKwkJCWkrKzsKPj4+PiArCQlkc3QtPngxID0gbWluKGRzdC0+eDEsIHNy Y1tpXS54MSk7Cj4+Pj4gKwkJZHN0LT54MiA9IG1heChkc3QtPngyLCBzcmNbaV0ueDIpOwo+Pj4+ ICsJCWRzdC0+eTEgPSBtaW4oZHN0LT55MSwgc3JjW2ldLnkxKTsKPj4+PiArCQlkc3QtPnkyID0g bWF4KGRzdC0+eTIsIHNyY1tpXS55Mik7Cj4+Pj4gKwl9Cj4+Pj4gK30KPj4+PiArRVhQT1JUX1NZ TUJPTChkcm1fY2xpcF9yZWN0X21lcmdlKTsKPj4+PiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9kcm0v ZHJtX3JlY3QuaCBiL2luY2x1ZGUvZHJtL2RybV9yZWN0LmgKPj4+PiBpbmRleCA4M2JiMTU2Li45 MzZhZDhkIDEwMDY0NAo+Pj4+IC0tLSBhL2luY2x1ZGUvZHJtL2RybV9yZWN0LmgKPj4+PiArKysg Yi9pbmNsdWRlL2RybS9kcm1fcmVjdC5oCj4+Pj4gQEAgLTI0LDYgKzI0LDggQEAKPj4+PiAgICAj aWZuZGVmIERSTV9SRUNUX0gKPj4+PiAgICAjZGVmaW5lIERSTV9SRUNUX0gKPj4+PiAgICAKPj4+ PiArI2luY2x1ZGUgPHVhcGkvZHJtL2RybS5oPgo+Pj4+ICsKPj4+PiAgICAvKioKPj4+PiAgICAg KiBET0M6IHJlY3QgdXRpbHMKPj4+PiAgICAgKgo+Pj4+IEBAIC0xNzEsNCArMTczLDcxIEBAIHZv aWQgZHJtX3JlY3Rfcm90YXRlX2ludihzdHJ1Y3QgZHJtX3JlY3QgKnIsCj4+Pj4gICAgCQkJIGlu dCB3aWR0aCwgaW50IGhlaWdodCwKPj4+PiAgICAJCQkgdW5zaWduZWQgaW50IHJvdGF0aW9uKTsK Pj4+PiAgICAKPj4+PiArLyoqCj4+Pj4gKyAqIGRybV9jbGlwX3JlY3Rfd2lkdGggLSBkZXRlcm1p bmUgdGhlIGNsaXAgcmVjdGFuZ2xlIHdpZHRoCj4+Pj4gKyAqIEByOiBjbGlwIHJlY3RhbmdsZSB3 aG9zZSB3aWR0aCBpcyByZXR1cm5lZAo+Pj4+ICsgKgo+Pj4+ICsgKiBSRVRVUk5TOgo+Pj4+ICsg KiBUaGUgd2lkdGggb2YgdGhlIGNsaXAgcmVjdGFuZ2xlLgo+Pj4+ICsgKi8KPj4+PiArc3RhdGlj IGlubGluZSBpbnQgZHJtX2NsaXBfcmVjdF93aWR0aChjb25zdCBzdHJ1Y3QgZHJtX2NsaXBfcmVj dCAqcikKPj4+PiArewo+Pj4+ICsJcmV0dXJuIHItPngyIC0gci0+eDE7Cj4+Pj4gK30KPj4+PiAr Cj4+Pj4gKy8qKgo+Pj4+ICsgKiBkcm1fY2xpcF9yZWN0X2hlaWdodCAtIGRldGVybWluZSB0aGUg Y2xpcCByZWN0YW5nbGUgaGVpZ2h0Cj4+Pj4gKyAqIEByOiBjbGlwIHJlY3RhbmdsZSB3aG9zZSBo ZWlnaHQgaXMgcmV0dXJuZWQKPj4+PiArICoKPj4+PiArICogUkVUVVJOUzoKPj4+PiArICogVGhl IGhlaWdodCBvZiB0aGUgY2xpcCByZWN0YW5nbGUuCj4+Pj4gKyAqLwo+Pj4+ICtzdGF0aWMgaW5s aW5lIGludCBkcm1fY2xpcF9yZWN0X2hlaWdodChjb25zdCBzdHJ1Y3QgZHJtX2NsaXBfcmVjdCAq cikKPj4+PiArewo+Pj4+ICsJcmV0dXJuIHItPnkyIC0gci0+eTE7Cj4+Pj4gK30KPj4+PiArCj4+ Pj4gKy8qKgo+Pj4+ICsgKiBkcm1fY2xpcF9yZWN0X3Zpc2libGUgLSBkZXRlcm1pbmUgaWYgdGhl IHRoZSBjbGlwIHJlY3RhbmdsZSBpcyB2aXNpYmxlCj4+Pj4gKyAqIEByOiBjbGlwIHJlY3Rhbmds ZSB3aG9zZSB2aXNpYmlsaXR5IGlzIHJldHVybmVkCj4+Pj4gKyAqCj4+Pj4gKyAqIFJFVFVSTlM6 Cj4+Pj4gKyAqICV0cnVlIGlmIHRoZSBjbGlwIHJlY3RhbmdsZSBpcyB2aXNpYmxlLCAlZmFsc2Ug b3RoZXJ3aXNlLgo+Pj4+ICsgKi8KPj4+PiArc3RhdGljIGlubGluZSBib29sIGRybV9jbGlwX3Jl Y3RfdmlzaWJsZShjb25zdCBzdHJ1Y3QgZHJtX2NsaXBfcmVjdCAqcikKPj4+PiArewo+Pj4+ICsJ cmV0dXJuIGRybV9jbGlwX3JlY3Rfd2lkdGgocikgPiAwICYmIGRybV9jbGlwX3JlY3RfaGVpZ2h0 KHIpID4gMDsKPj4+PiArfQo+Pj4+ICsKPj4+PiArLyoqCj4+Pj4gKyAqIGRybV9jbGlwX3JlY3Rf cmVzZXQgLSBSZXNldCBjbGlwIHJlY3RhbmdsZQo+Pj4+ICsgKiBAY2xpcDogY2xpcCByZWN0YW5n bGUKPj4+PiArICoKPj4+PiArICogU2V0cyBjbGlwIHJlY3RhbmdsZSB0byB7MCwwLDAsMH0uCj4+ Pj4gKyAqLwo+Pj4+ICtzdGF0aWMgaW5saW5lIHZvaWQgZHJtX2NsaXBfcmVjdF9yZXNldChzdHJ1 Y3QgZHJtX2NsaXBfcmVjdCAqY2xpcCkKPj4+PiArewo+Pj4+ICsJY2xpcC0+eDEgPSAwOwo+Pj4+ ICsJY2xpcC0+eDIgPSAwOwo+Pj4+ICsJY2xpcC0+eTEgPSAwOwo+Pj4+ICsJY2xpcC0+eTIgPSAw Owo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICsvKioKPj4+PiArICogZHJtX2NsaXBfcmVjdF9pc19lbXB0 eSAtIElzIGNsaXAgcmVjdGFuZ2xlIGVtcHR5Pwo+Pj4+ICsgKiBAY2xpcDogY2xpcCByZWN0YW5n bGUKPj4+PiArICoKPj4+PiArICogUmV0dXJucyB0cnVlIGlmIGNsaXAgcmVjdGFuZ2xlIGlzIHsw LDAsMCwwfS4KPj4+PiArICovCj4+Pj4gK3N0YXRpYyBpbmxpbmUgYm9vbCBkcm1fY2xpcF9yZWN0 X2lzX2VtcHR5KHN0cnVjdCBkcm1fY2xpcF9yZWN0ICpjbGlwKQo+Pj4+ICt7Cj4+Pj4gKwlyZXR1 cm4gKCFjbGlwLT54MSAmJiAhY2xpcC0+eDIgJiYgIWNsaXAtPnkxICYmICFjbGlwLT55Mik7Cj4+ Pj4gK30KPj4+PiArCj4+Pj4gK2Jvb2wgZHJtX2NsaXBfcmVjdF9pbnRlcnNlY3Qoc3RydWN0IGRy bV9jbGlwX3JlY3QgKnIxLAo+Pj4+ICsJCQkgICAgIGNvbnN0IHN0cnVjdCBkcm1fY2xpcF9yZWN0 ICpyMik7Cj4+Pj4gK3ZvaWQgZHJtX2NsaXBfcmVjdF9tZXJnZShzdHJ1Y3QgZHJtX2NsaXBfcmVj dCAqZHN0LAo+Pj4+ICsJCQkgc3RydWN0IGRybV9jbGlwX3JlY3QgKnNyYywgdW5zaWduZWQgbnVt X2NsaXBzLAo+Pj4+ICsJCQkgdW5zaWduZWQgZmxhZ3MsIHUzMiB3aWR0aCwgdTMyIGhlaWdodCk7 Cj4+Pj4gKwo+Pj4+ICAgICNlbmRpZgo+Pj4+IC0tIAo+Pj4+IDIuMi4yCj4+Pj4KPj4+PiBfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwo+Pj4+IGRyaS1kZXZl bCBtYWlsaW5nIGxpc3QKPj4+PiBkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCj4+Pj4g aHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZl bCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xp c3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=