From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-180.mta0.migadu.com (out-180.mta0.migadu.com [91.218.175.180]) (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 94CB435968 for ; Mon, 20 Jan 2025 07:05:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.180 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737356714; cv=none; b=nOH3N9ZWK4vGcfNEZkA82ULgqIH+Qcvu7RolIa426+i180V+xXxaDx9Wv+l1oQLpDYy08pCiI3s8HV+mHQVmSyP88Fiqntinqm6gSV31V8fVw2bqaWezNN/uwPPfg9QyYNNcU0lhNgv1PHKOLgSlsauvdfff2bTD7DHopxfLjSA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737356714; c=relaxed/simple; bh=YHwhOhlln+ZBW4bsRMLXZlhX9KD0bxvWtNvYlkSCv3s=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=HwKd0vUifzDbIB1ZcP8a0KDs+zlRv4t1hNBWN+mZEaTfksZPzmbOZE+0wfrLu+nLLfVpBrfoLIoY9mQ8DJBQXLiPAoZhRO52XzjqVNDYA9kAd+p/x3JYcu8LKPxFPPUisfsNYhD9CejQb6bg4bkW5b0cL8cNQJnLCgRu5E0vSGE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=H42Z2l+U; arc=none smtp.client-ip=91.218.175.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="H42Z2l+U" Message-ID: <84adda72-24c1-428d-9c55-8bb9ec189584@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1737356708; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s4k8B9SqdOW/b4nXIri28MHaonby69L1MPYqhyNKUX0=; b=H42Z2l+UXNpZWYWEmHERkXyThqLsthOt2Tl1gQlgH7BXsUNxeI/rr3PfiugdYdU7zHqpvq dLqd9siDrRP2RNM9ARbxgV6zGEqcH+5CdCKOZz1TBdC0GDysb1JYpX1OOzaYOnjlwgwB22 siLOW8pFM6wtm6a+laFnQN1GQRPRQXE= Date: Mon, 20 Jan 2025 15:04:56 +0800 Precedence: bulk X-Mailing-List: imx@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: Re: [PATCH v2 25/25] drm/xlnx: Compute dumb-buffer sizes with drm_mode_size_dumb() To: Laurent Pinchart 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 References: <8234927e-0d12-4655-813d-8ec94179b737@linux.dev> <20250119201443.GB2467@pendragon.ideasonboard.com> Content-Language: en-US X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng In-Reply-To: <20250119201443.GB2467@pendragon.ideasonboard.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT Hi, On 2025/1/20 04:14, Laurent Pinchart wrote: > 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. Right. >>>> 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. Sometimes there may have 2D GPU or Image Process Unit get involved. Setting the dimension, the clip window and pitch etc parameters to the hardware are needed. The value of bpp affects pitch, bigger pitch may cause the hardware load more bytes than it should on one line. While the 'height' may affect the size of the clip window, depend on the calculation method. But I have no strong opinion toward with this and agree with you in overall. > 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. > -- Best regards, Sui 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 536D1C02188 for ; Mon, 20 Jan 2025 07:05:32 +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-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:From:References:Cc:To:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=MkiK9A6p94SqRCVFxbh6be4MqfIONzhGp0mh4aLciME=; b=A2rgMeFgk10aLY F7Avlp7y/SMjQ4yQfS9MtK919KSJIiAOfJFuz2Bw9HZR8rQOuMzqH6DqTdDei9v+cWqVM8Ag8CSEO ysFi2bvQDv4KfAIBeZlRxj2P7BVzDgqS+HY96sRGUO+YOp5K3fkl+e5mDe+a9vWNbLazjnEuxzp6d A4wjTjyCVF3PvWn8GjHdeeB1bp4P0lFY7TNKqjCtP636eiUyJoaw3pdSqJUnUMZ7DvmupOL4ZL6bD /xYT3Dqr1x+itI08MjjmOBJHtVYIDlzrF6rYkwE66HW1PTZ3ymWCNKTzvmv2ZM1orrv45sjQ117Dl 5hxlQtic8EpveN/M+DhA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tZlqd-00000004sKR-0CHV; Mon, 20 Jan 2025 07:05:23 +0000 Received: from out-188.mta0.migadu.com ([2001:41d0:1004:224b::bc]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tZlqa-00000004sJ6-3Lp2 for linux-rockchip@lists.infradead.org; Mon, 20 Jan 2025 07:05:22 +0000 Message-ID: <84adda72-24c1-428d-9c55-8bb9ec189584@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1737356708; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s4k8B9SqdOW/b4nXIri28MHaonby69L1MPYqhyNKUX0=; b=H42Z2l+UXNpZWYWEmHERkXyThqLsthOt2Tl1gQlgH7BXsUNxeI/rr3PfiugdYdU7zHqpvq dLqd9siDrRP2RNM9ARbxgV6zGEqcH+5CdCKOZz1TBdC0GDysb1JYpX1OOzaYOnjlwgwB22 siLOW8pFM6wtm6a+laFnQN1GQRPRQXE= Date: Mon, 20 Jan 2025 15:04:56 +0800 MIME-Version: 1.0 Subject: Re: [PATCH v2 25/25] drm/xlnx: Compute dumb-buffer sizes with drm_mode_size_dumb() To: Laurent Pinchart 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 References: <8234927e-0d12-4655-813d-8ec94179b737@linux.dev> <20250119201443.GB2467@pendragon.ideasonboard.com> Content-Language: en-US X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Sui Jingfeng In-Reply-To: <20250119201443.GB2467@pendragon.ideasonboard.com> X-Migadu-Flow: FLOW_OUT X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250119_230521_038954_7B390B77 X-CRM114-Status: GOOD ( 37.98 ) 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-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org SGksCgpPbiAyMDI1LzEvMjAgMDQ6MTQsIExhdXJlbnQgUGluY2hhcnQgd3JvdGU6Cj4gT24gTW9u LCBKYW4gMjAsIDIwMjUgYXQgMTI6MjY6MzBBTSArMDgwMCwgU3VpIEppbmdmZW5nIHdyb3RlOgo+ PiBPbiAyMDI1LzEvMTkgMjM6MjIsIFRvbWkgVmFsa2VpbmVuIHdyb3RlOgo+Pj4gT24gMTkvMDEv MjAyNSAxNjo1OSwgU3VpIEppbmdmZW5nIHdyb3RlOgo+Pj4KPj4+Pj4+PiBCdXQgdXNlcnNwYWNl IG11c3QgYmUgYWJsZSB0byBjb250aW51ZSBhbGxvY2F0aW5nIFlVViBidWZmZXJzIHRocm91Z2gK Pj4+Pj4+PiBDUkVBVEVfRFVNQi4KPj4+Pj4+IEkgdGhpbmssIGFsbG9jYXRpbmcgWVVWIGJ1ZmZl cnMgdGhyb3VnaCBDUkVBVEVfRFVNQiBpbnRlcmZhY2UgaXMganVzdAo+Pj4+Pj4gYW4gKmFidXNl KiBhbmQgKm1pc3VzZSogb2YgdGhpcyBBUEkgZm9yIG5vdy4KPj4+Pj4+Cj4+Pj4+PiBUYWtlIHRo ZSBOVjEyIGZvcm1hdCBhcyBhbiBleGFtcGxlLCBOVjEyIGlzIFlVVjQyMCBwbGFuYXIgZm9ybWF0 LCBoYXZlCj4+Pj4+PiB0d28gcGxhbmFyOiB0aGUgWS1wbGFuYXIgYW5kIHRoZSBVVi1wbGFuYXIu IFRoZSBZLXBsYW5hciBhcHBlYXIgZmlyc3QKPj4+Pj4+IGluIG1lbW9yeSBhcyBhbiBhcnJheSBv ZiB1bnNpZ25lZCBjaGFyIHZhbHVlcy4gVGhlIFktcGxhbmFyIGlzIGZvbGxvd2VkCj4+Pj4+PiBp bW1lZGlhdGVseSBieSB0aGUgVVYtcGxhbmFyLCB3aGljaCBpcyBhbHNvIGFuIGFycmF5IG9mIHVu c2lnbmVkIGNoYXIKPj4+Pj4+IHZhbHVlcyB0aGF0IGNvbnRhaW5zIHBhY2tlZCBVIChDYikgYW5k IFYgKENyKSBzYW1wbGVzLgo+Pj4+Pj4KPj4+Pj4+IEJ1dCB0aGUgJ2RybV9tb2RlX2NyZWF0ZV9k dW1iJyBzdHJ1Y3R1cmUgaXMgb25seSBpbnRlbmQgdG8gcHJvdmlkZQo+Pj4+Pj4gZGVzY3JpcHRp b25zIGZvciAqb25lKiBwbGFuYXIuCj4+Pj4+Pgo+Pj4+Pj4gc3RydWN0IGRybV9tb2RlX2NyZWF0 ZV9kdW1iIHsKPj4+Pj4+ICDCoMKgwqDCoCBfX3UzMiBoZWlnaHQ7Cj4+Pj4+PiAgwqDCoMKgwqAg X191MzIgd2lkdGg7Cj4+Pj4+PiAgwqDCoMKgwqAgX191MzIgYnBwOwo+Pj4+Pj4gIMKgwqDCoMKg IF9fdTMyIGZsYWdzOwo+Pj4+Pj4gIMKgwqDCoMKgIF9fdTMyIGhhbmRsZTsKPj4+Pj4+ICDCoMKg wqDCoCBfX3UzMiBwaXRjaDsKPj4+Pj4+ICDCoMKgwqDCoCBfX3U2NCBzaXplOwo+Pj4+Pj4gfTsK Pj4+Pj4+Cj4+Pj4+PiBBbiB3aWR0aCB4IGhlaWdodCBOVjEyIGltYWdlIHRha2VzIHVwIHdpZHRo KmhlaWdodCooMSArIDEvNCArIDEvNCkKPj4+Pj4+IGJ5dGVzLgo+Pj4+Pj4KPj4+Pj4+IFNvIHdl IGNhbiBhbGxvY2F0ZSBhbiAqZXF1aXZhbGVudCogc2l6ZWQgYnVmZmVyIHRvIHN0b3JlIHRoZSBO VjEyCj4+Pj4+PiByYXcgZGF0YS4KPj4+Pj4+Cj4+Pj4+PiBFaXRoZXIgJ3dpZHRoICogKGhlaWdo dCAqIDMvMiknIHdoZXJlIGVhY2ggcGl4ZWwgdGFrZSB1cCA4IGJpdHMsCj4+Pj4+PiBvciBqdXN0 ICd3aXRoICogaGVpZ2h0JyB3aGVyZSBlYWNoIHBpeGVscyB0YWtlIHVwIDEyIGJpdHMuCj4+Pj4+ Pgo+Pj4+Pj4gSG93ZXZlciwgYWxsIHRob3NlIG1hdGggYXJlIGp1c3QgZXF1aXZhbGVudHMgZGVz Y3JpcHRpb24gdG8gdGhlIG9yaWdpbmFsCj4+Pj4+PiBOVjEyIGZvcm1hdCwgbmVpdGhlciBhcmUg Y29uY3JldGUgY29ycmVjdCBwaHlzaWNhbCBkZXNjcmlwdGlvbi4KPj4+Pj4gSSBkb24ndCBzZWUg dGhlIHByb2JsZW0uIEFsbG9jYXRpbmcgZHVtYiBidWZmZXJzLCBpZiB3ZSBkb24ndCBoYXZlCj4+ Pj4+IGFueSBoZXVyaXN0aWNzIHJlbGF0ZWQgdG8gUkdCIGJlaGluZCBpdCwgaXMgZXNzZW50aWFs bHkganVzdAo+Pj4+PiBhbGxvY2F0aW5nIGEgc3BlY2lmaWMgYW1vdW50IG9mIG1lbW9yeSwgZGVm aW5lZCBieSB3aWR0aCwgaGVpZ2h0IGFuZAo+Pj4+PiBiaXRzcGVycGl4ZWwuCj4+Pj4+Cj4+Pj4g SSB0aGluaywgdGhlIHByb2JsZW0gd2lsbCBiZSB0aGF0IHRoZSAnd2lkdGgnLCAnaGVpZ2h0JyBh bmQgJ2JwcCcKPj4+PiBhcmUgb3JpZ2luYWxseSB1c2VkIHRvIGRlc2NyaWJlIG9uZSBwbGFuZS4g VGhvc2UgdGhyZWUgcGFyYW1ldGVycwo+Pj4+IGhhcyBwZXJmZWN0bHkgZGVmaW5lZCBwaHlzaWNh bCBzZW1hbnRpY3MuCj4+Pj4KPj4+PiBCdXQgd2l0aCBtdWx0aSBwbGFuYXIgZm9ybWF0cywgdGFr ZSBOVjEyIGltYWdlIGFzIGFuIGV4YW1wbGUsCj4+Pj4gZm9yIGEgMsOXMiBzcXVhcmUgb2YgcGl4 ZWxzLCB0aGVyZSBhcmUgNCBZIHNhbXBsZXMgYnV0IG9ubHkgMSBVCj4+Pj4gc2FtcGxlIGFuZCAx IFYgc2FtcGxlLiBUaGlzIGZvcm1hdCByZXF1aXJlcyA0eDgrMXg4KzF4OD00OCBiaXRzCj4+Pj4g dG8gc3RvcmUgdGhlIDJ4MiBzcXVhcmUuCj4+Pj4KPj4+PiBTbyBpdHMgZGVwdGggaXMgMTIgYml0 cyBwZXIgcGl4ZWwgKDQ4IC8gKDIgKiAyKSkuCj4+Pj4KPj4+PiBzbyBteSBwcm9ibGVtIGlzIHRo YXQgdGhlIG1lbnRpb25lZCAxMmJwcCBpbiB0aGlzIGV4YW1wbGUgb25seQo+Pj4+IG1ha2Ugc2Vu c2UgaW4gbWF0aGVtYXRpY3MsIGl0IGRvZXNuJ3QgaGFzIGEgZ29vZCBwaHlzaWNhbAo+Pj4+IGlu dGVycHJldC4gRG8geW91IGFncmVlIHdpdGggbWUgb24gdGhpcyB0ZWNobmlxdWUgcG9pbnQ/Cj4+ Pj4KPj4+Pj4gSWYgSSB3YW50IHRvIGNyZWF0ZSBhbiBOVjEyIGZyYW1lYnVmZmVyLCBJIGFsbG9j YXRlIHR3byBkdW1iCj4+Pj4+IGJ1ZmZlcnMsIG9uZSBmb3IgWSBhbmQgb25lIGZvciBVViBwbGFu ZXMsIGFuZCBzaXplIHRoZW0gYWNjb3JkaW5nbHkuCj4+Pj4+IEFuZCB0aGVuIGNyZWF0ZSB0aGUg RFJNIGZyYW1lYnVmZmVyIHdpdGggdGhvc2UuCj4+Pj4+Cj4+Pj4gVGhlbiBob3cgeW91IGZpbGwg dGhlIHZhbHVlIG9mIHRoZSAnd2lkdGgnLCAnaGVpZ2h0JyBhbmQgJ2JwcCcgb2YKPj4+PiBlYWNo IGR1bWIgYnVmZmVycz8KPj4+IEZvciA2NDB4NDgwLU5WMTI6Cj4+PiBwbGFuZSAwOiB3aWR0aCA9 IDY0MCwgaGVpZ2h0ID0gNDgwLCBicHAgPSA4Cj4+PiBwbGFuZSAxOiB3aWR0aCA9IDY0MCAvIDIs IGhlaWdodCA9IDQ4MCAvIDIsIGJwcCA9IDE2Cj4+IEJ1dCBpIHRoaW5rIHRoaXMgc2hvdWxkIGJl IGhhcmR3YXJlIGRlcGVuZGVudC4gVGhlIGhhcmR3YXJlIEknbSB1c2luZwo+PiBsb2FkIE5WMTIg IHJhdyBkYXRhIGFzIGEgd2hvbGUuIEkgb25seSBuZWVkIHRvIGZlZWQgZ3B1dmEgb2YgdGhlIGJh Y2tpbmcKPj4gbWVtb3J5IHRvIHRoZSBoYXJkd2FyZSByZWdpc3RlciBvbmNlLgo+Pgo+PiBOb3Qg ZmFtaWxpYXIgd2l0aCB5b3VyIGhhcmR3YXJlLCBzbyBJIGNhbid0IHRhbGsgbW9yZSBvbiB0aGlz IHNvZnR3YXJlCj4+IGRlc2lnbi4gUGVyaGFwcyBzb21lb25lIGtub3cgbW9yZSBjb3VsZCBoYXZl IGEgY29tbWVudCBvbiB0aGlzLgo+IExheW91dCBvZiBwbGFuZXMgaW4gbWVtb3J5IGlzIGp1c3Qg b25lIGhhcmR3YXJlIGNvbnN0cmFpbnQsIHRoZSBzYW1lIHdheQo+IHdlIGhhdmUgY29uc3RyYWlu dHMgb24gYWxpZ25tZW50IGFuZCBzdHJpZGVzLiBTb21lIGRldmljZXMgcmVxdWlyZSB0aGUKPiBw bGFuZXMgdG8gYmUgY29udGlndW91cyAobGlrZWx5IHdpdGggc29tZSBhbGlnbm1lbnQgY29uc3Ry YWludHMpLCBzb21lCj4gY2FuIHdvcmsgd2l0aCBwbGFuZXMgYmVpbmcgaW4gZGlzY29udGlndW91 cyBwaWVjZXMgb2YgbWVtb3J5LCBhbmQgZXZlbgo+IHJlcXVpcmUgdGhlbSB0byBiZSBkaXNjb250 aWd1b3VzIGFuZCBsb2NhdGVkIGluIHNlcGFyYXRlIERSQU0gYmFua3MuCgpSaWdodC4KCgo+Pj4+ IFdoeSBub3QgYWxsb2NhdGUgc3RvcmFnZSBmb3IgdGhlIHdob2xlIG9uIG9uZSBzaG9vdD8KPj4+ IFlvdSBjYW4sIGlmIHlvdSBhZGp1c3QgdGhlIHBhcmFtZXRlcnMgYWNjb3JkaW5nbHkuIEhvd2V2 ZXIsIGlmIHRoZQo+Pj4gc3RyaWRlcyBvZiB0aGUgcGxhbmVzIGFyZSBub3QgZXF1YWwsIEkgZ3Vl c3MgaXQgbWlnaHQgY2F1c2UgcHJvYmxlbXMKPj4+IG9uIHNvbWUgcGxhdGZvcm1zLgo+Pj4KPj4+ IEJ1dCBJIHRoaW5rIGl0J3MgdXN1YWxseSBzaW1wbGVyIHRvIGFsbG9jYXRlIG9uZSBidWZmZXIg cGVyIHBsYW5lLCBhbmQKPj4+IHBlcmhhcHMgZXZlbiBiZXR0ZXIgYXMgaXQgZG9lc24ndCByZXF1 aXJlIGFzIGxhcmdlIGNvbnRpZ3VvdXMgbWVtb3J5Cj4+PiBhcmVhLgo+Pj4KPj4+PiBUaGUgbW9k ZXRlc3QgaW4gbGliZHJtIGNhbiBiZSBhbiBnb29kIGV4YW1wbGUsIHNlbmQgaXRbMV0gdG8geW91 IGFzCj4+Pj4gYW4gcmVmZXJlbmNlLgo+Pj4gUmlnaHQsIHNvIG1vZGV0ZXN0IGFscmVhZHkgZG9l cyBpdCBzdWNjZXNzZnVsbHkuIFNvLi4uIFdoYXQgaXMgdGhlIGlzc3VlPwo+PiBCdXQgdGhlbiwg dGhlIHByb2JsZW0gd2lsbCBiZWNvbWUgdGhhdCBpdCBvdmVycmlkZSB0aGUgJ2hlaWdodCcgcGFy YW1ldGVyLgo+PiBXaGF0J3MgdGhlIHBoeXNpY2FsIGludGVycHJldGF0aW9uIG9mIHRoZSAnaGVp Z2h0JyBwYXJhbWV0ZXIgd2hlbiBjcmVhdGluZwo+PiBhbiBOVjEyIGltYWdlIHdpdGggdGhlIGR1 bXAgQVBJIHRoZW4/Cj4gSSB3b3VsZG4ndCBiZSB0b28gY29uY2VybmVkIGFib3V0IHBoeXNpY2Fs IGludGVycHJldGF0aW9ucy4gWWVzLCB0aGUKPiBoZWlnaHQsIHdpZHRoIGFuZCBicHAgcGFyYW1l dGVycyB3ZXJlIGxpa2VseSBkZXNpZ25lZCB3aXRoIFJHQiBmb3JtYXRzCj4gaW4gbWluZC4gWWVz LCB1c2luZyBEVU1CX0NSRUFURSBmb3IgWVVWIGZvcm1hdHMgaXMgcHJvYmFibHkgc29tZXRoaW5n Cj4gdGhhdCB0aGUgb3JpZ2luYWwgYXV0aG9ycyBkaWRuJ3QgZW52aXNpb24uIEFuZCB5ZXMsIGZy b20gdGhhdCBwb2ludCBvZgo+IHZpZXcsIGl0IGNvdWxkIGJlIHNlZW4gYnkgdGhlIG9yaWdpbmFs IGF1dGhvcnMgYXMgYW4gYWJ1c2Ugb2YgdGhlIEFQSS4KPiBCdXQgSSBkb24ndCB0aGluayB0aGF0 J3MgYSBwcm9ibGVtIGFzIHN1Y2guCgpTb21ldGltZXMgdGhlcmUgbWF5IGhhdmUgMkQgR1BVIG9y IEltYWdlIFByb2Nlc3MgVW5pdCBnZXQgaW52b2x2ZWQuClNldHRpbmcgdGhlIGRpbWVuc2lvbiwg dGhlIGNsaXAgd2luZG93IGFuZCBwaXRjaCBldGMgcGFyYW1ldGVycyB0byB0aGUKaGFyZHdhcmUg YXJlIG5lZWRlZC4KClRoZSB2YWx1ZSBvZiBicHAgYWZmZWN0cyBwaXRjaCwgYmlnZ2VyIHBpdGNo IG1heSBjYXVzZSB0aGUgaGFyZHdhcmUgbG9hZAptb3JlIGJ5dGVzIHRoYW4gaXQgc2hvdWxkIG9u IG9uZSBsaW5lLiBXaGlsZSB0aGUgJ2hlaWdodCcgbWF5IGFmZmVjdCB0aGUKc2l6ZSBvZiB0aGUg Y2xpcCB3aW5kb3csIGRlcGVuZCBvbiB0aGUgY2FsY3VsYXRpb24gbWV0aG9kLgoKQnV0IEkgaGF2 ZSBubyBzdHJvbmcgb3BpbmlvbiB0b3dhcmQgd2l0aCB0aGlzIGFuZCBhZ3JlZSB3aXRoIHlvdSBp biBvdmVyYWxsLgoKPiBBbiBBUEkgaXMganVzdCBhbiBBUEkuIFRydWUsIGl0IHdvdWxkIGJlIG5p Y2VyIGlmIHRoZSB1c2FnZSBvZiB0aGUgaW9jdGwKPiBwYXJhbWV0ZXJzIHdhcyBtb3JlIGludHVp dGl2ZSBmb3IgWVVWIGZvcm1hdHMsIGJ1dCBJIGJlbGlldmUgd2UgY291bGQKPiBzdGlsbCBzdGFu ZGFyZGl6ZSBob3cgdGhlIGV4aXN0aW5nIHBhcmFtZXRlcnMgbWFwIHRvIGxpbmVhciBzY2Fub3V0 IFlVVgo+IGZvcm1hdHMgd2l0aG91dCBjYXVzaW5nIHRoZSB3b3JsZCB0byBlbmQuIEFzIGhhcyBi ZWVuIHNhaWQgYmVmb3JlLCBsb3RzCj4gb2YgZHJpdmVycyBhcmUgdXNpbmcgRFVNQl9DUkVBVEUg Zm9yIHRoaXMgcHVycG9zZSwgYW5kIHdlIGNhbid0IGNoYW5nZQo+IHRoYXQuCj4KPiBUaGlzIGRv ZXNuJ3QgbWVhbiB3ZSBzaG91bGRuJ3Qgd29yayBvbiBpbXByb3ZpbmcgbWVtb3J5IGFsbG9jYXRp b24sIGJ1dAo+IEkgc2VlIHRoYXQgYXMgYSBzZXBhcmF0ZSBpc3N1ZS4KPgo+PiBJIGd1ZXNzLCBz b2x2aW5nIGNvbXBsZXggcHJvYmxlbXMgd2l0aCBzaW1wbGUgQVBJcyBtYXkgc2VlIHRoZSBsaW1p dGF0aW9uLAo+PiBzb29uZXIgb3IgbGF0ZXIuIEJ1dCBJIG5vdCB2ZXJ5IHN1cmUgYW5kIG1pZ2h0 IGJlIHdyb25nLiBTbyBvdGhlciBwZW9wbGVzCj4+IGNhbiBvdmVycmlkZSBtZSB3b3Jkcy4KPj4K Pj4+IEV2ZXJ5b25lIGFncmVlcyB0aGF0IENSRUFURV9EVU1CIGlzIG5vdCB0aGUgYmVzdCBpb2N0 bCB0byBhbGxvY2F0ZQo+Pj4gYnVmZmVycywgYW5kIG9uZSBjYW4ndCBjb25zaWRlciBpdCB0byB3 b3JrIGlkZW50aWNhbGx5IGFjcm9zcyB0aGUKPj4+IHBsYXRmb3Jtcy4gQnV0IGl0J3Mgd2hhdCB3 ZSBoYXZlIGFuZCB3aGF0IGhhcyBiZWVuIHVzZWQgZm9yIGFnZXMuCj4+IFllYWgsIHlvdXIgcmVx dWVzdCBhcmUgbm90IHVucmVhc29uYWJsZS4gSXQgY2FuIGJlIHNlZW4gYXMgYSBraW5kIG9mIHJp Z2lkIGRlbWFuZC4KPj4gU2luY2UgR0VNIERNQSBoZWxwZXJzIGRvZXNuJ3QgZXhwb3J0IGFuIG1v cmUgYWR2YW5jZWQgaW50ZXJmYWNlIHRvIHVzZXJzcGFjZSBzbyBmYXIuCj4+IEFzIGEgcmVzdWx0 LCBkcml2ZXJzIHRoYXQgZW1wbG95aW5nIEdFTSBETUEgaGFzIG5vIG90aGVyIGNob2ljZSwgYnV0 IHRvIGFidXNlIHRoZQo+PiBkdW1iIGJ1ZmZlciBBUEkgdG8gZG8gYWxsb2NhdGlvbiBmb3IgdGhl IG1vcmUgY29tcGxleCBmb3JtYXQgYnVmZmVycy4KPj4KPj4gVGhlIGR1bWIgYnVmZmVyIEFQSSBk b2Vzbid0IHN1cHBvcnQgdG8gc3BlY2lmeSBidWZmZXIgZm9ybWF0LCB0aWxlIHN0YXR1cyBhbmQK Pj4gcGxhY2VtZW50IGV0Yy4gVGhlIG1vcmUgYWR2YW5jZSBkcml2ZXJzIGhhcyBiZWVuIGV4cG9z ZWQgdGhlIHh4eF9jcmVhdGVfZ2VtKCkKPj4gdG8gdXNlci1zcGFjZS4gSXQgc2VlbXMgdGhhdCBh IGZldyBtb3JlIGV4cGVyaWVuY2VkIHByb2dyYW1tZXJzIGhpbnQgdXMgdG8KPj4gY3JlYXRlIGFu IG5ldyBpb2N0bCBhdCBhYm92ZSB0aHJlYWQsIHNvIHRoYXQgd2UgY2FuIGtlZXAgZW1wbG95aW5n IHNpbXBsZSBBUEkKPj4gdG8gZG8gc2ltcGxlIHRoaW5ncyBhbmQgdG8gc3VpdCBjb21wbGV4IG5l ZWRzIHdpdGggdGhlIG1vcmUgYWR2YW5jZWQgQVBJcy4KPiBJJ2QgcmVhbGx5IGxpa2UgdG8gZXhw bG9yZSBhZGRpbmcgbmV3IGlvY3RscyB0byBleHBvc3VyZSBtZW1vcnkKPiBhbGxvY2F0aW9uIGNv bnN0cmFpbnRzLCBhbmQgYWxsb2NhdGluZyB0aGUgbWVtb3J5IGl0c2VsZiBmcm9tIERNQSBoZWFw cy4KPgotLSAKQmVzdCByZWdhcmRzLApTdWkKCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fXwpMaW51eC1yb2NrY2hpcCBtYWlsaW5nIGxpc3QKTGludXgtcm9j a2NoaXBAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWls bWFuL2xpc3RpbmZvL2xpbnV4LXJvY2tjaGlwCg==