From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC7B463CB; Sun, 19 Jan 2025 20:14:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737317693; cv=none; b=ma1OMiPABaOMbW9ff61W4uCkEuOt39jkx3DYEJkHC2uDhNoD719NYD/u4e/deEBCbO5k/phyzP7AX1RwZ07hSBt0Yx7cXo6Tx9qVEyK8dyNPMLBukhOiVaDApf2hj0gFuiwvWy+sQ4uGVvAyUfYjEjco3hd0zeM8Dc1QKmX85II= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737317693; c=relaxed/simple; bh=Ur5TiuDT0KV1E3ES7k+/3Zr4hEwwAAPuNmpmijHxcE0=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=NVjmHumvIgxD7H9NEqBb5B4HzCW2alfRrByajWOEyiEimxc6sOu9lxXnezJLj30GVutjRtoNhb7HGHTodDKev5g7ynLdrFq3a850HlsL9z+xFPRR1fVvb/Vg49T4F6ZmgImSfX6SdDmZdtbStCU4TqWF6Jo9cg40obvFj73kywM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=SS+99s7t; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SS+99s7t" Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 85456928; Sun, 19 Jan 2025 21:13:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1737317628; bh=Ur5TiuDT0KV1E3ES7k+/3Zr4hEwwAAPuNmpmijHxcE0=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=SS+99s7tpuo+gPcxMER5jdDaof5TicjCpzG4c3b8L9QjuYGIwEIGNxOpvhm9TbJ1K WDQ8UU3Os41Ewzy+4kV7y7CeQXv55XGw/jZbTqWOQI9B6aQfo6jbIU+WwUmbNEjidS k9ILi43LKurT0oL3MNbHe4TD8sUVaA21oTrP0eCY= Date: Sun, 19 Jan 2025 22:14:43 +0200 From: Laurent Pinchart To: Sui Jingfeng Cc: Tomi Valkeinen , Dmitry Baryshkov , Geert Uytterhoeven , Thomas Zimmermann , maarten.lankhorst@linux.intel.com, mripard@kernel.org, airlied@gmail.com, simona@ffwll.ch, dri-devel@lists.freedesktop.org, linux-mediatek@lists.infradead.org, freedreno@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, imx@lists.linux.dev, linux-samsung-soc@vger.kernel.org, nouveau@lists.freedesktop.org, virtualization@lists.linux.dev, spice-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-tegra@vger.kernel.org, intel-xe@lists.freedesktop.org, xen-devel@lists.xenproject.org, Andy Yan , Daniel Stone Subject: Re: [PATCH v2 25/25] drm/xlnx: Compute dumb-buffer sizes with drm_mode_size_dumb() Message-ID: <20250119201443.GB2467@pendragon.ideasonboard.com> References: <8234927e-0d12-4655-813d-8ec94179b737@linux.dev> Precedence: bulk X-Mailing-List: imx@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <8234927e-0d12-4655-813d-8ec94179b737@linux.dev> On Mon, Jan 20, 2025 at 12:26:30AM +0800, Sui Jingfeng wrote: > On 2025/1/19 23:22, Tomi Valkeinen wrote: > > On 19/01/2025 16:59, Sui Jingfeng wrote: > > > >>>>> But userspace must be able to continue allocating YUV buffers through > >>>>> CREATE_DUMB. > >>>> > >>>> I think, allocating YUV buffers through CREATE_DUMB interface is just > >>>> an *abuse* and *misuse* of this API for now. > >>>> > >>>> Take the NV12 format as an example, NV12 is YUV420 planar format, have > >>>> two planar: the Y-planar and the UV-planar. The Y-planar appear first > >>>> in memory as an array of unsigned char values. The Y-planar is followed > >>>> immediately by the UV-planar, which is also an array of unsigned char > >>>> values that contains packed U (Cb) and V (Cr) samples. > >>>> > >>>> But the 'drm_mode_create_dumb' structure is only intend to provide > >>>> descriptions for *one* planar. > >>>> > >>>> struct drm_mode_create_dumb { > >>>>      __u32 height; > >>>>      __u32 width; > >>>>      __u32 bpp; > >>>>      __u32 flags; > >>>>      __u32 handle; > >>>>      __u32 pitch; > >>>>      __u64 size; > >>>> }; > >>>> > >>>> An width x height NV12 image takes up width*height*(1 + 1/4 + 1/4) > >>>> bytes. > >>>> > >>>> So we can allocate an *equivalent* sized buffer to store the NV12 > >>>> raw data. > >>>> > >>>> Either 'width * (height * 3/2)' where each pixel take up 8 bits, > >>>> or just 'with * height' where each pixels take up 12 bits. > >>>> > >>>> However, all those math are just equivalents description to the original > >>>> NV12 format, neither are concrete correct physical description. > >>> > >>> I don't see the problem. Allocating dumb buffers, if we don't have > >>> any heuristics related to RGB behind it, is essentially just > >>> allocating a specific amount of memory, defined by width, height and > >>> bitsperpixel. > >>> > >> I think, the problem will be that the 'width', 'height' and 'bpp' > >> are originally used to describe one plane. Those three parameters > >> has perfectly defined physical semantics. > >> > >> But with multi planar formats, take NV12 image as an example, > >> for a 2×2 square of pixels, there are 4 Y samples but only 1 U > >> sample and 1 V sample. This format requires 4x8+1x8+1x8=48 bits > >> to store the 2x2 square. > >> > >> So its depth is 12 bits per pixel (48 / (2 * 2)). > >> > >> so my problem is that the mentioned 12bpp in this example only > >> make sense in mathematics, it doesn't has a good physical > >> interpret. Do you agree with me on this technique point? > >> > >>> If I want to create an NV12 framebuffer, I allocate two dumb > >>> buffers, one for Y and one for UV planes, and size them accordingly. > >>> And then create the DRM framebuffer with those. > >>> > >> Then how you fill the value of the 'width', 'height' and 'bpp' of > >> each dumb buffers? > > > > For 640x480-NV12: > > plane 0: width = 640, height = 480, bpp = 8 > > plane 1: width = 640 / 2, height = 480 / 2, bpp = 16 > > But i think this should be hardware dependent. The hardware I'm using > load NV12 raw data as a whole. I only need to feed gpuva of the backing > memory to the hardware register once. > > Not familiar with your hardware, so I can't talk more on this software > design. Perhaps someone know more could have a comment on this. Layout of planes in memory is just one hardware constraint, the same way we have constraints on alignment and strides. Some devices require the planes to be contiguous (likely with some alignment constraints), some can work with planes being in discontiguous pieces of memory, and even require them to be discontiguous and located in separate DRAM banks. > >> Why not allocate storage for the whole on one shoot? > > > > You can, if you adjust the parameters accordingly. However, if the > > strides of the planes are not equal, I guess it might cause problems > > on some platforms. > > > > But I think it's usually simpler to allocate one buffer per plane, and > > perhaps even better as it doesn't require as large contiguous memory > > area. > > > >> The modetest in libdrm can be an good example, send it[1] to you as > >> an reference. > > > > Right, so modetest already does it successfully. So... What is the issue? > > But then, the problem will become that it override the 'height' parameter. > What's the physical interpretation of the 'height' parameter when creating > an NV12 image with the dump API then? I wouldn't be too concerned about physical interpretations. Yes, the height, width and bpp parameters were likely designed with RGB formats in mind. Yes, using DUMB_CREATE for YUV formats is probably something that the original authors didn't envision. And yes, from that point of view, it could be seen by the original authors as an abuse of the API. But I don't think that's a problem as such. An API is just an API. True, it would be nicer if the usage of the ioctl parameters was more intuitive for YUV formats, but I believe we could still standardize how the existing parameters map to linear scanout YUV formats without causing the world to end. As has been said before, lots of drivers are using DUMB_CREATE for this purpose, and we can't change that. This doesn't mean we shouldn't work on improving memory allocation, but I see that as a separate issue. > I guess, solving complex problems with simple APIs may see the limitation, > sooner or later. But I not very sure and might be wrong. So other peoples > can override me words. > > > Everyone agrees that CREATE_DUMB is not the best ioctl to allocate > > buffers, and one can't consider it to work identically across the > > platforms. But it's what we have and what has been used for ages. > > Yeah, your request are not unreasonable. It can be seen as a kind of rigid demand. > Since GEM DMA helpers doesn't export an more advanced interface to userspace so far. > As a result, drivers that employing GEM DMA has no other choice, but to abuse the > dumb buffer API to do allocation for the more complex format buffers. > > The dumb buffer API doesn't support to specify buffer format, tile status and > placement etc. The more advance drivers has been exposed the xxx_create_gem() > to user-space. It seems that a few more experienced programmers hint us to > create an new ioctl at above thread, so that we can keep employing simple API > to do simple things and to suit complex needs with the more advanced APIs. I'd really like to explore adding new ioctls to exposure memory allocation constraints, and allocating the memory itself from DMA heaps. -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1B1F3C02188 for ; Sun, 19 Jan 2025 20:15:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=A5WwTxWKJtUGwDNL2YoeTdvbEEWbKsBnipf/z0ky3Hw=; b=hAJar1uXqYNObd sYJGGePV4fV2EomsM1XPEaEZtQ/2WPkp6xdKkizZHUSPehOPf99GzzHIABXUp3fkbuXReZZYxNnSh II75pWql3DzhqnkPJYNptpdixHCdEGW5Eidz04DzArhPL6fmHNWZ2L0oLqTk90qqoGcTme+YI8L0X mMuzNm+PKJ4KUbHO6J+LKcLQYbFjsU8lIOWEha90ZXa2EtTyGoOW1zbtvmYM1txCU1NOO8EnFih4F +FPN4xDIlUJYycyW2nEkkj2Vd4uC+TyLPFWYD+tADzO826VZMDxjfut6t2VwfFUPvxYlT5StqgOEf cMAmilUQll0QcKwNz9/g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tZbh9-00000004J2i-1vWo; Sun, 19 Jan 2025 20:14:55 +0000 Received: from perceval.ideasonboard.com ([213.167.242.64]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tZbh6-00000004J1H-1ugn; Sun, 19 Jan 2025 20:14:53 +0000 Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 85456928; Sun, 19 Jan 2025 21:13:48 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1737317628; bh=Ur5TiuDT0KV1E3ES7k+/3Zr4hEwwAAPuNmpmijHxcE0=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=SS+99s7tpuo+gPcxMER5jdDaof5TicjCpzG4c3b8L9QjuYGIwEIGNxOpvhm9TbJ1K WDQ8UU3Os41Ewzy+4kV7y7CeQXv55XGw/jZbTqWOQI9B6aQfo6jbIU+WwUmbNEjidS k9ILi43LKurT0oL3MNbHe4TD8sUVaA21oTrP0eCY= Date: Sun, 19 Jan 2025 22:14:43 +0200 From: Laurent Pinchart To: Sui Jingfeng Cc: Tomi Valkeinen , Dmitry Baryshkov , Geert Uytterhoeven , Thomas Zimmermann , maarten.lankhorst@linux.intel.com, mripard@kernel.org, airlied@gmail.com, simona@ffwll.ch, dri-devel@lists.freedesktop.org, linux-mediatek@lists.infradead.org, freedreno@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, imx@lists.linux.dev, linux-samsung-soc@vger.kernel.org, nouveau@lists.freedesktop.org, virtualization@lists.linux.dev, spice-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-tegra@vger.kernel.org, intel-xe@lists.freedesktop.org, xen-devel@lists.xenproject.org, Andy Yan , Daniel Stone Subject: Re: [PATCH v2 25/25] drm/xlnx: Compute dumb-buffer sizes with drm_mode_size_dumb() Message-ID: <20250119201443.GB2467@pendragon.ideasonboard.com> References: <8234927e-0d12-4655-813d-8ec94179b737@linux.dev> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <8234927e-0d12-4655-813d-8ec94179b737@linux.dev> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250119_121452_655237_91E71544 X-CRM114-Status: GOOD ( 44.52 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org T24gTW9uLCBKYW4gMjAsIDIwMjUgYXQgMTI6MjY6MzBBTSArMDgwMCwgU3VpIEppbmdmZW5nIHdy b3RlOgo+IE9uIDIwMjUvMS8xOSAyMzoyMiwgVG9taSBWYWxrZWluZW4gd3JvdGU6Cj4gPiBPbiAx OS8wMS8yMDI1IDE2OjU5LCBTdWkgSmluZ2Zlbmcgd3JvdGU6Cj4gPgo+ID4+Pj4+IEJ1dCB1c2Vy c3BhY2UgbXVzdCBiZSBhYmxlIHRvIGNvbnRpbnVlIGFsbG9jYXRpbmcgWVVWIGJ1ZmZlcnMgdGhy b3VnaAo+ID4+Pj4+IENSRUFURV9EVU1CLgo+ID4+Pj4KPiA+Pj4+IEkgdGhpbmssIGFsbG9jYXRp bmcgWVVWIGJ1ZmZlcnMgdGhyb3VnaCBDUkVBVEVfRFVNQiBpbnRlcmZhY2UgaXMganVzdAo+ID4+ Pj4gYW4gKmFidXNlKiBhbmQgKm1pc3VzZSogb2YgdGhpcyBBUEkgZm9yIG5vdy4KPiA+Pj4+Cj4g Pj4+PiBUYWtlIHRoZSBOVjEyIGZvcm1hdCBhcyBhbiBleGFtcGxlLCBOVjEyIGlzIFlVVjQyMCBw bGFuYXIgZm9ybWF0LCBoYXZlCj4gPj4+PiB0d28gcGxhbmFyOiB0aGUgWS1wbGFuYXIgYW5kIHRo ZSBVVi1wbGFuYXIuIFRoZSBZLXBsYW5hciBhcHBlYXIgZmlyc3QKPiA+Pj4+IGluIG1lbW9yeSBh cyBhbiBhcnJheSBvZiB1bnNpZ25lZCBjaGFyIHZhbHVlcy4gVGhlIFktcGxhbmFyIGlzIGZvbGxv d2VkCj4gPj4+PiBpbW1lZGlhdGVseSBieSB0aGUgVVYtcGxhbmFyLCB3aGljaCBpcyBhbHNvIGFu IGFycmF5IG9mIHVuc2lnbmVkIGNoYXIKPiA+Pj4+IHZhbHVlcyB0aGF0IGNvbnRhaW5zIHBhY2tl ZCBVIChDYikgYW5kIFYgKENyKSBzYW1wbGVzLgo+ID4+Pj4KPiA+Pj4+IEJ1dCB0aGUgJ2RybV9t b2RlX2NyZWF0ZV9kdW1iJyBzdHJ1Y3R1cmUgaXMgb25seSBpbnRlbmQgdG8gcHJvdmlkZQo+ID4+ Pj4gZGVzY3JpcHRpb25zIGZvciAqb25lKiBwbGFuYXIuCj4gPj4+Pgo+ID4+Pj4gc3RydWN0IGRy bV9tb2RlX2NyZWF0ZV9kdW1iIHsKPiA+Pj4+IMKgwqDCoMKgIF9fdTMyIGhlaWdodDsKPiA+Pj4+ IMKgwqDCoMKgIF9fdTMyIHdpZHRoOwo+ID4+Pj4gwqDCoMKgwqAgX191MzIgYnBwOwo+ID4+Pj4g wqDCoMKgwqAgX191MzIgZmxhZ3M7Cj4gPj4+PiDCoMKgwqDCoCBfX3UzMiBoYW5kbGU7Cj4gPj4+ PiDCoMKgwqDCoCBfX3UzMiBwaXRjaDsKPiA+Pj4+IMKgwqDCoMKgIF9fdTY0IHNpemU7Cj4gPj4+ PiB9Owo+ID4+Pj4KPiA+Pj4+IEFuIHdpZHRoIHggaGVpZ2h0IE5WMTIgaW1hZ2UgdGFrZXMgdXAg d2lkdGgqaGVpZ2h0KigxICsgMS80ICsgMS80KSAKPiA+Pj4+IGJ5dGVzLgo+ID4+Pj4KPiA+Pj4+ IFNvIHdlIGNhbiBhbGxvY2F0ZSBhbiAqZXF1aXZhbGVudCogc2l6ZWQgYnVmZmVyIHRvIHN0b3Jl IHRoZSBOVjEyIAo+ID4+Pj4gcmF3IGRhdGEuCj4gPj4+Pgo+ID4+Pj4gRWl0aGVyICd3aWR0aCAq IChoZWlnaHQgKiAzLzIpJyB3aGVyZSBlYWNoIHBpeGVsIHRha2UgdXAgOCBiaXRzLAo+ID4+Pj4g b3IganVzdCAnd2l0aCAqIGhlaWdodCcgd2hlcmUgZWFjaCBwaXhlbHMgdGFrZSB1cCAxMiBiaXRz Lgo+ID4+Pj4KPiA+Pj4+IEhvd2V2ZXIsIGFsbCB0aG9zZSBtYXRoIGFyZSBqdXN0IGVxdWl2YWxl bnRzIGRlc2NyaXB0aW9uIHRvIHRoZSBvcmlnaW5hbAo+ID4+Pj4gTlYxMiBmb3JtYXQsIG5laXRo ZXIgYXJlIGNvbmNyZXRlIGNvcnJlY3QgcGh5c2ljYWwgZGVzY3JpcHRpb24uCj4gPj4+Cj4gPj4+ IEkgZG9uJ3Qgc2VlIHRoZSBwcm9ibGVtLiBBbGxvY2F0aW5nIGR1bWIgYnVmZmVycywgaWYgd2Ug ZG9uJ3QgaGF2ZSAKPiA+Pj4gYW55IGhldXJpc3RpY3MgcmVsYXRlZCB0byBSR0IgYmVoaW5kIGl0 LCBpcyBlc3NlbnRpYWxseSBqdXN0IAo+ID4+PiBhbGxvY2F0aW5nIGEgc3BlY2lmaWMgYW1vdW50 IG9mIG1lbW9yeSwgZGVmaW5lZCBieSB3aWR0aCwgaGVpZ2h0IGFuZCAKPiA+Pj4gYml0c3BlcnBp eGVsLgo+ID4+Pgo+ID4+IEkgdGhpbmssIHRoZSBwcm9ibGVtIHdpbGwgYmUgdGhhdCB0aGUgJ3dp ZHRoJywgJ2hlaWdodCcgYW5kICdicHAnCj4gPj4gYXJlIG9yaWdpbmFsbHkgdXNlZCB0byBkZXNj cmliZSBvbmUgcGxhbmUuIFRob3NlIHRocmVlIHBhcmFtZXRlcnMKPiA+PiBoYXMgcGVyZmVjdGx5 IGRlZmluZWQgcGh5c2ljYWwgc2VtYW50aWNzLgo+ID4+Cj4gPj4gQnV0IHdpdGggbXVsdGkgcGxh bmFyIGZvcm1hdHMsIHRha2UgTlYxMiBpbWFnZSBhcyBhbiBleGFtcGxlLAo+ID4+IGZvciBhIDLD lzIgc3F1YXJlIG9mIHBpeGVscywgdGhlcmUgYXJlIDQgWSBzYW1wbGVzIGJ1dCBvbmx5IDEgVQo+ ID4+IHNhbXBsZSBhbmQgMSBWIHNhbXBsZS4gVGhpcyBmb3JtYXQgcmVxdWlyZXMgNHg4KzF4OCsx eDg9NDggYml0cwo+ID4+IHRvIHN0b3JlIHRoZSAyeDIgc3F1YXJlLgo+ID4+Cj4gPj4gU28gaXRz IGRlcHRoIGlzIDEyIGJpdHMgcGVyIHBpeGVsICg0OCAvICgyICogMikpLgo+ID4+Cj4gPj4gc28g bXkgcHJvYmxlbSBpcyB0aGF0IHRoZSBtZW50aW9uZWQgMTJicHAgaW4gdGhpcyBleGFtcGxlIG9u bHkKPiA+PiBtYWtlIHNlbnNlIGluIG1hdGhlbWF0aWNzLCBpdCBkb2Vzbid0IGhhcyBhIGdvb2Qg cGh5c2ljYWwKPiA+PiBpbnRlcnByZXQuIERvIHlvdSBhZ3JlZSB3aXRoIG1lIG9uIHRoaXMgdGVj aG5pcXVlIHBvaW50Pwo+ID4+Cj4gPj4+IElmIEkgd2FudCB0byBjcmVhdGUgYW4gTlYxMiBmcmFt ZWJ1ZmZlciwgSSBhbGxvY2F0ZSB0d28gZHVtYiAKPiA+Pj4gYnVmZmVycywgb25lIGZvciBZIGFu ZCBvbmUgZm9yIFVWIHBsYW5lcywgYW5kIHNpemUgdGhlbSBhY2NvcmRpbmdseS4gCj4gPj4+IEFu ZCB0aGVuIGNyZWF0ZSB0aGUgRFJNIGZyYW1lYnVmZmVyIHdpdGggdGhvc2UuCj4gPj4+Cj4gPj4g VGhlbiBob3cgeW91IGZpbGwgdGhlIHZhbHVlIG9mIHRoZSAnd2lkdGgnLCAnaGVpZ2h0JyBhbmQg J2JwcCcgb2YgCj4gPj4gZWFjaCBkdW1iIGJ1ZmZlcnM/Cj4gPgo+ID4gRm9yIDY0MHg0ODAtTlYx MjoKPiA+IHBsYW5lIDA6IHdpZHRoID0gNjQwLCBoZWlnaHQgPSA0ODAsIGJwcCA9IDgKPiA+IHBs YW5lIDE6IHdpZHRoID0gNjQwIC8gMiwgaGVpZ2h0ID0gNDgwIC8gMiwgYnBwID0gMTYKPgo+IEJ1 dCBpIHRoaW5rIHRoaXMgc2hvdWxkIGJlIGhhcmR3YXJlIGRlcGVuZGVudC4gVGhlIGhhcmR3YXJl IEknbSB1c2luZwo+IGxvYWQgTlYxMiAgcmF3IGRhdGEgYXMgYSB3aG9sZS4gSSBvbmx5IG5lZWQg dG8gZmVlZCBncHV2YSBvZiB0aGUgYmFja2luZwo+IG1lbW9yeSB0byB0aGUgaGFyZHdhcmUgcmVn aXN0ZXIgb25jZS4KPiAKPiBOb3QgZmFtaWxpYXIgd2l0aCB5b3VyIGhhcmR3YXJlLCBzbyBJIGNh bid0IHRhbGsgbW9yZSBvbiB0aGlzIHNvZnR3YXJlCj4gZGVzaWduLiBQZXJoYXBzIHNvbWVvbmUg a25vdyBtb3JlIGNvdWxkIGhhdmUgYSBjb21tZW50IG9uIHRoaXMuCgpMYXlvdXQgb2YgcGxhbmVz IGluIG1lbW9yeSBpcyBqdXN0IG9uZSBoYXJkd2FyZSBjb25zdHJhaW50LCB0aGUgc2FtZSB3YXkK d2UgaGF2ZSBjb25zdHJhaW50cyBvbiBhbGlnbm1lbnQgYW5kIHN0cmlkZXMuIFNvbWUgZGV2aWNl cyByZXF1aXJlIHRoZQpwbGFuZXMgdG8gYmUgY29udGlndW91cyAobGlrZWx5IHdpdGggc29tZSBh bGlnbm1lbnQgY29uc3RyYWludHMpLCBzb21lCmNhbiB3b3JrIHdpdGggcGxhbmVzIGJlaW5nIGlu IGRpc2NvbnRpZ3VvdXMgcGllY2VzIG9mIG1lbW9yeSwgYW5kIGV2ZW4KcmVxdWlyZSB0aGVtIHRv IGJlIGRpc2NvbnRpZ3VvdXMgYW5kIGxvY2F0ZWQgaW4gc2VwYXJhdGUgRFJBTSBiYW5rcy4KCj4g Pj4gV2h5IG5vdCBhbGxvY2F0ZSBzdG9yYWdlIGZvciB0aGUgd2hvbGUgb24gb25lIHNob290Pwo+ ID4KPiA+IFlvdSBjYW4sIGlmIHlvdSBhZGp1c3QgdGhlIHBhcmFtZXRlcnMgYWNjb3JkaW5nbHku IEhvd2V2ZXIsIGlmIHRoZSAKPiA+IHN0cmlkZXMgb2YgdGhlIHBsYW5lcyBhcmUgbm90IGVxdWFs LCBJIGd1ZXNzIGl0IG1pZ2h0IGNhdXNlIHByb2JsZW1zIAo+ID4gb24gc29tZSBwbGF0Zm9ybXMu Cj4gPgo+ID4gQnV0IEkgdGhpbmsgaXQncyB1c3VhbGx5IHNpbXBsZXIgdG8gYWxsb2NhdGUgb25l IGJ1ZmZlciBwZXIgcGxhbmUsIGFuZCAKPiA+IHBlcmhhcHMgZXZlbiBiZXR0ZXIgYXMgaXQgZG9l c24ndCByZXF1aXJlIGFzIGxhcmdlIGNvbnRpZ3VvdXMgbWVtb3J5IAo+ID4gYXJlYS4KPiA+Cj4g Pj4gVGhlIG1vZGV0ZXN0IGluIGxpYmRybSBjYW4gYmUgYW4gZ29vZCBleGFtcGxlLCBzZW5kIGl0 WzFdIHRvIHlvdSBhcyAKPiA+PiBhbiByZWZlcmVuY2UuCj4gPgo+ID4gUmlnaHQsIHNvIG1vZGV0 ZXN0IGFscmVhZHkgZG9lcyBpdCBzdWNjZXNzZnVsbHkuIFNvLi4uIFdoYXQgaXMgdGhlIGlzc3Vl Pwo+Cj4gQnV0IHRoZW4sIHRoZSBwcm9ibGVtIHdpbGwgYmVjb21lIHRoYXQgaXQgb3ZlcnJpZGUg dGhlICdoZWlnaHQnIHBhcmFtZXRlci4KPiBXaGF0J3MgdGhlIHBoeXNpY2FsIGludGVycHJldGF0 aW9uIG9mIHRoZSAnaGVpZ2h0JyBwYXJhbWV0ZXIgd2hlbiBjcmVhdGluZwo+IGFuIE5WMTIgaW1h Z2Ugd2l0aCB0aGUgZHVtcCBBUEkgdGhlbj8KCkkgd291bGRuJ3QgYmUgdG9vIGNvbmNlcm5lZCBh Ym91dCBwaHlzaWNhbCBpbnRlcnByZXRhdGlvbnMuIFllcywgdGhlCmhlaWdodCwgd2lkdGggYW5k IGJwcCBwYXJhbWV0ZXJzIHdlcmUgbGlrZWx5IGRlc2lnbmVkIHdpdGggUkdCIGZvcm1hdHMKaW4g bWluZC4gWWVzLCB1c2luZyBEVU1CX0NSRUFURSBmb3IgWVVWIGZvcm1hdHMgaXMgcHJvYmFibHkg c29tZXRoaW5nCnRoYXQgdGhlIG9yaWdpbmFsIGF1dGhvcnMgZGlkbid0IGVudmlzaW9uLiBBbmQg eWVzLCBmcm9tIHRoYXQgcG9pbnQgb2YKdmlldywgaXQgY291bGQgYmUgc2VlbiBieSB0aGUgb3Jp Z2luYWwgYXV0aG9ycyBhcyBhbiBhYnVzZSBvZiB0aGUgQVBJLgpCdXQgSSBkb24ndCB0aGluayB0 aGF0J3MgYSBwcm9ibGVtIGFzIHN1Y2guCgpBbiBBUEkgaXMganVzdCBhbiBBUEkuIFRydWUsIGl0 IHdvdWxkIGJlIG5pY2VyIGlmIHRoZSB1c2FnZSBvZiB0aGUgaW9jdGwKcGFyYW1ldGVycyB3YXMg bW9yZSBpbnR1aXRpdmUgZm9yIFlVViBmb3JtYXRzLCBidXQgSSBiZWxpZXZlIHdlIGNvdWxkCnN0 aWxsIHN0YW5kYXJkaXplIGhvdyB0aGUgZXhpc3RpbmcgcGFyYW1ldGVycyBtYXAgdG8gbGluZWFy IHNjYW5vdXQgWVVWCmZvcm1hdHMgd2l0aG91dCBjYXVzaW5nIHRoZSB3b3JsZCB0byBlbmQuIEFz IGhhcyBiZWVuIHNhaWQgYmVmb3JlLCBsb3RzCm9mIGRyaXZlcnMgYXJlIHVzaW5nIERVTUJfQ1JF QVRFIGZvciB0aGlzIHB1cnBvc2UsIGFuZCB3ZSBjYW4ndCBjaGFuZ2UKdGhhdC4KClRoaXMgZG9l c24ndCBtZWFuIHdlIHNob3VsZG4ndCB3b3JrIG9uIGltcHJvdmluZyBtZW1vcnkgYWxsb2NhdGlv biwgYnV0Ckkgc2VlIHRoYXQgYXMgYSBzZXBhcmF0ZSBpc3N1ZS4KCj4gSSBndWVzcywgc29sdmlu ZyBjb21wbGV4IHByb2JsZW1zIHdpdGggc2ltcGxlIEFQSXMgbWF5IHNlZSB0aGUgbGltaXRhdGlv biwKPiBzb29uZXIgb3IgbGF0ZXIuIEJ1dCBJIG5vdCB2ZXJ5IHN1cmUgYW5kIG1pZ2h0IGJlIHdy b25nLiBTbyBvdGhlciBwZW9wbGVzCj4gY2FuIG92ZXJyaWRlIG1lIHdvcmRzLgo+IAo+ID4gRXZl cnlvbmUgYWdyZWVzIHRoYXQgQ1JFQVRFX0RVTUIgaXMgbm90IHRoZSBiZXN0IGlvY3RsIHRvIGFs bG9jYXRlIAo+ID4gYnVmZmVycywgYW5kIG9uZSBjYW4ndCBjb25zaWRlciBpdCB0byB3b3JrIGlk ZW50aWNhbGx5IGFjcm9zcyB0aGUgCj4gPiBwbGF0Zm9ybXMuIEJ1dCBpdCdzIHdoYXQgd2UgaGF2 ZSBhbmQgd2hhdCBoYXMgYmVlbiB1c2VkIGZvciBhZ2VzLgo+Cj4gWWVhaCwgeW91ciByZXF1ZXN0 IGFyZSBub3QgdW5yZWFzb25hYmxlLiBJdCBjYW4gYmUgc2VlbiBhcyBhIGtpbmQgb2YgcmlnaWQg ZGVtYW5kLgo+IFNpbmNlIEdFTSBETUEgaGVscGVycyBkb2Vzbid0IGV4cG9ydCBhbiBtb3JlIGFk dmFuY2VkIGludGVyZmFjZSB0byB1c2Vyc3BhY2Ugc28gZmFyLgo+IEFzIGEgcmVzdWx0LCBkcml2 ZXJzIHRoYXQgZW1wbG95aW5nIEdFTSBETUEgaGFzIG5vIG90aGVyIGNob2ljZSwgYnV0IHRvIGFi dXNlIHRoZQo+IGR1bWIgYnVmZmVyIEFQSSB0byBkbyBhbGxvY2F0aW9uIGZvciB0aGUgbW9yZSBj b21wbGV4IGZvcm1hdCBidWZmZXJzLgo+IAo+IFRoZSBkdW1iIGJ1ZmZlciBBUEkgZG9lc24ndCBz dXBwb3J0IHRvIHNwZWNpZnkgYnVmZmVyIGZvcm1hdCwgdGlsZSBzdGF0dXMgYW5kCj4gcGxhY2Vt ZW50IGV0Yy4gVGhlIG1vcmUgYWR2YW5jZSBkcml2ZXJzIGhhcyBiZWVuIGV4cG9zZWQgdGhlIHh4 eF9jcmVhdGVfZ2VtKCkKPiB0byB1c2VyLXNwYWNlLiBJdCBzZWVtcyB0aGF0IGEgZmV3IG1vcmUg ZXhwZXJpZW5jZWQgcHJvZ3JhbW1lcnMgaGludCB1cyB0bwo+IGNyZWF0ZSBhbiBuZXcgaW9jdGwg YXQgYWJvdmUgdGhyZWFkLCBzbyB0aGF0IHdlIGNhbiBrZWVwIGVtcGxveWluZyBzaW1wbGUgQVBJ Cj4gdG8gZG8gc2ltcGxlIHRoaW5ncyBhbmQgdG8gc3VpdCBjb21wbGV4IG5lZWRzIHdpdGggdGhl IG1vcmUgYWR2YW5jZWQgQVBJcy4KCkknZCByZWFsbHkgbGlrZSB0byBleHBsb3JlIGFkZGluZyBu ZXcgaW9jdGxzIHRvIGV4cG9zdXJlIG1lbW9yeQphbGxvY2F0aW9uIGNvbnN0cmFpbnRzLCBhbmQg YWxsb2NhdGluZyB0aGUgbWVtb3J5IGl0c2VsZiBmcm9tIERNQSBoZWFwcy4KCi0tIApSZWdhcmRz LAoKTGF1cmVudCBQaW5jaGFydAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX18KTGludXgtcm9ja2NoaXAgbWFpbGluZyBsaXN0CkxpbnV4LXJvY2tjaGlwQGxp c3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0 aW5mby9saW51eC1yb2NrY2hpcAo=