GNU bug report logs - #73563
[Ben Simms] Performance bottleneck in ns_draw_fringe_bitmap

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Reported by: Stefan Kangas <stefankangas@HIDDEN>; dated Mon, 30 Sep 2024 08:03:02 UTC; Maintainer for emacs is bug-gnu-emacs@HIDDEN.

Message received at 73563 <at> debbugs.gnu.org:


Received: (at 73563) by debbugs.gnu.org; 17 May 2025 11:24:03 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat May 17 07:24:03 2025
Received: from localhost ([127.0.0.1]:46676 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1uGFe6-0002lZ-C5
	for submit <at> debbugs.gnu.org; Sat, 17 May 2025 07:24:03 -0400
Received: from dane.soverin.net ([185.233.34.38]:49115)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <alan@HIDDEN>) id 1uGFe4-0002l4-E3
 for 73563 <at> debbugs.gnu.org; Sat, 17 May 2025 07:24:01 -0400
Received: from smtp.soverin.net (unknown [10.10.4.74])
 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
 (No client certificate requested)
 by dane.soverin.net (Postfix) with ESMTPS id 4b01mV2cfvz186L;
 Sat, 17 May 2025 11:23:54 +0000 (UTC)
Received: from smtp.soverin.net (smtp.soverin.net [10.10.4.99]) by soverin.net
 (Postfix) with ESMTPSA id 4b01mT4HVmz7X; 
 Sat, 17 May 2025 11:23:53 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=idiocy.org; s=soverin;
 t=1747481034; bh=c8EU3rK7D0uWiVMxFhSEPZTPDW9k5yxrzHA680ly2+0=;
 h=Date:From:To:Cc:Subject:References:In-Reply-To:From;
 b=Txzb5Y7lhuNNIYmXHWtmXEo/Jhqha/OINDKDmNhe9SjIMZd9ENWiIB8M65ASuePPb
 3P60qNqV65uMaOXLJSeqic55lNyvmZ/Sx2e75P0qbyrrEWveRlYruaOxjnBx2rBNdM
 rhYMOF3nfh07EcaQjG7T+T91e1lJowWCiO81jiuvREyyqkqkrmZ42NN44sD/NYTFBK
 2sgEx+JrFkG4udzXSG0oXg8AA1+qOAv/UaSfNu+NGpC0sljh0LNtKIkIFtj/dNke/u
 P4aOV92MOiSBSW2CLEjDP6oY0ViecXteUnj+f6zE65Yy6RT1jjtlZLixXHyQeyRBAT
 ZlTdF5lAMQBzA==
X-CM-Envelope: MS4xfJsOuxhDmEk4adHEAz4ubT+bEd/3mke6MdcF4AsnFO8qgM584XfvxSZmR8WIPHxfFnGCbJL42dHjpRV3/TLvWQXxFCkr+8vZErpjQKH2QbgTtObQMQCX
 R2psp0jqTrTJQBiZ/3rQP6MfwVkG5EGGuhna6jRX8snX9/nKLflJuC7TzuYRrs2S8RZNxQnfz5I2P/PSZyd475kW1T7ij6sSa+R9G5zxgo1yPpxcd4z4X/YO
 aBb5zDGwbZFhpQG4BaPN+SHMWqzjkJ3TldhCXZck9KnIzuMNX0WXyNGApqqp9Q53W0tnVKp1KoA6rb0nU8Q2WA==
X-CM-Analysis: v=2.4 cv=d/oPyQjE c=1 sm=1 tr=0 ts=682871ca
 a=UbsBXRcqaZ6D9kgPt/Dvnw==:617 a=xqWC_Br6kY4A:10 a=kj9zAlcOel0A:10
 a=dt9VzEwgFbYA:10 a=NEAV23lmAAAA:8 a=mDV3o1hIAAAA:8 a=fvF8FFjmQgGntISpTSEA:9
 a=CjuIK1q_8ugA:10 a=9MSFP0l5Dcwi9NrB_JPx:22
Received: from localhost (faroe.holly.idiocy.org [local])
 by faroe.holly.idiocy.org (OpenSMTPD) with ESMTPA id f253ee2a;
 Sat, 17 May 2025 11:23:53 +0000 (UTC)
Date: Sat, 17 May 2025 12:23:53 +0100
From: Alan Third <alan@HIDDEN>
To: Eli Zaretskii <eliz@HIDDEN>
Subject: Re: bug#73563: [Ben Simms] Performance bottleneck in
 ns_draw_fringe_bitmap
Message-ID: <aChxyarDxZUdur11@HIDDEN>
Mail-Followup-To: Alan Third <alan@HIDDEN>, Eli Zaretskii <eliz@HIDDEN>,
 Jordan Ellis Coppard <jc+o.emacs@HIDDEN>,
 Gerd =?iso-8859-1?Q?M=F6llmann?= <gerd.moellmann@HIDDEN>,
 73563 <at> debbugs.gnu.org, ben@HIDDEN
References: <CADwFkmn9fhiU7XfXu5Ku+ouuxH=J+cx73n-APP7Gkq4FdywD0g@HIDDEN>
 <d3fd9db3-d93b-4f80-b216-3818383212d0@HIDDEN>
 <865xhzwptp.fsf@HIDDEN>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <865xhzwptp.fsf@HIDDEN>
X-Spampanel-Class: ham
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 73563
Cc: Gerd =?iso-8859-1?Q?M=F6llmann?= <gerd.moellmann@HIDDEN>,
 ben@HIDDEN, 73563 <at> debbugs.gnu.org,
 Jordan Ellis Coppard <jc+o.emacs@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

On Sat, May 17, 2025 at 12:26:26PM +0300, Eli Zaretskii wrote:
> > Cc: Ben Simms <ben@HIDDEN>
> > Date: Tue, 13 May 2025 20:37:55 +0900
> > From:  Jordan Ellis Coppard via "Bug reports for GNU Emacs,
> >  the Swiss army knife of text editors" <bug-gnu-emacs@HIDDEN>
> > 
> > Howdy,
> > 
> > 
> > I've been using the following patch (bottom of this email) until my most 
> > recent rebuild of Emacs from master. Since the recent commit fixing 
> > stipple drawing the patch can be reduced to just: 
> > https://github.com/emacs-mirror/emacs/commit/7f2efe6503fdce2a4e552c14802644a05b581bc7 
> > (link to a diff authored by Ben Simms).
> > 
> > I've now noticed again extreme slowdown when fringe bitmaps are used. It 
> > appears to be proportional to the number of bits set in the bitmap. An 
> > 'empty' bitmap (all zeroes) doesn't yield any noticeable slowdown, a 
> > bitmap with 1 bit set yields a little, with 2 its noticeable and with 
> > all 8 bits set Emacs takes up to 1 second to respond to any input at all.
> > 
> > This has been the case since at least August of last year. I can get a 
> > minimal reproduction but it has happened on completely different 
> > configurations with the only common denominator being the NS build (on 
> > ARM-based macOS), and the use of fringe bitmaps.
> > 
> > Below is trace with update_frame as the root context. Captured with 
> > Instruments.app (which uses dtrace and more under the hood IIRC).
> > 
> > ns_draw_fringe_bitmap takes up 94% of the time for the short 
> > reproduction this trace records. The deepest the trace goes is to 
> > CG::Path::recalculate_bounding_box() which eats 80% of time. So instead 
> > of a cached value the bounding box is being recalculated every time 
> > which appears very expensive, but beyond that I have close to zero 
> > experience with macOS' graphics stack.
> > 
> > I've just recompiled Emacs against the same commit of my recent master 
> > build (648453c04d9b91d96452b930c0c948b0b39b5dc0) except now with the 
> > patch applied (since the stipple changes are merged it's just the 
> > smallest subset: 
> > https://github.com/emacs-mirror/emacs/commit/7f2efe6503fdce2a4e552c14802644a05b581bc7) 
> > and once again fringe performance is back to being buttery smooth.
> 
> Alan and Gerd, any comments or suggestions?

I've not looked at it closely, but I will point out that AFAIK GNUStep
does not support Core Graphics, so any function or struct starting
with "CG" needs an alternative method in place.

-- 
Alan Third




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#73563; Package emacs. Full text available.

Message received at 73563 <at> debbugs.gnu.org:


Received: (at 73563) by debbugs.gnu.org; 17 May 2025 09:45:43 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat May 17 05:45:43 2025
Received: from localhost ([127.0.0.1]:45912 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1uGE6x-0004yv-5f
	for submit <at> debbugs.gnu.org; Sat, 17 May 2025 05:45:43 -0400
Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]:54434)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.84_2) (envelope-from <gerd.moellmann@HIDDEN>)
 id 1uGE6v-0004yN-G6
 for 73563 <at> debbugs.gnu.org; Sat, 17 May 2025 05:45:42 -0400
Received: by mail-wm1-x331.google.com with SMTP id
 5b1f17b1804b1-43edecbfb46so22493865e9.0
 for <73563 <at> debbugs.gnu.org>; Sat, 17 May 2025 02:45:41 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1747475135; x=1748079935; darn=debbugs.gnu.org;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=uRo9lzVrhGEmJOCUc6b67Hod/JrXf3kqn1abCh1Y2sM=;
 b=c0OjXoyJJ/p5D2SLO+khniz0G8D/H/4tXgZhksTDjN242bQS+BAOTT8jFCRKWz4yTi
 K57HpIW5/Y7lCy9qXJmzrWuBFcv44hXjL2XO5F8WQoaLPFIW8GhWjHrS/x1IObiA4pEX
 a5/IFLD1nBJC8royARTYO/hMyGWvrVuB2KNb72jGrVZxaFyE/GRFJLl0jIt8OiTMudCh
 mwBoE72kpZEELC+UVY1PjxmuSUqaDOSgvs7yuBTYyMvL5x6P+6iPrng2waVwn1fs/3uG
 zt4xFwPSkfFxY0D+npKEqvvup1D6eDrk4WLZIXdCY2aBnmssRTI96C/9hz/JY73DniMF
 mfpQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1747475135; x=1748079935;
 h=mime-version:user-agent:message-id:date:references:in-reply-to
 :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date
 :message-id:reply-to;
 bh=uRo9lzVrhGEmJOCUc6b67Hod/JrXf3kqn1abCh1Y2sM=;
 b=VdZmBi/tCbaXKygNeVQrRWb3uZU2Vhcsx7THI6Z+Q8TuD50hBTWZnxS7YBz2odLOOE
 idI+69MqeN/x2qVEmPhVeYlq2BR1ZrLStoXJFlR16PDtwOBJ5XmiU4tMbP5x8gM13+qa
 d/7fMwPni9b5O/B/DGlhds4JAij9Ax7nsJ9en+fu4Ln5yrYm0IeHCkLC58LB8KpjJC84
 gtQ2VAtDAMnA5UmZ8qF9v/fPJjQA0N/hhZBScEWUMM7QfnqEZCQ0zOL9Su2OOPYW8vij
 B+lRrhqgUP3uHfazxzgrsI3scWnld+HyLovdrAQfmyXtFsYxzpM75u+wg8gqRbyIY0Nt
 E5DA==
X-Forwarded-Encrypted: i=1;
 AJvYcCWJatJUi0cTEI7tE44qiLYS6e2MR8HWdWpujJe1+GjTH7Kk6g+8a4WIwB2+2XzoeNLdRFeyNA==@debbugs.gnu.org
X-Gm-Message-State: AOJu0YwffuF/s6vfe95aP8YyLYEdvwC1+0mo2gxr1kcXGHBcSlVE5IId
 a4LG+kEaUJu4sG+Q5whVFawO8/KkRezrVO0iOT/nRxZDBvw5zCcBQyJL
X-Gm-Gg: ASbGncvMDIDayhEZy0RaaoHE+GJozShOfHFkGIPxhN134eNbwekF5lwQAZZU7hqop9j
 fZsr3erRoE7cRk8mH6fOugtGOxLC07bELiniT/X9uUMk0dcQTGkJdeFOElUdBFAm5yNwNPqt2mo
 KznaXSZe7MVutphnfODipyo+60KlO/Q11Nt22pGqiEr2B8D6Icjb3c5Ov6KN7WigtwKWd18DP2R
 Nuaj27FQO+hcS0DcYDbi7xQm0hcK2Y86h9mhaX5jv/pG5y7ziLpfcxX4j9wXeOvGtLr320JJJjm
 4BPJSN9XL6D40jNHnplip6Gxo2v4ajGASoqUL8vIGhdJ6pSO5VkeGMurSqaTtCcML8fE3wMGYfy
 ZCUULc6OKaUbHDWYFX7wwSA3zlvtvYN5J+iqGRl66bONQyyGZaJJDrsjkbJMxMrpdWlV2gjA=
X-Google-Smtp-Source: AGHT+IEr0fBWgC/Qx6Vpp1WR8SMEXvB2zsLDc97reamzI2OoRqJ133edS1mhjKgiOfeZ4rvkR2nsLA==
X-Received: by 2002:a5d:5442:0:b0:3a3:64fb:304d with SMTP id
 ffacd0b85a97d-3a364fb30f1mr2062083f8f.12.1747475135203; 
 Sat, 17 May 2025 02:45:35 -0700 (PDT)
Received: from pro2 (p200300e0b7074700f5e9568db45acf37.dip0.t-ipconnect.de.
 [2003:e0:b707:4700:f5e9:568d:b45a:cf37])
 by smtp.gmail.com with ESMTPSA id
 ffacd0b85a97d-3a35ca6254bsm5770810f8f.52.2025.05.17.02.45.34
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Sat, 17 May 2025 02:45:34 -0700 (PDT)
From: =?utf-8?Q?Gerd_M=C3=B6llmann?= <gerd.moellmann@HIDDEN>
To: Eli Zaretskii <eliz@HIDDEN>
Subject: Re: bug#73563: [Ben Simms] Performance bottleneck in
 ns_draw_fringe_bitmap
In-Reply-To: <865xhzwptp.fsf@HIDDEN>
References: <CADwFkmn9fhiU7XfXu5Ku+ouuxH=J+cx73n-APP7Gkq4FdywD0g@HIDDEN>
 <d3fd9db3-d93b-4f80-b216-3818383212d0@HIDDEN> <865xhzwptp.fsf@HIDDEN>
Date: Sat, 17 May 2025 11:45:33 +0200
Message-ID: <m2tt5jfu4i.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13)
MIME-Version: 1.0
Content-Type: text/plain
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 73563
Cc: ben@HIDDEN, Alan Third <alan@HIDDEN>, 73563 <at> debbugs.gnu.org,
 Jordan Ellis Coppard <jc+o.emacs@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

Eli Zaretskii <eliz@HIDDEN> writes:

> Alan and Gerd, any comments or suggestions?

That goes beyond my macOS graphics knowledge I'm afraid.




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#73563; Package emacs. Full text available.

Message received at 73563 <at> debbugs.gnu.org:


Received: (at 73563) by debbugs.gnu.org; 17 May 2025 09:26:44 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat May 17 05:26:44 2025
Received: from localhost ([127.0.0.1]:45759 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1uGDoW-0003jO-MP
	for submit <at> debbugs.gnu.org; Sat, 17 May 2025 05:26:44 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10]:47652)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <eliz@HIDDEN>) id 1uGDoR-0003iv-Kb
 for 73563 <at> debbugs.gnu.org; Sat, 17 May 2025 05:26:39 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <eliz@HIDDEN>)
 id 1uGDoK-00019R-O0; Sat, 17 May 2025 05:26:28 -0400
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org;
 s=fencepost-gnu-org; h=MIME-version:References:Subject:In-Reply-To:To:From:
 Date; bh=LVmmBgNkGePz8nVYphteseDcUkAhcoktGy31CKUqxhc=; b=IgpfFM/LY/ca4Y8Z8aLX
 kt+4D6Mx3aqOrlg9hVl65RfgXNtS9E4lfUUHYd38YUUl+5/vMyx6hMsExFe2Rsju0MRF+OnqLgsuc
 RC0r8eXf3M1WGwEWWcgE0yaqZ+TO63gm1cysfMY9sLZgNGInZGpw2a2A1KqUcGAPfeeDgQSQb1Zsr
 BizVJcOgtcmC+O01D29oiq1zDsOA+ezGVrJjk7vq/e8/JTvbh2bzG276RZNqaUQDMu0PuYJ3XSH1I
 gbAuTs8bHEbc+j2wwpR8UJ9mprEnxDnATg6M5teSFy7IWBruCmpQiwrO7ZZdGFgXQGhSZlbnFCBX2
 mawpiRRHv3BZ1Q==;
Date: Sat, 17 May 2025 12:26:26 +0300
Message-Id: <865xhzwptp.fsf@HIDDEN>
From: Eli Zaretskii <eliz@HIDDEN>
To: Jordan Ellis Coppard <jc+o.emacs@HIDDEN>,
 Alan Third <alan@HIDDEN>, =?utf-8?Q?Gerd_M=C3=B6llmann?=
 <gerd.moellmann@HIDDEN> 
In-Reply-To: <d3fd9db3-d93b-4f80-b216-3818383212d0@HIDDEN>
 (bug-gnu-emacs@HIDDEN)
Subject: Re: bug#73563: [Ben Simms] Performance bottleneck in
 ns_draw_fringe_bitmap
References: <CADwFkmn9fhiU7XfXu5Ku+ouuxH=J+cx73n-APP7Gkq4FdywD0g@HIDDEN>
 <d3fd9db3-d93b-4f80-b216-3818383212d0@HIDDEN>
MIME-version: 1.0
Content-type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
X-Spam-Score: -2.3 (--)
X-Debbugs-Envelope-To: 73563
Cc: ben@HIDDEN, 73563 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -3.3 (---)

> Cc: Ben Simms <ben@HIDDEN>
> Date: Tue, 13 May 2025 20:37:55 +0900
> From:  Jordan Ellis Coppard via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs@HIDDEN>
> 
> Howdy,
> 
> 
> I've been using the following patch (bottom of this email) until my most 
> recent rebuild of Emacs from master. Since the recent commit fixing 
> stipple drawing the patch can be reduced to just: 
> https://github.com/emacs-mirror/emacs/commit/7f2efe6503fdce2a4e552c14802644a05b581bc7 
> (link to a diff authored by Ben Simms).
> 
> I've now noticed again extreme slowdown when fringe bitmaps are used. It 
> appears to be proportional to the number of bits set in the bitmap. An 
> 'empty' bitmap (all zeroes) doesn't yield any noticeable slowdown, a 
> bitmap with 1 bit set yields a little, with 2 its noticeable and with 
> all 8 bits set Emacs takes up to 1 second to respond to any input at all.
> 
> This has been the case since at least August of last year. I can get a 
> minimal reproduction but it has happened on completely different 
> configurations with the only common denominator being the NS build (on 
> ARM-based macOS), and the use of fringe bitmaps.
> 
> Below is trace with update_frame as the root context. Captured with 
> Instruments.app (which uses dtrace and more under the hood IIRC).
> 
> ns_draw_fringe_bitmap takes up 94% of the time for the short 
> reproduction this trace records. The deepest the trace goes is to 
> CG::Path::recalculate_bounding_box() which eats 80% of time. So instead 
> of a cached value the bounding box is being recalculated every time 
> which appears very expensive, but beyond that I have close to zero 
> experience with macOS' graphics stack.
> 
> I've just recompiled Emacs against the same commit of my recent master 
> build (648453c04d9b91d96452b930c0c948b0b39b5dc0) except now with the 
> patch applied (since the stipple changes are merged it's just the 
> smallest subset: 
> https://github.com/emacs-mirror/emacs/commit/7f2efe6503fdce2a4e552c14802644a05b581bc7) 
> and once again fringe performance is back to being buttery smooth.

Alan and Gerd, any comments or suggestions?

> (trace also here in-case formatting gets borked:
> trace:
> 
> 3.07 s  100.0%	0 s	               update_frame
> 3.06 s  100.0%	0 s	                update_window_tree
> 3.06 s  100.0%	1.00 ms	                 update_window
> 2.89 s  94.2%	0 s	                  gui_update_window_end
> 2.88 s  94.1%	0 s	                   draw_window_fringes
> 2.88 s  93.9%	0 s	                    draw_fringe_bitmap
> 2.88 s  93.9%	0 s	                     draw_fringe_bitmap_1
> 2.88 s  93.9%	0 s	                      ns_draw_fringe_bitmap
> 2.72 s  88.7%	0 s	                       -[NSBezierPath copyWithZone:]
> 2.72 s  88.7%	0 s	                        -[NSBezierPath _appendToPath:]
> 2.72 s  88.7%	0 s	                         -[NSBezierPath 
> _enumeratePathElementsUsingBlock:]
> 2.72 s  88.7%	0 s	                          CGPathApplyWithBlock2
> 2.72 s  88.7%	5.00 ms	                           CG::Path::apply(void 
> (CGPathElementType, CGPoint const*, bool*) block_pointer) const
> 2.71 s  88.5%	30.00 ms	 
> __CGPathApplyWithBlock2_block_invoke
> 2.68 s  87.4%	11.00 ms	                             __49-[NSBezierPath 
> _enumeratePathElementsUsingBlock:]_block_invoke
> 2.48 s  80.8%	1.00 ms	 
> -[NSBezierPath(NSBezierPathDevicePrimitives) _deviceMoveToPoint:]
> 2.47 s  80.6%	2.00 ms	                               CGPathMoveToPoint
> 2.46 s  80.3%	2.46 s	 
> CG::Path::recalculate_bounding_box()
> 5.00 ms   0.2%	4.00 ms	 
> CG::Path::move_to_point(CGPoint const&, CGAffineTransform const*)
> 1.00 ms   0.0%	1.00 ms	 
> CG::Path::convert_to_huge()
> 2.00 ms   0.1%	2.00 ms	                                (anonymous 
> namespace)::transform_is_valid(CGAffineTransform const*)
> 1.00 ms   0.0%	1.00 ms	 
> CG::Path::convert_to_huge()
> 1.00 ms   0.0%	1.00 ms	 
> CGFloatValidateWithLog
> 1.00 ms   0.0%	1.00 ms	 
> DYLD-STUB$$CGPathMoveToPoint
> 1.00 ms   0.0%	1.00 ms	                               -[NSBezierPath 
> _cgPath]
> 1.00 ms   0.0%	1.00 ms	                               objc_msgSend
> 1.00 ms   0.0%	1.00 ms	                               (anonymous 
> namespace)::transform_is_valid(CGAffineTransform const*)
> 67.00 ms   2.2%	7.00 ms	 
> -[NSBezierPath(NSBezierPathDevicePrimitives) _deviceLineToPoint:]
> 40.00 ms   1.3%	5.00 ms	 
> -[NSBezierPath(NSBezierPathDevicePrimitives) _deviceClosePath]
> 39.00 ms   1.3%	2.00 ms	                              -[NSBezierPath 
> lineToPoint:]
> 14.00 ms   0.5%	14.00 ms	                              objc_msgSend
> 6.00 ms   0.2%	6.00 ms	                              -[NSBezierPath _cgPath]
> 5.00 ms   0.2%	5.00 ms	                              CGPathAddLineToPoint
> 4.00 ms   0.1%	4.00 ms	                              __30-[NSBezierPath 
> _appendToPath:]_block_invoke
> 4.00 ms   0.1%	4.00 ms	 
> objc_msgSend$lineToPoint:
> 2.00 ms   0.1%	2.00 ms	                              CGPathIsEmpty
> 2.00 ms   0.1%	2.00 ms	 
> objc_msgSend$moveToPoint:
> 2.00 ms   0.1%	2.00 ms	 
> CG::Path::close_subpath()
> 1.00 ms   0.0%	1.00 ms	 
> objc_msgSend$_deviceLineToPoint:
> 1.00 ms   0.0%	1.00 ms	                              CGPathGetCurrentPoint
> 1.00 ms   0.0%	1.00 ms	                              -[NSBezierPath 
> moveToPoint:]
> 1.00 ms   0.0%	1.00 ms	 
> objc_msgSend$_deviceClosePath
> 1.00 ms   0.0%	1.00 ms	                              objc_msgSend$closePath
> 1.00 ms   0.0%	1.00 ms	 
> objc_msgSend$_deviceMoveToPoint:
> 3.00 ms   0.1%	3.00 ms	                             -[NSBezierPath 
> lineToPoint:]
> 1.00 ms   0.0%	1.00 ms	 
> -[NSBezierPath(NSBezierPathDevicePrimitives) _deviceLineToPoint:]
> 2.00 ms   0.1%	2.00 ms	                            __49-[NSBezierPath 
> _enumeratePathElementsUsingBlock:]_block_invoke
> 1.00 ms   0.0%	1.00 ms	                        objc_msgSend$setFlatness:
> 104.00 ms   3.4%	0 s	                       -[NSBezierPath fill]
> 42.00 ms   1.4%	0 s	                       -[NSBezierPath 
> transformUsingAffineTransform:]
> 7.00 ms   0.2%	0 s	                       NSRectFill
> 2.00 ms   0.1%	0 s	                       NSColorSetWithFillAndStroke
> 1.00 ms   0.0%	1.00 ms	                       CGContextClipToRect
> 1.00 ms   0.0%	0 s	                       -[NSBezierPath dealloc]
> 1.00 ms   0.0%	1.00 ms	                       CGGStateSetCompositeOperation
> 1.00 ms   0.0%	1.00 ms	                      lookup_named_face
> 5.00 ms   0.2%	4.00 ms	                    set_buffer_internal_2
> 1.00 ms   0.0%	0 s	                   unblock_input
> 1.00 ms   0.0%	0 s	                   ns_draw_window_cursor
> 121.00 ms   3.9%	0 s	                  ns_scroll_run
> 51.00 ms   1.7%	1.00 ms	                  update_window_line
> 4.00 ms   0.1%	4.00 ms	                  row_equal_p
> 1.00 ms   0.0%	1.00 ms	                  xwidget_end_redisplay
> 1.00 ms   0.0%	0 s	                ns_update_end
> 
> 
> 
> Patch:
> 
> --- src/nsimage.m.orig
> +++ src/nsimage.m
> @@ -28,6 +28,7 @@ Updated by Christian Limpach (chris@HIDDEN)
>   /* This should be the first include, as it may set up #defines affecting
>      interpretation of even the system includes.  */
>   #include <config.h>
> +#include <CoreGraphics/CoreGraphics.h>
> 
>   #include "lisp.h"
>   #include "dispextern.h"
> @@ -510,10 +511,20 @@ - (void) setAlphaAtX: (int) x Y: (int) y to: 
> (unsigned char) a
>   }
> 
>   /* Returns a pattern color, which is cached here.  */
> -- (NSColor *)stippleMask
> +- (CGImageRef)stippleMask
>   {
> -  if (stippleMask == nil)
> -      stippleMask = [[NSColor colorWithPatternImage: self] retain];
> +  if (stippleMask == nil) {
> +    CGDataProviderRef provider = CGDataProviderCreateWithData (NULL, 
> [bmRep bitmapData],
> +                                                             [self 
> sizeInBytes], NULL);
> +    id mask = (id)CGImageMaskCreate(
> +                                          [self size].width,
> +                                          [self size].height,
> +                                          8, 8, [self size].width,
> +                                          provider, NULL, 0);
> +
> +    CGDataProviderRelease(provider);
> +    stippleMask = (CGImageRef)[mask retain];
> +  }
>     return stippleMask;
>   }
> 
> --- src/nsterm.h.orig
> +++ src/nsterm.h
> @@ -670,7 +670,7 @@ enum ns_return_frame_mode
>   {
>     NSBitmapImageRep *bmRep; /* used for accessing pixel data */
>     unsigned char *pixmapData[5]; /* shortcut to access pixel data */
> -  NSColor *stippleMask;
> +  CGImageRef stippleMask;
>   @public
>     NSAffineTransform *transform;
>     BOOL smoothing;
> @@ -687,8 +687,8 @@ enum ns_return_frame_mode
>                  green: (unsigned char)g blue: (unsigned char)b
>                 alpha:(unsigned char)a;
>   - (void)setAlphaAtX: (int)x Y: (int)y to: (unsigned char)a;
> -- (NSColor *)stippleMask;
> +- (CGImageRef)stippleMask;
>   - (Lisp_Object)getMetadata;
>   - (BOOL)setFrame: (unsigned int) index;
>   - (void)setTransform: (double[3][3]) m;
> 
> --- src/nsterm.m.orig
> +++ src/nsterm.m
> @@ -2903,22 +2903,24 @@ Hide the window (X11 semantics)
>   static void
>   ns_define_fringe_bitmap (int which, unsigned short *bits, int h, int w)
>   {
> -  NSBezierPath *p = [NSBezierPath bezierPath];
> -
>     if (!fringe_bmp)
>       fringe_bmp = [[NSMutableDictionary alloc] initWithCapacity:25];
> 
> -  [p moveToPoint:NSMakePoint (0, 0)];
> 
> -  for (int y = 0 ; y < h ; y++)
> -    for (int x = 0 ; x < w ; x++)
> -      {
> -        bool bit = bits[y] & (1 << (w - x - 1));
> -        if (bit)
> -          [p appendBezierPathWithRect:NSMakeRect (x, y, 1, 1)];
> -      }
> +  for (int i = 0; i < h; i++)
> +    bits[i] = ~bits[i];
> +
> +  CGDataProviderRef provider = CGDataProviderCreateWithData (NULL, bits,
> +					   sizeof (unsigned short) * h, NULL);
> +  if (provider) {
> +    id p = (id)CGImageMaskCreate (w, h, 1, 1,
> +                 sizeof (unsigned short),
> +                 provider, NULL, 0);
> +    CGDataProviderRelease (provider);
> +
> +    [fringe_bmp setObject:p forKey:[NSNumber numberWithInt:which]];
> +  }
> 
> -  [fringe_bmp setObject:p forKey:[NSNumber numberWithInt:which]];
>   }
> 
> 
> @@ -2981,26 +2983,29 @@ Hide the window (X11 semantics)
>         NSRectFill (clearRect);
>       }
> 
> -  NSBezierPath *bmp = [fringe_bmp objectForKey:[NSNumber 
> numberWithInt:p->which]];
> +  CGImageRef bmp = (CGImageRef)[fringe_bmp objectForKey:[NSNumber 
> numberWithInt:p->which]];
> 
>     if (bmp == nil
>         && p->which < max_used_fringe_bitmap)
>       {
>         gui_define_fringe_bitmap (f, p->which);
> -      bmp = [fringe_bmp objectForKey: [NSNumber numberWithInt: p->which]];
> +      bmp = (CGImageRef)[fringe_bmp objectForKey: [NSNumber 
> numberWithInt: p->which]];
>       }
> 
>     if (bmp)
>       {
> -      NSAffineTransform *transform = [NSAffineTransform transform];
> -      NSColor *bm_color;
> +      CGRect bounds = CGRectMake (p->x, p->y - p->dh,
> +			   CGImageGetWidth (bmp), CGImageGetHeight (bmp));
> +
> +      NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
> +      [ctx saveGraphicsState];
> +      CGContextRef context = [ctx CGContext];
> 
> -      /* Because the image is defined at (0, 0) we need to take a copy
> -         and then transform that copy to the new origin.  */
> -      bmp = [bmp copy];
> -      [transform translateXBy:p->x yBy:p->y - p->dh];
> -      [bmp transformUsingAffineTransform:transform];
> +      CGContextTranslateCTM (context,
> +			     CGRectGetMinX (bounds), CGRectGetMaxY (bounds));
> +      CGContextScaleCTM (context, 1, -1);
> 
> +      NSColor *bm_color;
>         if (!p->cursor_p)
>           bm_color = [NSColor colorWithUnsignedLong:face->foreground];
>         else if (p->overlay_p)
> @@ -3009,9 +3014,10 @@ Hide the window (X11 semantics)
>           bm_color = f->output_data.ns->cursor_color;
> 
>         [bm_color set];
> -      [bmp fill];
> +      bounds.origin = CGPointZero;
> +      CGContextDrawImage (context, bounds, bmp);
> 
> -      [bmp release];
> +      [[NSGraphicsContext currentContext] restoreGraphicsState];
>       }
>     ns_unfocus (f);
>   }
> @@ -3273,11 +3279,10 @@ Note that CURSOR_WIDTH is meaningful only for 
> (h)bar cursors.
>   ns_draw_underwave (struct glyph_string *s, EmacsCGFloat width, 
> EmacsCGFloat x)
>   {
>     int wave_height = 3, wave_length = 2;
> -  int y, dx, dy, odd, xmax;
> -  NSPoint a, b;
> +  int y, dx, dy, xmax;
>     NSRect waveClip;
> 
> -  dx = wave_length;
> +  dx = wave_length * 2;
>     dy = wave_height - 1;
>     y =  s->ybase - wave_height + 3;
>     xmax = x + width;
> @@ -3287,25 +3292,24 @@ Note that CURSOR_WIDTH is meaningful only for 
> (h)bar cursors.
>     [[NSGraphicsContext currentContext] saveGraphicsState];
>     NSRectClip (waveClip);
> 
> -  /* Draw the waves */
> -  a.x = x - ((int)(x) % dx) + (EmacsCGFloat) 0.5;
> -  b.x = a.x + dx;
> -  odd = (int)(a.x/dx) % 2;
> -  a.y = b.y = y + 0.5;
> +  float ax = x - ((int)(x) % dx);
> +  float ay = y + wave_height / 2.0;
> 
> -  if (odd)
> -    a.y += dy;
> -  else
> -    b.y += dy;
> +  NSBezierPath *path = [[NSBezierPath alloc] init];
> +  [path moveToPoint: (NSPoint){ ax, ay }];
> +
> +  NSPoint stepOne = { dx, 0 };
> +  NSPoint controlOne = { 0.5 * dx, dy };
> +  NSPoint controlTwo = { 0.5 * dx, -dy };
> 
> -  while (a.x <= xmax)
> +  while (ax <= xmax)
>       {
> -      [NSBezierPath strokeLineFromPoint:a toPoint:b];
> -      a.x = b.x, a.y = b.y;
> -      b.x += dx, b.y = y + 0.5 + odd*dy;
> -      odd = !odd;
> +      [path relativeCurveToPoint:stepOne controlPoint1:controlOne 
> controlPoint2:controlTwo];
> +      ax += dx;
>       }
> 
> +  [path stroke];
> +
>     /* Restore previous clipping rectangle(s) */
>     [[NSGraphicsContext currentContext] restoreGraphicsState];
>   }
> @@ -3825,10 +3829,35 @@ Function modeled after x_draw_glyph_string_box ().
>         int box_line_width = max (s->face->box_horizontal_line_width, 0);
> 
>         if (s->stippled_p)
> -	{
> -	  struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
> -	  [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
> -	  goto fill;
> +        {
> +          [[NSColor colorWithUnsignedLong:face->background] set];
> +          r = NSMakeRect (s->x, s->y + box_line_width,
> +                          s->background_width,
> +                          s->height - 2 * box_line_width);
> +          NSRectFill (r);
> +          s->background_filled_p = 1;
> +
> +          struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
> +          CGImageRef mask =
> +            [dpyinfo->bitmaps[face->stipple - 1].img stippleMask];
> +
> +          CGRect bounds = CGRectMake (s->x, s->y + box_line_width,
> +                                      s->background_width,
> +                                      s->height - 2 * box_line_width);
> +          NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
> +          [ctx saveGraphicsState];
> +          CGContextRef context = [ctx CGContext];
> +
> +          CGContextClipToRect (context, bounds);
> +
> +          CGContextScaleCTM (context, 1, -1);
> +          [[NSColor colorWithUnsignedLong:face->foreground] set];
> +
> +          CGRect imageSize = CGRectMake (0, 0, CGImageGetWidth (mask),
> +                                         CGImageGetHeight (mask));
> +
> +          CGContextDrawTiledImage (context, imageSize, mask);
> +          [[NSGraphicsContext currentContext] restoreGraphicsState];
>   	}
>         else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
>   	       /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font
> @@ -3851,7 +3880,6 @@ Function modeled after x_draw_glyph_string_box ().
>   	  else
>   	    [FRAME_CURSOR_COLOR (s->f) set];
> 
> -	fill:
>   	  r = NSMakeRect (s->x, s->y + box_line_width,
>   			  s->background_width,
>   			  s->height - 2 * box_line_width);
> @@ -4175,12 +4203,42 @@ Function modeled after x_draw_glyph_string_box ().
>   	  dpyinfo = FRAME_DISPLAY_INFO (s->f);
>   	  if (s->hl == DRAW_CURSOR)
>   	    [FRAME_CURSOR_COLOR (s->f) set];
> -	  else if (s->stippled_p)
> -	    [[dpyinfo->bitmaps[s->face->stipple - 1].img stippleMask] set];
> -	  else
> +	  else if (s->stippled_p) {
> +              [[NSColor colorWithUnsignedLong:s->face->background]
> +                set];
> +              NSRectFill (
> +                NSMakeRect (x, s->y, background_width, s->height));
> +
> +              CGImageRef mask =
> +                [dpyinfo->bitmaps[s->face->stipple - 1]
> +                    .img stippleMask];
> +
> +              CGRect bounds
> +                = CGRectMake (s->x, s->y, s->background_width,
> +                              s->height);
> +
> +              NSGraphicsContext *ctx =
> +                [NSGraphicsContext currentContext];
> +              [ctx saveGraphicsState];
> +              CGContextRef context = [ctx CGContext];
> +              CGContextClipToRect(context, bounds);
> +              CGContextScaleCTM (context, 1, -1);
> +              [[NSColor colorWithUnsignedLong:s->face->foreground]
> +                set];
> +
> +              CGRect imageSize
> +                = CGRectMake (0, 0, CGImageGetWidth (mask),
> +                              CGImageGetHeight (mask));
> +
> +              CGContextDrawTiledImage (context, imageSize, mask);
> +
> +              [[NSGraphicsContext currentContext]
> +		restoreGraphicsState];
> +	    }
> +	  else {
>   	    [[NSColor colorWithUnsignedLong: s->face->background] set];
> -
> -	  NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
> +            NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
> +          }
>   	}
>       }
> 
> 
> 
> 
> 




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#73563; Package emacs. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 13 May 2025 11:39:07 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Tue May 13 07:39:07 2025
Received: from localhost ([127.0.0.1]:58359 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1uEnyU-0008P7-16
	for submit <at> debbugs.gnu.org; Tue, 13 May 2025 07:39:06 -0400
Received: from lists.gnu.org ([2001:470:142::17]:38732)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <jc+o.emacs@HIDDEN>) id 1uEnyN-0008Nt-72
 for submit <at> debbugs.gnu.org; Tue, 13 May 2025 07:39:03 -0400
Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <jc+o.emacs@HIDDEN>) id 1uEnxz-0005VF-9B
 for bug-gnu-emacs@HIDDEN; Tue, 13 May 2025 07:38:35 -0400
Received: from out-186.mta0.migadu.com ([2001:41d0:1004:224b::ba])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <jc+o.emacs@HIDDEN>) id 1uEnxp-0000tL-SM
 for bug-gnu-emacs@HIDDEN; Tue, 13 May 2025 07:38:32 -0400
Message-ID: <d3fd9db3-d93b-4f80-b216-3818383212d0@HIDDEN>
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wz.ht; s=key1;
 t=1747136282;
 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;
 bh=rzN7ea6eXWRz99KqphfMw5GnHYIrFRDFe66WWSVkzRU=;
 b=azg8Wk7S9KRiyGO2SdRl2Gh9PisBpTiJG0a0gEyoEnENrxsdMMG4ya4d9G3fAflMEjXL20
 NcIROn3L3v0J21+2NYAowMrLjDHYzoT65vvW6quOseT2pAAoLO7NuXN2YwQL+TQZi0WC/U
 Zf82AnXZy12oNZ4l3FGz5A7yAl4y2bA=
Date: Tue, 13 May 2025 20:37:55 +0900
MIME-Version: 1.0
Content-Language: en-US
To: Emacs Bugs <bug-gnu-emacs@HIDDEN>
X-Report-Abuse: Please report any abuse attempt to abuse@HIDDEN and
 include these headers.
From: Jordan Ellis Coppard <jc+o.emacs@HIDDEN>
Subject: bug#73563: [Ben Simms] Performance bottleneck in ns_draw_fringe_bitmap
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
X-Migadu-Flow: FLOW_OUT
Received-SPF: pass client-ip=2001:41d0:1004:224b::ba;
 envelope-from=jc+o.emacs@HIDDEN; helo=out-186.mta0.migadu.com
X-Spam_score_int: -20
X-Spam_score: -2.1
X-Spam_bar: --
X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001,
 SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-Spam-Score: 0.9 (/)
X-Debbugs-Envelope-To: submit
Cc: Ben Simms <ben@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.1 (/)

Howdy,


I've been using the following patch (bottom of this email) until my most 
recent rebuild of Emacs from master. Since the recent commit fixing 
stipple drawing the patch can be reduced to just: 
https://github.com/emacs-mirror/emacs/commit/7f2efe6503fdce2a4e552c14802644a05b581bc7 
(link to a diff authored by Ben Simms).

I've now noticed again extreme slowdown when fringe bitmaps are used. It 
appears to be proportional to the number of bits set in the bitmap. An 
'empty' bitmap (all zeroes) doesn't yield any noticeable slowdown, a 
bitmap with 1 bit set yields a little, with 2 its noticeable and with 
all 8 bits set Emacs takes up to 1 second to respond to any input at all.

This has been the case since at least August of last year. I can get a 
minimal reproduction but it has happened on completely different 
configurations with the only common denominator being the NS build (on 
ARM-based macOS), and the use of fringe bitmaps.

Below is trace with update_frame as the root context. Captured with 
Instruments.app (which uses dtrace and more under the hood IIRC).

ns_draw_fringe_bitmap takes up 94% of the time for the short 
reproduction this trace records. The deepest the trace goes is to 
CG::Path::recalculate_bounding_box() which eats 80% of time. So instead 
of a cached value the bounding box is being recalculated every time 
which appears very expensive, but beyond that I have close to zero 
experience with macOS' graphics stack.

I've just recompiled Emacs against the same commit of my recent master 
build (648453c04d9b91d96452b930c0c948b0b39b5dc0) except now with the 
patch applied (since the stipple changes are merged it's just the 
smallest subset: 
https://github.com/emacs-mirror/emacs/commit/7f2efe6503fdce2a4e552c14802644a05b581bc7) 
and once again fringe performance is back to being buttery smooth.


(trace also here in-case formatting gets borked:
trace:

3.07 s  100.0%	0 s	               update_frame
3.06 s  100.0%	0 s	                update_window_tree
3.06 s  100.0%	1.00 ms	                 update_window
2.89 s  94.2%	0 s	                  gui_update_window_end
2.88 s  94.1%	0 s	                   draw_window_fringes
2.88 s  93.9%	0 s	                    draw_fringe_bitmap
2.88 s  93.9%	0 s	                     draw_fringe_bitmap_1
2.88 s  93.9%	0 s	                      ns_draw_fringe_bitmap
2.72 s  88.7%	0 s	                       -[NSBezierPath copyWithZone:]
2.72 s  88.7%	0 s	                        -[NSBezierPath _appendToPath:]
2.72 s  88.7%	0 s	                         -[NSBezierPath 
_enumeratePathElementsUsingBlock:]
2.72 s  88.7%	0 s	                          CGPathApplyWithBlock2
2.72 s  88.7%	5.00 ms	                           CG::Path::apply(void 
(CGPathElementType, CGPoint const*, bool*) block_pointer) const
2.71 s  88.5%	30.00 ms	 
__CGPathApplyWithBlock2_block_invoke
2.68 s  87.4%	11.00 ms	                             __49-[NSBezierPath 
_enumeratePathElementsUsingBlock:]_block_invoke
2.48 s  80.8%	1.00 ms	 
-[NSBezierPath(NSBezierPathDevicePrimitives) _deviceMoveToPoint:]
2.47 s  80.6%	2.00 ms	                               CGPathMoveToPoint
2.46 s  80.3%	2.46 s	 
CG::Path::recalculate_bounding_box()
5.00 ms   0.2%	4.00 ms	 
CG::Path::move_to_point(CGPoint const&, CGAffineTransform const*)
1.00 ms   0.0%	1.00 ms	 
CG::Path::convert_to_huge()
2.00 ms   0.1%	2.00 ms	                                (anonymous 
namespace)::transform_is_valid(CGAffineTransform const*)
1.00 ms   0.0%	1.00 ms	 
CG::Path::convert_to_huge()
1.00 ms   0.0%	1.00 ms	 
CGFloatValidateWithLog
1.00 ms   0.0%	1.00 ms	 
DYLD-STUB$$CGPathMoveToPoint
1.00 ms   0.0%	1.00 ms	                               -[NSBezierPath 
_cgPath]
1.00 ms   0.0%	1.00 ms	                               objc_msgSend
1.00 ms   0.0%	1.00 ms	                               (anonymous 
namespace)::transform_is_valid(CGAffineTransform const*)
67.00 ms   2.2%	7.00 ms	 
-[NSBezierPath(NSBezierPathDevicePrimitives) _deviceLineToPoint:]
40.00 ms   1.3%	5.00 ms	 
-[NSBezierPath(NSBezierPathDevicePrimitives) _deviceClosePath]
39.00 ms   1.3%	2.00 ms	                              -[NSBezierPath 
lineToPoint:]
14.00 ms   0.5%	14.00 ms	                              objc_msgSend
6.00 ms   0.2%	6.00 ms	                              -[NSBezierPath _cgPath]
5.00 ms   0.2%	5.00 ms	                              CGPathAddLineToPoint
4.00 ms   0.1%	4.00 ms	                              __30-[NSBezierPath 
_appendToPath:]_block_invoke
4.00 ms   0.1%	4.00 ms	 
objc_msgSend$lineToPoint:
2.00 ms   0.1%	2.00 ms	                              CGPathIsEmpty
2.00 ms   0.1%	2.00 ms	 
objc_msgSend$moveToPoint:
2.00 ms   0.1%	2.00 ms	 
CG::Path::close_subpath()
1.00 ms   0.0%	1.00 ms	 
objc_msgSend$_deviceLineToPoint:
1.00 ms   0.0%	1.00 ms	                              CGPathGetCurrentPoint
1.00 ms   0.0%	1.00 ms	                              -[NSBezierPath 
moveToPoint:]
1.00 ms   0.0%	1.00 ms	 
objc_msgSend$_deviceClosePath
1.00 ms   0.0%	1.00 ms	                              objc_msgSend$closePath
1.00 ms   0.0%	1.00 ms	 
objc_msgSend$_deviceMoveToPoint:
3.00 ms   0.1%	3.00 ms	                             -[NSBezierPath 
lineToPoint:]
1.00 ms   0.0%	1.00 ms	 
-[NSBezierPath(NSBezierPathDevicePrimitives) _deviceLineToPoint:]
2.00 ms   0.1%	2.00 ms	                            __49-[NSBezierPath 
_enumeratePathElementsUsingBlock:]_block_invoke
1.00 ms   0.0%	1.00 ms	                        objc_msgSend$setFlatness:
104.00 ms   3.4%	0 s	                       -[NSBezierPath fill]
42.00 ms   1.4%	0 s	                       -[NSBezierPath 
transformUsingAffineTransform:]
7.00 ms   0.2%	0 s	                       NSRectFill
2.00 ms   0.1%	0 s	                       NSColorSetWithFillAndStroke
1.00 ms   0.0%	1.00 ms	                       CGContextClipToRect
1.00 ms   0.0%	0 s	                       -[NSBezierPath dealloc]
1.00 ms   0.0%	1.00 ms	                       CGGStateSetCompositeOperation
1.00 ms   0.0%	1.00 ms	                      lookup_named_face
5.00 ms   0.2%	4.00 ms	                    set_buffer_internal_2
1.00 ms   0.0%	0 s	                   unblock_input
1.00 ms   0.0%	0 s	                   ns_draw_window_cursor
121.00 ms   3.9%	0 s	                  ns_scroll_run
51.00 ms   1.7%	1.00 ms	                  update_window_line
4.00 ms   0.1%	4.00 ms	                  row_equal_p
1.00 ms   0.0%	1.00 ms	                  xwidget_end_redisplay
1.00 ms   0.0%	0 s	                ns_update_end



Patch:

--- src/nsimage.m.orig
+++ src/nsimage.m
@@ -28,6 +28,7 @@ Updated by Christian Limpach (chris@HIDDEN)
  /* This should be the first include, as it may set up #defines affecting
     interpretation of even the system includes.  */
  #include <config.h>
+#include <CoreGraphics/CoreGraphics.h>

  #include "lisp.h"
  #include "dispextern.h"
@@ -510,10 +511,20 @@ - (void) setAlphaAtX: (int) x Y: (int) y to: 
(unsigned char) a
  }

  /* Returns a pattern color, which is cached here.  */
-- (NSColor *)stippleMask
+- (CGImageRef)stippleMask
  {
-  if (stippleMask == nil)
-      stippleMask = [[NSColor colorWithPatternImage: self] retain];
+  if (stippleMask == nil) {
+    CGDataProviderRef provider = CGDataProviderCreateWithData (NULL, 
[bmRep bitmapData],
+                                                             [self 
sizeInBytes], NULL);
+    id mask = (id)CGImageMaskCreate(
+                                          [self size].width,
+                                          [self size].height,
+                                          8, 8, [self size].width,
+                                          provider, NULL, 0);
+
+    CGDataProviderRelease(provider);
+    stippleMask = (CGImageRef)[mask retain];
+  }
    return stippleMask;
  }

--- src/nsterm.h.orig
+++ src/nsterm.h
@@ -670,7 +670,7 @@ enum ns_return_frame_mode
  {
    NSBitmapImageRep *bmRep; /* used for accessing pixel data */
    unsigned char *pixmapData[5]; /* shortcut to access pixel data */
-  NSColor *stippleMask;
+  CGImageRef stippleMask;
  @public
    NSAffineTransform *transform;
    BOOL smoothing;
@@ -687,8 +687,8 @@ enum ns_return_frame_mode
                 green: (unsigned char)g blue: (unsigned char)b
                alpha:(unsigned char)a;
  - (void)setAlphaAtX: (int)x Y: (int)y to: (unsigned char)a;
-- (NSColor *)stippleMask;
+- (CGImageRef)stippleMask;
  - (Lisp_Object)getMetadata;
  - (BOOL)setFrame: (unsigned int) index;
  - (void)setTransform: (double[3][3]) m;

--- src/nsterm.m.orig
+++ src/nsterm.m
@@ -2903,22 +2903,24 @@ Hide the window (X11 semantics)
  static void
  ns_define_fringe_bitmap (int which, unsigned short *bits, int h, int w)
  {
-  NSBezierPath *p = [NSBezierPath bezierPath];
-
    if (!fringe_bmp)
      fringe_bmp = [[NSMutableDictionary alloc] initWithCapacity:25];

-  [p moveToPoint:NSMakePoint (0, 0)];

-  for (int y = 0 ; y < h ; y++)
-    for (int x = 0 ; x < w ; x++)
-      {
-        bool bit = bits[y] & (1 << (w - x - 1));
-        if (bit)
-          [p appendBezierPathWithRect:NSMakeRect (x, y, 1, 1)];
-      }
+  for (int i = 0; i < h; i++)
+    bits[i] = ~bits[i];
+
+  CGDataProviderRef provider = CGDataProviderCreateWithData (NULL, bits,
+					   sizeof (unsigned short) * h, NULL);
+  if (provider) {
+    id p = (id)CGImageMaskCreate (w, h, 1, 1,
+                 sizeof (unsigned short),
+                 provider, NULL, 0);
+    CGDataProviderRelease (provider);
+
+    [fringe_bmp setObject:p forKey:[NSNumber numberWithInt:which]];
+  }

-  [fringe_bmp setObject:p forKey:[NSNumber numberWithInt:which]];
  }


@@ -2981,26 +2983,29 @@ Hide the window (X11 semantics)
        NSRectFill (clearRect);
      }

-  NSBezierPath *bmp = [fringe_bmp objectForKey:[NSNumber 
numberWithInt:p->which]];
+  CGImageRef bmp = (CGImageRef)[fringe_bmp objectForKey:[NSNumber 
numberWithInt:p->which]];

    if (bmp == nil
        && p->which < max_used_fringe_bitmap)
      {
        gui_define_fringe_bitmap (f, p->which);
-      bmp = [fringe_bmp objectForKey: [NSNumber numberWithInt: p->which]];
+      bmp = (CGImageRef)[fringe_bmp objectForKey: [NSNumber 
numberWithInt: p->which]];
      }

    if (bmp)
      {
-      NSAffineTransform *transform = [NSAffineTransform transform];
-      NSColor *bm_color;
+      CGRect bounds = CGRectMake (p->x, p->y - p->dh,
+			   CGImageGetWidth (bmp), CGImageGetHeight (bmp));
+
+      NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
+      [ctx saveGraphicsState];
+      CGContextRef context = [ctx CGContext];

-      /* Because the image is defined at (0, 0) we need to take a copy
-         and then transform that copy to the new origin.  */
-      bmp = [bmp copy];
-      [transform translateXBy:p->x yBy:p->y - p->dh];
-      [bmp transformUsingAffineTransform:transform];
+      CGContextTranslateCTM (context,
+			     CGRectGetMinX (bounds), CGRectGetMaxY (bounds));
+      CGContextScaleCTM (context, 1, -1);

+      NSColor *bm_color;
        if (!p->cursor_p)
          bm_color = [NSColor colorWithUnsignedLong:face->foreground];
        else if (p->overlay_p)
@@ -3009,9 +3014,10 @@ Hide the window (X11 semantics)
          bm_color = f->output_data.ns->cursor_color;

        [bm_color set];
-      [bmp fill];
+      bounds.origin = CGPointZero;
+      CGContextDrawImage (context, bounds, bmp);

-      [bmp release];
+      [[NSGraphicsContext currentContext] restoreGraphicsState];
      }
    ns_unfocus (f);
  }
@@ -3273,11 +3279,10 @@ Note that CURSOR_WIDTH is meaningful only for 
(h)bar cursors.
  ns_draw_underwave (struct glyph_string *s, EmacsCGFloat width, 
EmacsCGFloat x)
  {
    int wave_height = 3, wave_length = 2;
-  int y, dx, dy, odd, xmax;
-  NSPoint a, b;
+  int y, dx, dy, xmax;
    NSRect waveClip;

-  dx = wave_length;
+  dx = wave_length * 2;
    dy = wave_height - 1;
    y =  s->ybase - wave_height + 3;
    xmax = x + width;
@@ -3287,25 +3292,24 @@ Note that CURSOR_WIDTH is meaningful only for 
(h)bar cursors.
    [[NSGraphicsContext currentContext] saveGraphicsState];
    NSRectClip (waveClip);

-  /* Draw the waves */
-  a.x = x - ((int)(x) % dx) + (EmacsCGFloat) 0.5;
-  b.x = a.x + dx;
-  odd = (int)(a.x/dx) % 2;
-  a.y = b.y = y + 0.5;
+  float ax = x - ((int)(x) % dx);
+  float ay = y + wave_height / 2.0;

-  if (odd)
-    a.y += dy;
-  else
-    b.y += dy;
+  NSBezierPath *path = [[NSBezierPath alloc] init];
+  [path moveToPoint: (NSPoint){ ax, ay }];
+
+  NSPoint stepOne = { dx, 0 };
+  NSPoint controlOne = { 0.5 * dx, dy };
+  NSPoint controlTwo = { 0.5 * dx, -dy };

-  while (a.x <= xmax)
+  while (ax <= xmax)
      {
-      [NSBezierPath strokeLineFromPoint:a toPoint:b];
-      a.x = b.x, a.y = b.y;
-      b.x += dx, b.y = y + 0.5 + odd*dy;
-      odd = !odd;
+      [path relativeCurveToPoint:stepOne controlPoint1:controlOne 
controlPoint2:controlTwo];
+      ax += dx;
      }

+  [path stroke];
+
    /* Restore previous clipping rectangle(s) */
    [[NSGraphicsContext currentContext] restoreGraphicsState];
  }
@@ -3825,10 +3829,35 @@ Function modeled after x_draw_glyph_string_box ().
        int box_line_width = max (s->face->box_horizontal_line_width, 0);

        if (s->stippled_p)
-	{
-	  struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
-	  [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set];
-	  goto fill;
+        {
+          [[NSColor colorWithUnsignedLong:face->background] set];
+          r = NSMakeRect (s->x, s->y + box_line_width,
+                          s->background_width,
+                          s->height - 2 * box_line_width);
+          NSRectFill (r);
+          s->background_filled_p = 1;
+
+          struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f);
+          CGImageRef mask =
+            [dpyinfo->bitmaps[face->stipple - 1].img stippleMask];
+
+          CGRect bounds = CGRectMake (s->x, s->y + box_line_width,
+                                      s->background_width,
+                                      s->height - 2 * box_line_width);
+          NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
+          [ctx saveGraphicsState];
+          CGContextRef context = [ctx CGContext];
+
+          CGContextClipToRect (context, bounds);
+
+          CGContextScaleCTM (context, 1, -1);
+          [[NSColor colorWithUnsignedLong:face->foreground] set];
+
+          CGRect imageSize = CGRectMake (0, 0, CGImageGetWidth (mask),
+                                         CGImageGetHeight (mask));
+
+          CGContextDrawTiledImage (context, imageSize, mask);
+          [[NSGraphicsContext currentContext] restoreGraphicsState];
  	}
        else if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
  	       /* When xdisp.c ignores FONT_HEIGHT, we cannot trust font
@@ -3851,7 +3880,6 @@ Function modeled after x_draw_glyph_string_box ().
  	  else
  	    [FRAME_CURSOR_COLOR (s->f) set];

-	fill:
  	  r = NSMakeRect (s->x, s->y + box_line_width,
  			  s->background_width,
  			  s->height - 2 * box_line_width);
@@ -4175,12 +4203,42 @@ Function modeled after x_draw_glyph_string_box ().
  	  dpyinfo = FRAME_DISPLAY_INFO (s->f);
  	  if (s->hl == DRAW_CURSOR)
  	    [FRAME_CURSOR_COLOR (s->f) set];
-	  else if (s->stippled_p)
-	    [[dpyinfo->bitmaps[s->face->stipple - 1].img stippleMask] set];
-	  else
+	  else if (s->stippled_p) {
+              [[NSColor colorWithUnsignedLong:s->face->background]
+                set];
+              NSRectFill (
+                NSMakeRect (x, s->y, background_width, s->height));
+
+              CGImageRef mask =
+                [dpyinfo->bitmaps[s->face->stipple - 1]
+                    .img stippleMask];
+
+              CGRect bounds
+                = CGRectMake (s->x, s->y, s->background_width,
+                              s->height);
+
+              NSGraphicsContext *ctx =
+                [NSGraphicsContext currentContext];
+              [ctx saveGraphicsState];
+              CGContextRef context = [ctx CGContext];
+              CGContextClipToRect(context, bounds);
+              CGContextScaleCTM (context, 1, -1);
+              [[NSColor colorWithUnsignedLong:s->face->foreground]
+                set];
+
+              CGRect imageSize
+                = CGRectMake (0, 0, CGImageGetWidth (mask),
+                              CGImageGetHeight (mask));
+
+              CGContextDrawTiledImage (context, imageSize, mask);
+
+              [[NSGraphicsContext currentContext]
+		restoreGraphicsState];
+	    }
+	  else {
  	    [[NSColor colorWithUnsignedLong: s->face->background] set];
-
-	  NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
+            NSRectFill (NSMakeRect (x, s->y, background_width, s->height));
+          }
  	}
      }





Information forwarded to bug-gnu-emacs@HIDDEN:
bug#73563; Package emacs. Full text available.

Message received at 73563 <at> debbugs.gnu.org:


Received: (at 73563) by debbugs.gnu.org; 30 Sep 2024 12:27:17 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Sep 30 08:27:16 2024
Received: from localhost ([127.0.0.1]:44931 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1svFUi-0007jh-JB
	for submit <at> debbugs.gnu.org; Mon, 30 Sep 2024 08:27:16 -0400
Received: from eggs.gnu.org ([209.51.188.92]:41966)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <eliz@HIDDEN>) id 1svFUg-0007jB-JQ
 for 73563 <at> debbugs.gnu.org; Mon, 30 Sep 2024 08:27:15 -0400
Received: from fencepost.gnu.org ([2001:470:142:3::e])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <eliz@HIDDEN>)
 id 1svFU3-0002rx-K5; Mon, 30 Sep 2024 08:26:35 -0400
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org;
 s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date:
 mime-version; bh=sgpgEVTf7WdE1Nl18d8mqVd6+UV3/Hl+BxkoNBW23GM=; b=lCnMA+IuibSp
 S12j3lTimeBAZKSIy4XBj99Cp37SCkMxfiZzkXoxDZawJ/yhHW9RLplEzuPU79rCER0SNHCm3XEsC
 qxVYJ8qkB/mzedk404dhI7zQHJkadK942uRsyJkaRCVl92RNGs1hHBdmESeT5Fe74FxHNs27L6EuY
 4WbENr0pLyLYlUu+q0HERvyhk/tZ55O+6IRavr514I7cO+lREEGzBVoi4Ej6GUasZZaz3jEspjtZ4
 AQ+hzFltD2ab1o5bbDIAUS1Y1S842XZfALIoFj2HEUFhU+sobwjlhyOoeZaH2vUpuVIeUoQqEGibe
 kNbME89h/vTu5BYx876zbQ==;
Date: Mon, 30 Sep 2024 15:26:31 +0300
Message-Id: <86plol2uq0.fsf@HIDDEN>
From: Eli Zaretskii <eliz@HIDDEN>
To: Stefan Kangas <stefankangas@HIDDEN>
In-Reply-To: <CADwFkmn9fhiU7XfXu5Ku+ouuxH=J+cx73n-APP7Gkq4FdywD0g@HIDDEN>
 (message from Stefan Kangas on Mon, 30 Sep 2024 07:21:03 +0000)
Subject: Re: bug#73563: [Ben Simms] Performance bottleneck in
 ns_draw_fringe_bitmap
References: <CALNBX0aNy78GFVTfR_4O6hdeOcBiFLiKUJSi+kVbciXqLOd+jw@HIDDEN>
 <CADwFkmn9fhiU7XfXu5Ku+ouuxH=J+cx73n-APP7Gkq4FdywD0g@HIDDEN>
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: 73563
Cc: ben@HIDDEN, 73563 <at> debbugs.gnu.org
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

> Cc: Ben Simms <ben@HIDDEN>
> From: Stefan Kangas <stefankangas@HIDDEN>
> Date: Mon, 30 Sep 2024 07:21:03 +0000
> 
> Hi all, I recently started using Emacs (ns) HEAD on an ARM macos sonoma
> system.
> 
> I've noticed that ns_draw_fringe_bitmap is a fairly large performance sink
> when using pixel scrolling (to the point of 99% of cpu time being inside this
> function, with Emacs drawing at approx 5Hz). The slowness here isn't as
> obvious when not pixel scrolling, presumably because Emacs never tries to
> redraw at 60+Hz otherwise.
> 
> I have performed some profiling and discovered that in my observed worse case
> situation, of the 99% of cpu time spent in ns_draw_fringe_bitmap, approx 50%
> is spent in [NSBezierPath copy], and approx 30% in [NSBezierPath fill].

According to the posted profile, ns_draw_fringe_bitmap takes much less
than 99% of CPU time, somewhere around 10%.  What am I missing?




Information forwarded to bug-gnu-emacs@HIDDEN:
bug#73563; Package emacs. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 30 Sep 2024 08:02:59 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Sep 30 04:02:59 2024
Received: from localhost ([127.0.0.1]:44622 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1svBMw-0001Qs-MH
	for submit <at> debbugs.gnu.org; Mon, 30 Sep 2024 04:02:59 -0400
Received: from lists.gnu.org ([209.51.188.17]:50282)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <stefankangas@HIDDEN>) id 1svBMu-0001Qi-Bt
 for submit <at> debbugs.gnu.org; Mon, 30 Sep 2024 04:02:57 -0400
Received: from [2001:470:142:3::10] (helo=eggs.gnu.org)
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <stefankangas@HIDDEN>)
 id 1svAqT-00015S-DX
 for bug-gnu-emacs@HIDDEN; Mon, 30 Sep 2024 03:29:25 -0400
Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <stefankangas@HIDDEN>)
 id 1svApn-0007ve-HO
 for bug-gnu-emacs@HIDDEN; Mon, 30 Sep 2024 03:29:19 -0400
Received: by mail-wr1-x42d.google.com with SMTP id
 ffacd0b85a97d-37ce14ab7eeso1335559f8f.2
 for <bug-gnu-emacs@HIDDEN>; Mon, 30 Sep 2024 00:27:56 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1727681265; x=1728286065; darn=gnu.org;
 h=to:subject:message-id:date:mime-version:references:from:from:to:cc
 :subject:date:message-id:reply-to;
 bh=nca+oUsU+ZdAgNPc7kYpDTpQ1SKouoAfbK4g/qjl0Ec=;
 b=Z84zTd+Cju5fGWCLcHCPiTKUFospdrvzAhUgyk6UmLXkRTVLeIJcpOtgLQD7SPDr2u
 8XkkNwgcOYLs8u+kvrwYbcHmRGOhil41gkFbnOHrb6JvN04I52g99tVRx7YrgI8EZ9ce
 iZ7dBrE8SSeE2ZcFxCJQZf1Ow5E5amAkc96WWhJpZesaTdQo8+8OqgOcriiG+agKL4+b
 zF6QF4we1MDAEAHz1JO5khbTImZ4iLNufUKu7wyxH34MvlnIoOPp31hoSpKBSSaMuWqc
 fJ95jaiSHiSh4BWjEuJ8A8MWjaQoyyeoZncY9h9qErJHxqvH8ut3tKbONHflhtVEnFC/
 1KuQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1727681265; x=1728286065;
 h=to:subject:message-id:date:mime-version:references:from
 :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
 bh=nca+oUsU+ZdAgNPc7kYpDTpQ1SKouoAfbK4g/qjl0Ec=;
 b=BGjlPYZXL9IOalWH+eI3PwUXZz9WdjZ/hhl1J1r9NogTFITS5ErO8Ox5Vc9S8SoF96
 6MHeFSJ4+I/wMtgfKdOsXyHfS+/+Gr6/fxAB7g2eFeJkEFZTeVa/OBnsVsp85C+vlExx
 AcUn9whGseSS+N1XE2ceHjTZXhen1umtuGNdDAPlT5sf7pFQeTaVFIJf/OFav+JNcrY4
 d4XcLFNeTSaEKAiGWW9IPE0SE8ccskWhY3sm7Im97U61EoANdYo8cZjJO8WKIYktFfSR
 yjaa0yGv2wWaLy095Sn0kpcko21JmtkavGe7/XsQPfIVqCkR6VRK7DSOmlin16FdHLez
 vYhw==
X-Gm-Message-State: AOJu0YzwW0jiHSDmQZQZ+VAI9Miy8MtXVYaSIQoadSwBeWsG/oQ6/OTJ
 wEXmX/L9BO1BvINCz7wdPyveEl/SvO5VCR0gBbVK1qpnTywwnvIilijju45VXPCeO5r2AKCr7T6
 Gtf+a7SvLvPENTFF57rq188SLJykDdw==
X-Google-Smtp-Source: AGHT+IEgCABam4U7Nkv5XlRhtMOIgzcBqaOm8+hdRVB1FoXngnil0ijfzOxdvxCGdMzLpmcLY5ybtfNTabRa/RrBu8c=
X-Received: by 2002:a05:6402:909:b0:5c5:b6ee:e95b with SMTP id
 4fb4d7f45d1cf-5c8824d3c0cmr20532107a12.8.1727680863699; Mon, 30 Sep 2024
 00:21:03 -0700 (PDT)
Received: from 753933720722 named unknown by gmailapi.google.com with
 HTTPREST; Mon, 30 Sep 2024 07:21:03 +0000
From: Stefan Kangas <stefankangas@HIDDEN>
References: <CALNBX0aNy78GFVTfR_4O6hdeOcBiFLiKUJSi+kVbciXqLOd+jw@HIDDEN>
X-Debbugs-CC: Ben Simms <ben@HIDDEN>
MIME-Version: 1.0
Date: Mon, 30 Sep 2024 07:21:03 +0000
Message-ID: <CADwFkmn9fhiU7XfXu5Ku+ouuxH=J+cx73n-APP7Gkq4FdywD0g@HIDDEN>
Subject: [Ben Simms] Performance bottleneck in ns_draw_fringe_bitmap
To: bug-gnu-emacs@HIDDEN
Content-Type: multipart/mixed; boundary="0000000000002a887a0623510c8e"
Received-SPF: pass client-ip=2a00:1450:4864:20::42d;
 envelope-from=stefankangas@HIDDEN; helo=mail-wr1-x42d.google.com
X-Spam_score_int: -16
X-Spam_score: -1.7
X-Spam_bar: -
X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1,
 DKIM_SIGNED=0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001,
 T_SPF_HELO_TEMPERROR=0.01,
 T_SPF_TEMPERROR=0.01 autolearn=no autolearn_force=no
X-Spam_action: no action
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

--0000000000002a887a0623510c8e
Content-Type: text/plain; charset="UTF-8"

I'm forwarding this to the bug tracker so that we don't lose track of
it.

Original message:
https://lists.gnu.org/r/emacs-devel/2024-06/msg00900.html

-------------------- Start of forwarded message --------------------
From: Ben Simms <ben@HIDDEN>
Date: Wed, 26 Jun 2024 13:56:43 +0200
Subject: Performance bottleneck in ns_draw_fringe_bitmap
To: emacs-devel@HIDDEN

--0000000000002a887a0623510c8e
Content-Type: text/plain; charset="US-ASCII"
Content-Disposition: attachment
Content-Transfer-Encoding: base64
X-Attachment-Id: 583748d02080dd75_0.2

LS0tLS0tLS0tLS0tLS0tLS0tLS0gRW5kIG9mIGZvcndhcmRlZCBtZXNzYWdlIC0tLS0tLS0tLS0t
LS0tLS0tLS0tCg==
--0000000000002a887a0623510c8e
Content-Type: text/html; charset="utf-8"
Content-Disposition: attachment
Content-Transfer-Encoding: base64
X-Attachment-Id: 583748d02080dd75_0.1.1

PGRpdiBkaXI9Imx0ciI+SGkgYWxsLCBJIHJlY2VudGx5IHN0YXJ0ZWQgdXNpbmcgRW1hY3MgKG5z
KSBIRUFEIG9uIGFuIEFSTSBtYWNvcyBzb25vbWEgc3lzdGVtLjxkaXY+PGJyPjwvZGl2PjxkaXY+
SSYjMzk7dmUgbm90aWNlZCB0aGF0IG5zX2RyYXdfZnJpbmdlX2JpdG1hcCBpcyBhIGZhaXJseSBs
YXJnZSBwZXJmb3JtYW5jZSBzaW5rIHdoZW4gdXNpbmcgcGl4ZWwgc2Nyb2xsaW5nICh0byB0aGUg
cG9pbnQgb2YgOTklIG9mIGNwdSB0aW1lIGJlaW5nIGluc2lkZSB0aGlzIGZ1bmN0aW9uLCB3aXRo
IEVtYWNzIGRyYXdpbmcgYXQgYXBwcm94IDVIeikuIFRoZSBzbG93bmVzcyBoZXJlIGlzbiYjMzk7
dCBhcyBvYnZpb3VzIHdoZW4gbm90IHBpeGVsIHNjcm9sbGluZywgcHJlc3VtYWJseSBiZWNhdXNl
IEVtYWNzIG5ldmVyIHRyaWVzIHRvIHJlZHJhdyBhdCA2MCtIeiBvdGhlcndpc2UuPC9kaXY+PGRp
dj48YnI+PC9kaXY+PGRpdj5JIGhhdmUgcGVyZm9ybWVkIHNvbWUgcHJvZmlsaW5nIGFuZCBkaXNj
b3ZlcmVkIHRoYXQgaW4gbXkgb2JzZXJ2ZWQgd29yc2UgY2FzZSBzaXR1YXRpb24sIG9mIHRoZSA5
OSUgb2YgY3B1IHRpbWUgc3BlbnQgaW4gbnNfZHJhd19mcmluZ2VfYml0bWFwLCBhcHByb3ggNTAl
IGlzIHNwZW50IGluIFtOU0JlemllclBhdGggY29weV0sIGFuZCBhcHByb3ggMzAlIGluIFtOU0Jl
emllclBhdGggZmlsbF0uPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5JIGhhdmUgdXNlZCB0aGUg
Zm9sbG93aW5nIGJlbmNobWFyayB3aXRoIGVtYWNzIC1RIHRvIGF0dGVtcHQgdG8gcmVwcm9kdWNl
IG15IGVuY291bnRlcmVkIHBlcmZvcm1hbmNlIGlzc3VlLCBob3dldmVyIEkgY2Fubm90IHJlcHJv
ZHVjZSBleGFjdGx5IHRoZSBleHRyZW1lIGNhc2UgSSBleHBlcmllbmNlIGluIG15IGNvbmZpZywg
YnV0IEkgaGF2ZSB1c2VkIHRoaXMgYmVuY2htYXJrIHRvIHZhbGlkYXRlIGEgcGF0Y2ggdGhhdCBz
b2x2ZXMgdGhlIHNsb3dkb3duIEkmIzM5O20gZXhwZXJpZW5jaW5nOjwvZGl2PjxkaXY+PGJyPjwv
ZGl2PjxkaXY+KGRlZnVuIHNjcm9sbC11cC1iZW5jaG1hcmsgKCk8YnI+wqAgKGludGVyYWN0aXZl
KTxicj7CoCAobGV0ICgob2xkZ2MgZ2NzLWRvbmUpPGJyPsKgIMKgIMKgIMKgIChvbGR0aW1lIChm
bG9hdC10aW1lKSkpPGJyPsKgIMKgIMKgIChkb3RpbWVzIChfIDEwKSAocGl4ZWwtLXdoaXN0bGVz
dG9wLXBpeGVsLXVwICgqIDUgKHBpeGVsLWxpbmUtaGVpZ2h0KSkpIMKgKHBpeGVsLXNjcm9sbC1w
aXhlbC1kb3duICgqIDUgKHBpeGVsLWxpbmUtaGVpZ2h0KSkpKTxicj7CoCDCoCDCoCAocHJpbmMg
KGZvcm1hdCAmcXVvdDtHQ3M6ICVkIEVsYXBzZWQgdGltZTogJWYgc2Vjb25kc1xuJnF1b3Q7PGJy
PsKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgICgtIGdjcy1kb25lIG9sZGdjKSAo
LSAoZmxvYXQtdGltZSkgb2xkdGltZSkpICMmIzM5O2V4dGVybmFsLWRlYnVnZ2luZy1vdXRwdXQp
KSk8YnI+PGJyPihkZWZ1biBhZGQtZnJpbmdlcyAoKTxicj7CoCAoaW50ZXJhY3RpdmUpPGJyPsKg
IChkb3RpbWVzIChfIDIwKTxicj7CoCDCoCAobmV3bGluZS1hbmQtaW5kZW50KTxicj7CoCDCoCAo
aW5zZXJ0ICZxdW90O0EmcXVvdDspPGJyPsKgIMKgIChnb3RvLWNoYXIgKGxpbmUtYmVnaW5uaW5n
LXBvc2l0aW9uKSk8YnI+wqAgwqAgKGxldCAoKHMgJnF1b3Q7eCZxdW90Oyk8YnI+wqAgwqAgwqAg
wqAgwqAgKGZyaW5nZS1vdmVybGF5IChtYWtlLW92ZXJsYXkgKHBvaW50KSAoMSsgKHBvaW50KSkp
KSk8YnI+wqAgwqAgwqAgKHB1dC10ZXh0LXByb3BlcnR5IDAgMSAmIzM5O2Rpc3BsYXkgKGxpc3Qg
JiMzOTtsZWZ0LWZyaW5nZSAmIzM5O2xlZnQtdHJpYW5nbGUpIHMpPGJyPsKgIMKgIMKgIChvdmVy
bGF5LXB1dCBmcmluZ2Utb3ZlcmxheSAmIzM5O2JlZm9yZS1zdHJpbmcgcykpPGJyPsKgIMKgIChn
b3RvLWNoYXIgKGxpbmUtZW5kLXBvc2l0aW9uKSkpKTxicj48YnI+KHNjcm9sbC1iYXItbW9kZSAt
MSk8YnI+KG1lbnUtYmFyLW1vZGUgLTEpPGJyPihwaXhlbC1zY3JvbGwtbW9kZSk8YnI+KHBpeGVs
LXNjcm9sbC1wcmVjaXNpb24tbW9kZSk8YnI+KHNldHE8YnI+wqAgwqAgwqAgcGl4ZWwtc2Nyb2xs
LXByZWNpc2lvbi11c2UtbW9tZW50dW0gdCk8YnI+PGJyPihkb3RpbWVzIChfIDIwKTxicj7CoCAo
YWRkLWZyaW5nZXMpKTxicj4oZG90aW1lcyAoXyA1KTxicj7CoCAoZW5kLW9mLWJ1ZmZlcik8YnI+
wqAgKGNvbmRpdGlvbi1jYXNlIG5pbCAod2hpbGUgdCAoc2Nyb2xsLWRvd24pKTxicj7CoCDCoCAo
ZXJyb3IgbmlsKSk8YnI+wqAgKHNjcm9sbC11cC1iZW5jaG1hcmspKTxicj48ZGl2Pjxicj48L2Rp
dj48ZGl2Pjxicj48L2Rpdj48ZGl2Pk9uIEVtYWNzIChlNGUxZDBjZDApIHRoaXMgcmVwb3J0cyB0
aGUgZm9sbG93aW5nOjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+R0NzOiAxNCBFbGFwc2VkIHRp
bWU6IDUuNDQ5MDMyIHNlY29uZHM8YnI+R0NzOiAxNCBFbGFwc2VkIHRpbWU6IDUuMjA5MDA2IHNl
Y29uZHM8YnI+R0NzOiAxMyBFbGFwc2VkIHRpbWU6IDUuMTg3Nzc5IHNlY29uZHM8YnI+R0NzOiAx
MyBFbGFwc2VkIHRpbWU6IDUuMTc4NDcyIHNlY29uZHM8YnI+R0NzOiAxMyBFbGFwc2VkIHRpbWU6
IDUuMTg0NzQxIHNlY29uZHM8YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj5UaGUgcHJvZmls
ZXIgb3V0cHV0IGZvciB0aGlzIGlzIHRoZSBmb2xsb3dpbmc6PC9kaXY+PGRpdj48YnI+PC9kaXY+
PGRpdj5XZWlnaHQgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgU2VsZiBXZWlnaHQgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgU3ltYm9sIE5hbWU8YnI+MTEu
MzAgR2MgwqAxMDAuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgMS4wMCBNYyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBGcmVkaXNwbGF5PGJyPjExLjMw
IEdjIMKgIDk5LjklIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcmVkaXNwbGF5X3ByZXNlcnZlX2VjaG9fYXJl
YTxicj4xMS4xMiBHYyDCoCA5OC4zJSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAxLjAwIE1jIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmVkaXNwbGF5
X2ludGVybmFsPGJyPjYuOTcgR2MgwqAgNjEuNiUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLSDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBpbnRlcm5h
bF9jb25kaXRpb25fY2FzZV8xPGJyPjYuOTcgR2MgwqAgNjEuNiUgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHJlZGlzcGxheV93aW5kb3dfMTxicj42Ljk3IEdjIMKgIDYxLjYlIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgcmVkaXNwbGF5X3dpbmRvdzxicj41LjYwIEdjIMKgIDQ5LjUlIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqB0cnlfd2luZG93PGJyPjEuMjUgR2MgwqAgMTEuMCUgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoGRpc3BsYXlfbW9kZV9saW5lczxicj4xMTEuNjggTWMgwqAgwqAw
LjklIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB1cGRhdGVfZnJhbWVfdG9vbF9iYXI8YnI+Ni4w
MCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGd1aV9jb25zaWRlcl9mcmFt
ZV90aXRsZTxicj4yLjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAxLjAw
IE1jIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgdXBkYXRlX3dpbmRvd19mcmluZ2VzPGJyPjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqByZWNvbnNpZGVyX2NsaXBfY2hhbmdlczxicj4xLjAwIE1jIMKg
IMKgMC4wJSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgY3Vyc29yX3Jvd19mdWxseV92aXNpYmxl
X3A8YnI+MS4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgMS4wMCBNYyDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoF9f
X2Noa3N0a19kYXJ3aW48YnI+MS4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoHJlZGlzcGxheV90YWJfYmFyPGJyPjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB0cnlfd2luZG93X2lkPGJyPjMuNjQgR2MgwqAgMzIuMiUg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCB1cGRhdGVfZnJhbWU8YnI+My40NyBHYyDCoCAzMC42JSDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgdXBkYXRlX3dpbmRvd190cmVlPGJyPjMuNDcgR2MgwqAgMzAuNiUg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCB1cGRhdGVfd2luZG93PGJyPjIuMTUgR2MgwqAg
MTkuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGd1aV91cGRhdGVfd2luZG93X2VuZDxicj4y
LjExIEdjIMKgIDE4LjYlIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZHJhd193aW5kb3dfZnJp
bmdlczxicj4yLjA5IEdjIMKgIDE4LjQlIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIDEuMDAgTWMg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqBkcmF3X3Jvd19mcmluZ2VfYml0bWFwczxicj4yMC4wMCBNYyDCoCDCoDAuMSUgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoHNldF9idWZmZXJfaW50ZXJuYWxfMTxicj40MC4wMCBNYyDCoCDC
oDAuMyUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBkaXNwbGF5X2FuZF9zZXRfY3Vyc29yPGJy
PjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIDEuMDAgTWMgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZ3VpX2Ry
YXdfdmVydGljYWxfYm9yZGVyPGJyPjU4Ni4xOCBLYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCB1bmJsb2NrX2lucHV0PGJyPjEuMjggR2MgwqAgMTEuMyUgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgMy4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoHVwZGF0ZV93aW5kb3dfbGluZTxicj4yNS4wMCBNYyDCoCDCoDAu
MiUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgMy4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHNjcm9sbGluZ193aW5kb3c8YnI+OS4z
OSBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgMy4wMCBNYyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVwZGF0ZV93aW5k
b3dfZnJpbmdlczxicj4xLjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAx
LjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgcmVkcmF3X292ZXJsYXBwZWRfcm93czxicj4xLjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCAxLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgcmVkcmF3X292ZXJsYXBwaW5nX3Jvd3M8YnI+MTUyLjUz
IE1jIMKgIMKgMS4zJSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdXBkYXRlX2JlZ2luPGJyPjE4Ljcy
IE1jIMKgIMKgMC4xJSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdXBkYXRlX2VuZDxicj4zOTcuMDUg
TWMgwqAgwqAzLjUlIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgcHJlcGFyZV9tZW51X2JhcnM8YnI+OTEu
NDEgTWMgwqAgwqAwLjglIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgZWNob19hcmVhX2Rpc3BsYXk8YnI+
NS4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBuc19mcmFtZV91cF90b19kYXRl
PGJyPjQuMDEgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3RhcnRfcG9sbGluZzxi
cj40LjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAxLjAwIE1jIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHVuYmluZF90bzxi
cj4zLjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAyLjAwIE1jIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJ1bl93aW5kb3df
Y2hhbmdlX2Z1bmN0aW9uczxicj4yLjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IGhzY3JvbGxfd2luZG93czxicj4xLjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCAxLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIFhDT05TPGJyPjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgRmdl
dGhhc2g8YnI+MS4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLSDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjbGVhcl9kZXNp
cmVkX21hdHJpY2VzPGJyPjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgbWFya193aW5kb3dfZGlzcGxheV9hY2N1cmF0ZV8xPGJyPjEuMDAgTWMgwqAgwqAwLjAlIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgbnNfc2V0X2RvY19lZGl0ZWQ8YnI+MS4wMCBNYyDCoCDCoDAuMCUg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBjbGVhcl9nYXJiYWdlZF9mcmFtZXM8YnI+MTgxLjI5
IE1jIMKgIMKgMS42JSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZmx1c2hfZnJhbWU8YnI+MS4wMCBNYyDC
oCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVuYmluZF90bzxicj48YnI+PGJyPjExLjkwIEdj
IMKgMTAwLjAlIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
RnJlZGlzcGxheTxicj4xMS45MCBHYyDCoCA5OS45JSDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIHJlZGlzcGxheV9wcmVzZXJ2ZV9lY2hvX2FyZWE8YnI+MTEu
NjYgR2MgwqAgOTcuOSUgwqAgwqAgwqAgwqAgwqAgMi4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoHJlZGlzcGxheV9pbnRlcm5hbDxicj43LjQ4IEdjIMKgIDYyLjglIMKgIMKg
IMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgaW50ZXJuYWxfY29u
ZGl0aW9uX2Nhc2VfMTxicj43LjQ4IEdjIMKgIDYyLjglIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqByZWRpc3BsYXlfd2luZG93XzE8YnI+Ny40OCBH
YyDCoCA2Mi44JSDCoCDCoCDCoCDCoCDCoCAzLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIHJlZGlzcGxheV93aW5kb3c8YnI+Ni4zNSBHYyDCoCA1My4zJSDCoCDCoCDC
oCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdHJ5X3dpbmRv
dzxicj42LjIzIEdjIMKgIDUyLjMlIMKgIMKgIMKgIMKgIMKgIDM3LjAzIE1jIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRpc3BsYXlfbGluZTxicj43My43MCBNYyDCoCDC
oDAuNiUgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCBzdGFydF9kaXNwbGF5PGJyPjQ0LjAxIE1jIMKgIMKgMC4zJSDCoCDCoCDCoCDCoCDCoCAt
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIHBhcnRpYWxfbGluZV9oZWln
aHQ8YnI+MS4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgMS4wMCBNYyDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBhcHBlbmRfc3BhY2VfZm9yX25ld2xpbmU8YnI+
MS4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBndWlfcHJvZHVjZV9nbHlwaHM8YnI+OTc3LjQ4IE1jIMKg
IMKgOC4yJSDCoCDCoCDCoCDCoCDCoCAxLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgZGlzcGxheV9tb2RlX2xpbmVzPGJyPjEyNS44MCBNYyDCoCDCoDEuMCUgwqAg
wqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVwZGF0
ZV9mcmFtZV90b29sX2Jhcjxicj4xMC4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgLSDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGd1aV9jb25zaWRlcl9mcmFtZV90
aXRsZTxicj43LjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCAzLjAwIE1jIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdXBkYXRlX3dpbmRvd19mcmluZ2VzPGJyPjEu
MDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqBjdXJzb3Jfcm93X2Z1bGx5X3Zpc2libGVfcDxicj4xLjAwIE1jIMKgIMKg
MC4wJSDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgdW5iaW5kX3RvPGJyPjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBXSU5ET1dQPGJyPjEuMDAgTWMgwqAgwqAw
LjAlIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqB3aW5kb3dfd2FudHNfbW9kZV9saW5lPGJyPjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKg
IMKgIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB3aW5kb3df
c2Nyb2xsX21hcmdpbjxicj4zLjI0IEdjIMKgIDI3LjIlIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdXBkYXRlX2ZyYW1lPGJyPjMuMDYgR2MgwqAgMjUu
NyUgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVw
ZGF0ZV93aW5kb3dfdHJlZTxicj4zLjA2IEdjIMKgIDI1LjclIMKgIMKgIMKgIMKgIMKgIDEuMDAg
TWMgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgdXBkYXRlX3dpbmRvdzxicj4x
LjU4IEdjIMKgIDEzLjIlIMKgIMKgIMKgIMKgIMKgIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBndWlfdXBkYXRlX3dpbmRvd19lbmQ8YnI+MS41NCBHYyDCoCAx
Mi45JSDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIGRyYXdfd2luZG93X2ZyaW5nZXM8YnI+MS41MCBHYyDCoCAxMi42JSDCoCDCoCDCoCDCoCDC
oCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgZHJhd19yb3dfZnJp
bmdlX2JpdG1hcHM8YnI+MS41MCBHYyDCoCAxMi42JSDCoCDCoCDCoCDCoCDCoCAyLjAwIE1jIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGRyYXdfZnJpbmdlX2JpdG1h
cDxicj42MDguMzUgS2MgwqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIDYwOC4zNSBLYyDCoCDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBGUkFNRV9SSUdIVF9GUklOR0VfV0lE
VEg8YnI+MzQuMDEgTWMgwqAgwqAwLjIlIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzZXRfYnVmZmVyX2ludGVybmFsXzE8YnI+MzguMDAg
TWMgwqAgwqAwLjMlIMKgIMKgIMKgIMKgIMKgIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgZGlzcGxheV9hbmRfc2V0X2N1cnNvcjxicj4xLjQ0IEdjIMKgIDEy
LjAlIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqB1cGRhdGVfd2luZG93X2xpbmU8YnI+MzEuMDAgTWMgwqAgwqAwLjIlIMKgIMKgIMKgIMKgIMKg
IDIuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqBzY3JvbGxpbmdf
d2luZG93PGJyPjEyLjAwIE1jIMKgIMKgMC4xJSDCoCDCoCDCoCDCoCDCoCA2LjAwIE1jIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgdXBkYXRlX3dpbmRvd19mcmluZ2VzPGJy
PjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB3aW5kb3dfd2FudHNfbW9kZV9saW5lPGJyPjEuMDAgTWMg
wqAgwqAwLjAlIMKgIMKgIMKgIMKgIMKgIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqB3aW5kb3dfdGV4dF9ib3R0b21feTxicj4xLjAwIE1jIMKgIMKgMC4wJSDC
oCDCoCDCoCDCoCDCoCAxLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgcmVkcmF3X292ZXJsYXBwZWRfcm93czxicj4yMTQuNDkgS2MgwqAgwqAwLjAlIMKgIMKgIMKg
IMKgIMKgIDIxNC40OSBLYyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoGNs
aXBfdG9fYm91bmRzPGJyPjE1OS43NCBNYyDCoCDCoDEuMyUgwqAgwqAgwqAgwqAgwqAgLSDCoCDC
oCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoHVwZGF0ZV9iZWdpbjxicj4yMC4wMCBNYyDC
oCDCoDAuMSUgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoHVwZGF0ZV9lbmQ8YnI+MjAuMDAgTWMgwqAgwqAwLjElIMKgIMKgIMKgIMKgIMKgIC0gwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgbnNfdXBkYXRlX2VuZDxicj44MTUuMTUg
TWMgwqAgwqA2LjglIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAg
wqAgwqAgcHJlcGFyZV9tZW51X2JhcnM8YnI+MTA2LjE3IE1jIMKgIMKgMC44JSDCoCDCoCDCoCDC
oCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGVjaG9fYXJlYV9kaXNwbGF5
PGJyPjEwLjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIG5zX2ZyYW1lX3VwX3RvX2RhdGU8YnI+My4wMCBNYyDCoCDCoDAuMCUg
wqAgwqAgwqAgwqAgwqAgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBy
dW5fd2luZG93X2NoYW5nZV9mdW5jdGlvbnM8YnI+My4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAg
wqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCDCoCBuc19zZXRfZG9jX2VkaXRl
ZDxicj4xLjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIHNwZWNiaW5kPGJyPjEuMDAgTWMgwqAgwqAwLjAlIMKgIMKgIMKgIMKg
IMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgc3RhcnRfcG9sbGluZzxicj4x
LjAwIE1jIMKgIMKgMC4wJSDCoCDCoCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIHVwZGF0ZV9vdmVybGF5X2Fycm93czxicj4xLjAwIE1jIMKgIMKgMC4wJSDCoCDC
oCDCoCDCoCDCoCAtIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIGhzY3JvbGxfd2lu
ZG93czxicj4yMzcuNzIgTWMgwqAgwqAxLjklIMKgIMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAg
wqAgwqAgwqAgwqAgwqAgwqAgwqBmbHVzaF9mcmFtZTxicj4xODguOTcgS2MgwqAgwqAwLjAlIMKg
IMKgIMKgIMKgIMKgIC0gwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqAgwqB1bmJpbmRfdG88
YnI+Mi4wMCBNYyDCoCDCoDAuMCUgwqAgwqAgwqAgwqAgwqAgLSDCoCDCoCDCoCDCoCDCoCDCoCDC
oCDCoCDCoCDCoCBzd2FsbG93X2V2ZW50czxicj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkFu
ZCB3aXRoIGEgcGF0Y2ggSSBoYXZlIGRldmVsb3BlZCB0aGF0IHVzZXMgbWFza2VkIGJpdG1hcHMg
aW5zdGVhZCBvZiBiZXppZXJzIGZvciBkcmF3aW5nIGZyaW5nZXM6PC9kaXY+PGRpdj48YnI+PC9k
aXY+PGRpdj5HQ3M6IDE0IEVsYXBzZWQgdGltZTogNS4wOTExNjIgc2Vjb25kczxicj5HQ3M6IDE0
IEVsYXBzZWQgdGltZTogNC44MjU5NjYgc2Vjb25kczxicj5HQ3M6IDEzIEVsYXBzZWQgdGltZTog
NC43OTMzNjQgc2Vjb25kczxicj5HQ3M6IDEzIEVsYXBzZWQgdGltZTogNC43ODU5NjAgc2Vjb25k
czxicj5HQ3M6IDEzIEVsYXBzZWQgdGltZTogNC43ODI0NzAgc2Vjb25kczxicj48L2Rpdj48ZGl2
Pjxicj48L2Rpdj48ZGl2PldpdGggdGhlIGZvbGxvd2luZyBwcm9maWxlciBvdXRwdXQ6PC9kaXY+
PGRpdj48YnI+PC9kaXY+PGRpdj44LjU1IEdjIMKgMTAwLjAlIC0gRnJlZGlzcGxheTxicj44LjQ1
IEdjIMKgIDk4LjklIC0gcmVkaXNwbGF5X3ByZXNlcnZlX2VjaG9fYXJlYTxicj44LjI4IEdjIMKg
IDk2LjklIDEuMDAgTWMgwqByZWRpc3BsYXlfaW50ZXJuYWw8YnI+NS4zNSBHYyDCoCA2Mi41JSAt
IMKgIGludGVybmFsX2NvbmRpdGlvbl9jYXNlXzE8YnI+NS4zNSBHYyDCoCA2Mi41JSAtIMKgIMKg
cmVkaXNwbGF5X3dpbmRvd18xPGJyPjUuMzUgR2MgwqAgNjIuNSUgMS4wMCBNYyDCoCDCoCByZWRp
c3BsYXlfd2luZG93PGJyPjQuNjEgR2MgwqAgNTMuOCUgMS4xMSBNYyDCoCDCoCDCoHRyeV93aW5k
b3c8YnI+NjM5LjM3IE1jIMKgIMKgNy40JSAtIMKgIMKgIMKgZGlzcGxheV9tb2RlX2xpbmVzPGJy
Pjg2Ljg1IE1jIMKgIMKgMS4wJSAtIMKgIMKgIMKgdXBkYXRlX2ZyYW1lX3Rvb2xfYmFyPGJyPjgu
MDAgTWMgwqAgwqAwLjAlIDEuMDAgTWMgwqAgwqAgwqBndWlfY29uc2lkZXJfZnJhbWVfdGl0bGU8
YnI+Mi4wMCBNYyDCoCDCoDAuMCUgMi4wMCBNYyDCoCDCoCDCoHVwZGF0ZV93aW5kb3dfZnJpbmdl
czxicj4yLjAwIE1jIMKgIMKgMC4wJSAyLjAwIE1jIMKgIMKgIMKgdHJ5X3dpbmRvd19pZDxicj4x
LjAwIE1jIMKgIMKgMC4wJSAtIMKgIMKgIMKgd2luZG93X3dhbnRzX21vZGVfbGluZTxicj4xLjAw
IE1jIMKgIMKgMC4wJSAxLjAwIE1jIMKgIMKgcHVzaF9oYW5kbGVyPGJyPjIuMzcgR2MgwqAgMjcu
NyUgLSDCoCB1cGRhdGVfZnJhbWU8YnI+Mi4yMiBHYyDCoCAyNS45JSAtIMKgIMKgdXBkYXRlX3dp
bmRvd190cmVlPGJyPjIuMjIgR2MgwqAgMjUuOSUgMy4wMCBNYyDCoCDCoCB1cGRhdGVfd2luZG93
PGJyPjEuMTIgR2MgwqAgMTMuMCUgLSDCoCDCoCDCoGd1aV91cGRhdGVfd2luZG93X2VuZDxicj4x
LjEwIEdjIMKgIDEyLjglIDEuMDAgTWMgwqAgwqAgwqAgZHJhd193aW5kb3dfZnJpbmdlczxicj4x
LjA4IEdjIMKgIDEyLjYlIC0gwqAgwqAgwqAgwqBkcmF3X3Jvd19mcmluZ2VfYml0bWFwczxicj4x
LjA4IEdjIMKgIDEyLjYlIDEuMDAgTWMgwqAgwqAgwqAgwqAgZHJhd19mcmluZ2VfYml0bWFwPGJy
PjEuMDggR2MgwqAgMTIuNSUgMTIuNDggTWMgwqAgwqAgwqAgwqAgwqBkcmF3X2ZyaW5nZV9iaXRt
YXBfMTxicj45MDUuMTIgTWMgwqAgMTAuNSUgMS4wMyBNYyDCoCDCoCDCoCDCoCDCoCBuc19kcmF3
X2ZyaW5nZV9iaXRtYXA8YnI+NjY3LjkyIE1jIMKgIMKgNy44JSAtIMKgIMKgIMKgIMKgIMKgIMKg
Q0dDb250ZXh0RHJhd0ltYWdlV2l0aE9wdGlvbnM8YnI+ODEuOTEgTWMgwqAgwqAwLjklIDEuMDAg
TWMgwqAgwqAgwqAgwqAgwqAgwqBOU1JlY3RGaWxsPGJyPjQ1LjY1IE1jIMKgIMKgMC41JSAtIMKg
IMKgIMKgIMKgIMKgIMKgTlNDb2xvclNldFdpdGhGaWxsQW5kU3Ryb2tlPGJyPjI5LjA3IE1jIMKg
IMKgMC4zJSAyLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgbnNfcm93X3JlY3Q8YnI+MjIuNTMgTWMg
wqAgwqAwLjIlIC0gwqAgwqAgwqAgwqAgwqAgwqBuc19mb2N1czxicj4xMS4wMCBNYyDCoCDCoDAu
MSUgMi4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoCtbTlNDb2xvcihFbWFjc0NvbG9yKSBjb2xvcldp
dGhVbnNpZ25lZExvbmc6XTxicj44LjAwIE1jIMKgIMKgMC4wJSAxLjAwIE1jIMKgIMKgIMKgIMKg
IMKgIMKgbnNfdW5mb2N1czxicj44LjAwIE1jIMKgIMKgMC4wJSAtIMKgIMKgIMKgIMKgIMKgIMKg
LVtfTlNUYWdnZWRQb2ludGVyQ29sb3IgQ0dDb2xvcl08YnI+OC4wMCBNYyDCoCDCoDAuMCUgMi4w
MCBNYyDCoCDCoCDCoCDCoCDCoCDCoC1bX19OU0RpY3Rpb25hcnlNIG9iamVjdEZvcktleTpdPGJy
PjQuMDAgTWMgwqAgwqAwLjAlIDQuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqBOU1VuaW9uUmVjdDxi
cj4zLjAwIE1jIMKgIMKgMC4wJSAzLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgb2JqY19tc2dTZW5k
PGJyPjIuMDAgTWMgwqAgwqAwLjAlIDIuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqBndWlfZGVmaW5l
X2ZyaW5nZV9iaXRtYXA8YnI+Mi4wMCBNYyDCoCDCoDAuMCUgMi4wMCBNYyDCoCDCoCDCoCDCoCDC
oCDCoENHQ29udGV4dFNldENvbXBvc2l0ZU9wZXJhdGlvbjxicj4xLjAwIE1jIMKgIMKgMC4wJSAt
IMKgIMKgIMKgIMKgIMKgIMKgb2JqY19hdXRvcmVsZWFzZTxicj4xLjAwIE1jIMKgIMKgMC4wJSAx
LjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgQ0dDb250ZXh0Q2xpcFRvUmVjdDxicj4xLjAwIE1jIMKg
IMKgMC4wJSAtIMKgIMKgIMKgIMKgIMKgIMKgQ0dHU3RhdGVTZXRGaWxsQ29sb3I8YnI+MS4wMCBN
YyDCoCDCoDAuMCUgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCDCoF9vYmpjX3Jvb3RBdXRvcmVsZWFz
ZTxicj4xLjAwIE1jIMKgIMKgMC4wJSAxLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgTlNJbnRlcnNl
Y3Rpb25SZWN0PGJyPjEuMDAgTWMgwqAgwqAwLjAlIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqBD
R0NvbnRleHRTYXZlR1N0YXRlPGJyPjEuMDAgTWMgwqAgwqAwLjAlIDEuMDAgTWMgwqAgwqAgwqAg
wqAgwqAgwqBOU01ha2VSZWN0PGJyPjEuMDAgTWMgwqAgwqAwLjAlIDEuMDAgTWMgwqAgwqAgwqAg
wqAgwqAgwqAtW05TT2JqZWN0IGF1dG9yZWxlYXNlXTxicj4xLjAwIE1jIMKgIMKgMC4wJSAxLjAw
IE1jIMKgIMKgIMKgIMKgIMKgIMKgQ0dEYXRhUHJvdmlkZXJJc1pvbWJpZTxicj4xLjAwIE1jIMKg
IMKgMC4wJSAxLjAwIE1jIMKgIMKgIMKgIMKgIMKgIMKgRFlMRC1TVFVCJCROU1JlY3RGaWxsPGJy
PjEuMDAgTWMgwqAgwqAwLjAlIDEuMDAgTWMgwqAgwqAgwqAgwqAgwqAgwqBvYmpjX21zZ1NlbmQk
Y29sb3JXaXRoVW5zaWduZWRMb25nOjxicj4xMjkuMzggTWMgwqAgwqAxLjUlIDExLjM0IE1jIMKg
IMKgIMKgIMKgIMKgIGxvb2t1cF9uYW1lZF9mYWNlPGJyPjguMDAgTWMgwqAgwqAwLjAlIC0gwqAg
wqAgwqAgwqAgwqAgd2luZG93X2JveF9yaWdodDxicj40LjMxIE1jIMKgIMKgMC4wJSAxLjAwIE1j
IMKgIMKgIMKgIMKgIMKgIHdpbmRvd193YW50c190YWJfbGluZTxicj41LjAwIE1jIMKgIMKgMC4w
JSAxLjAwIE1jIMKgIMKgIMKgIMKgIMKgIHdpbmRvd193YW50c19oZWFkZXJfbGluZTxicj4zLjA5
IE1jIMKgIMKgMC4wJSAzLjAwIE1jIMKgIMKgIMKgIMKgIMKgIGJ1aWx0aW5fbGlzcF9zeW1ib2w8
YnI+Mi4wMCBNYyDCoCDCoDAuMCUgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCB3aW5kb3dfYm94X2xl
ZnQ8YnI+Mi4wMCBNYyDCoCDCoDAuMCUgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoCBGUkFNRV9JTlRF
Uk5BTF9CT1JERVJfV0lEVEg8YnI+MS41NSBNYyDCoCDCoDAuMCUgMS41NSBNYyDCoCDCoCDCoCDC
oCDCoCBGQUNFX0ZST01fSURfT1JfTlVMTDxicj4xLjAwIE1jIMKgIMKgMC4wJSAtIMKgIMKgIMKg
IMKgIMKgIFdJTkRPV1A8YnI+MS4wMCBNYyDCoCDCoDAuMCUgMS4wMCBNYyDCoCDCoCDCoCDCoCDC
oCBFUTxicj4yNjAuODMgS2MgwqAgwqAwLjAlIDI2MC44MyBLYyDCoCDCoCDCoCDCoCDCoCBFUTxi
cj4xLjAwIE1jIMKgIMKgMC4wJSAxLjAwIE1jIMKgIMKgIMKgIMKgIMKgIGdldF9mcmluZ2VfYml0
bWFwX2RhdGE8YnI+MS4wMCBNYyDCoCDCoDAuMCUgMS4wMCBNYyDCoCDCoCDCoCDCoCDCoG5zX2Ry
YXdfZnJpbmdlX2JpdG1hcDxicj4xLjAwIE1jIMKgIMKgMC4wJSAxLjAwIE1jIMKgIMKgIMKgIMKg
IEZSQU1FX1JJR0hUX0ZSSU5HRV9XSURUSDxicj4yMC4wMCBNYyDCoCDCoDAuMiUgMS4wMCBNYyDC
oCDCoCDCoCDCoHNldF9idWZmZXJfaW50ZXJuYWxfMTxicj4xOS4wMCBNYyDCoCDCoDAuMiUgMS4w
MCBNYyDCoCDCoCDCoCBkaXNwbGF5X2FuZF9zZXRfY3Vyc29yPGJyPjEuMDcgR2MgwqAgMTIuNCUg
Mi4wMCBNYyDCoCDCoCDCoHVwZGF0ZV93aW5kb3dfbGluZTxicj4yMS4yNSBNYyDCoCDCoDAuMiUg
Ni4wMCBNYyDCoCDCoCDCoHNjcm9sbGluZ193aW5kb3c8YnI+Ny4wMCBNYyDCoCDCoDAuMCUgMi4w
MCBNYyDCoCDCoCDCoHVwZGF0ZV93aW5kb3dfZnJpbmdlczxicj42NDYuMzggS2MgwqAgwqAwLjAl
IC0gwqAgwqAgwqB3aW5kb3dfdGV4dF9ib3R0b21feTxicj4xMzkuODcgTWMgwqAgwqAxLjYlIC0g
wqAgwqB1cGRhdGVfYmVnaW48YnI+MTYuMDEgTWMgwqAgwqAwLjElIC0gwqAgwqB1cGRhdGVfZW5k
PGJyPjQ4NC41OSBNYyDCoCDCoDUuNiUgLSDCoCBwcmVwYXJlX21lbnVfYmFyczxicj42My4xMiBN
YyDCoCDCoDAuNyUgMzY1LjI0IEtjIMKgIGVjaG9fYXJlYV9kaXNwbGF5PGJyPjMuMTMgTWMgwqAg
wqAwLjAlIC0gwqAgaHNjcm9sbF93aW5kb3dzPGJyPjIuNTEgTWMgwqAgwqAwLjAlIC0gwqAgbnNf
c2V0X2RvY19lZGl0ZWQ8YnI+Mi4wMCBNYyDCoCDCoDAuMCUgMi4wMCBNYyDCoCBvdmVybGF5X2Fy
cm93c19jaGFuZ2VkX3A8YnI+Mi4wMCBNYyDCoCDCoDAuMCUgMS4wMCBNYyDCoCBydW5fd2luZG93
X2NoYW5nZV9mdW5jdGlvbnM8YnI+MS4wMCBNYyDCoCDCoDAuMCUgMS4wMCBNYyDCoCByZXNldF9v
dXRlcm1vc3RfcmVzdHJpY3Rpb25zPGJyPjY1MS43OSBLYyDCoCDCoDAuMCUgNjUxLjc5IEtjIMKg
IF9fX2Noa3N0a19kYXJ3aW48YnI+MS4wMCBNYyDCoCDCoDAuMCUgMS4wMCBNYyDCoCBtYXJrX3dp
bmRvd19kaXNwbGF5X2FjY3VyYXRlXzE8YnI+MS4wMCBNYyDCoCDCoDAuMCUgLSDCoCB1bmJpbmRf
dG88YnI+MS4wMCBNYyDCoCDCoDAuMCUgLSDCoCBzdGFydF9wb2xsaW5nPGJyPjE2OS4zNSBNYyDC
oCDCoDEuOSUgLSDCoGZsdXNoX2ZyYW1lPGJyPjEuMDAgTWMgwqAgwqAwLjAlIC0gwqB1bmJpbmRf
dG88YnI+NTEuMDEgTWMgwqAgwqAwLjUlIC0gZGV0ZWN0X2lucHV0X3BlbmRpbmdfcnVuX3RpbWVy
czxicj40MS4xMyBNYyDCoCDCoDAuNCUgLSBzd2FsbG93X2V2ZW50czxicj48L2Rpdj48ZGl2Pjxi
cj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkkmIzM5O3ZlIHB1dCB0b2dldGhlciBhIHBhdGNo
IHRoYXQgZHJhd3MgdXNpbmcgYSBtYXNrZWQgQ0dJbWFnZSBpbnN0ZWFkIG9mIGFuIE5TQmV6aWVy
LiBIb3dldmVyIEkmIzM5O20gbm90IHN1cmUgaWYgaXQmIzM5O3MgYW55IGdvb2QgYXMgSSYjMzk7
bSBjb21wbGV0ZWx5IHVuZmFtaWxpYXIgd2l0aCB0aGUgRW1hY3MgY29kZWJhc2UgYW5kIG1hY29z
L05TIGdyYXBoaWNzIEFQSXMuIEFsc28gSSBiZWxpZXZlIE5TIGVtYWNzIHdhbnRzIHRvIGJlIGNv
bXBhdGlibGUgd2l0aCBHTlVTdGVwIGFuZCBJIGhhdmUgbm8gaWRlYSBpZiB0aGlzIHJlbWFpbnMg
Y29tcGF0aWJsZTo8YnI+PGJyPjxwcmUgc3R5bGU9ImNvbG9yOnJnYigwLDAsMCkiPkZyb20gZDU0
YzA5MTAwMmFmZjhmNzRmODE2NWRkMjFkNjUwNzVmMDI4ZTcyOCBNb24gU2VwIDE3IDAwOjAwOjAw
IDIwMDEKRnJvbTogQmVuIFNpbW1zICZsdDtiZW5AYmVuc2ltbXMubW9lJmd0OwpEYXRlOiBNb24s
IDI0IEp1biAyMDI0IDIzOjM1OjI5ICswMjAwClN1YmplY3Q6IFtQQVRDSF0gRHJhdyBmcmluZ2Ug
dXNpbmcgYml0bWFwcywgbm90IGh1Z2UgYmV6aWVycwoKLS0tCiBzcmMvbnN0ZXJtLm0gfCA1NSAr
KysrKysrKysrKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAxIGZp
bGUgY2hhbmdlZCwgMjUgaW5zZXJ0aW9ucygrKSwgMzAgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0
IGEvc3JjL25zdGVybS5tIGIvc3JjL25zdGVybS5tCmluZGV4IDc5NDYzMGRlMWMuLjljNzgxZTNi
ZDYgMTAwNjQ0Ci0tLSBhL3NyYy9uc3Rlcm0ubQorKysgYi9zcmMvbnN0ZXJtLm0KQEAgLTI5MDMs
MjIgKzI5MDMsMjQgQEAgSGlkZSB0aGUgd2luZG93IChYMTEgc2VtYW50aWNzKQogc3RhdGljIHZv
aWQKIG5zX2RlZmluZV9mcmluZ2VfYml0bWFwIChpbnQgd2hpY2gsIHVuc2lnbmVkIHNob3J0ICpi
aXRzLCBpbnQgaCwgaW50IHcpCiB7Ci0gIE5TQmV6aWVyUGF0aCAqcCA9IFtOU0JlemllclBhdGgg
YmV6aWVyUGF0aF07Ci0KICAgaWYgKCFmcmluZ2VfYm1wKQogICAgIGZyaW5nZV9ibXAgPSBbW05T
TXV0YWJsZURpY3Rpb25hcnkgYWxsb2NdIGluaXRXaXRoQ2FwYWNpdHk6MjVdOwogCi0gIFtwIG1v
dmVUb1BvaW50Ok5TTWFrZVBvaW50ICgwLCAwKV07CiAKLSAgZm9yIChpbnQgeSA9IDAgOyB5ICZs
dDsgaCA7IHkrKykKLSAgICBmb3IgKGludCB4ID0gMCA7IHggJmx0OyB3IDsgeCsrKQotICAgICAg
ewotICAgICAgICBib29sIGJpdCA9IGJpdHNbeV0gJmFtcDsgKDEgJmx0OyZsdDsgKHcgLSB4IC0g
MSkpOwotICAgICAgICBpZiAoYml0KQotICAgICAgICAgIFtwIGFwcGVuZEJlemllclBhdGhXaXRo
UmVjdDpOU01ha2VSZWN0ICh4LCB5LCAxLCAxKV07Ci0gICAgICB9CisgIGZvciAoaW50IGkgPSAw
OyBpICZsdDsgaDsgaSsrKQorICAgIGJpdHNbaV0gPSB+Yml0c1tpXTsKKworICBDR0RhdGFQcm92
aWRlclJlZiBwcm92aWRlciA9IENHRGF0YVByb3ZpZGVyQ3JlYXRlV2l0aERhdGEgKE5VTEwsIGJp
dHMsCisJCQkJCSAgIHNpemVvZiAodW5zaWduZWQgc2hvcnQpICogaCwgTlVMTCk7CisgIGlmIChw
cm92aWRlcikgeworICAgIGlkIHAgPSAoaWQpQ0dJbWFnZU1hc2tDcmVhdGUgKHcsIGgsIDEsIDEs
CisgICAgICAgICAgICAgICAgIHNpemVvZiAodW5zaWduZWQgc2hvcnQpLAorICAgICAgICAgICAg
ICAgICBwcm92aWRlciwgTlVMTCwgMCk7CisgICAgQ0dEYXRhUHJvdmlkZXJSZWxlYXNlIChwcm92
aWRlcik7CisKKyAgICBbZnJpbmdlX2JtcCBzZXRPYmplY3Q6cCBmb3JLZXk6W05TTnVtYmVyIG51
bWJlcldpdGhJbnQ6d2hpY2hdXTsKKyAgfQogCi0gIFtmcmluZ2VfYm1wIHNldE9iamVjdDpwIGZv
cktleTpbTlNOdW1iZXIgbnVtYmVyV2l0aEludDp3aGljaF1dOwogfQogCiAKQEAgLTI5ODEsMzcg
KzI5ODMsMzAgQEAgSGlkZSB0aGUgd2luZG93IChYMTEgc2VtYW50aWNzKQogICAgICAgTlNSZWN0
RmlsbCAoY2xlYXJSZWN0KTsKICAgICB9CiAKLSAgTlNCZXppZXJQYXRoICpibXAgPSBbZnJpbmdl
X2JtcCBvYmplY3RGb3JLZXk6W05TTnVtYmVyIG51bWJlcldpdGhJbnQ6cC0mZ3Q7d2hpY2hdXTsK
KyAgQ0dJbWFnZVJlZiBibXAgPSAoQ0dJbWFnZVJlZilbZnJpbmdlX2JtcCBvYmplY3RGb3JLZXk6
W05TTnVtYmVyIG51bWJlcldpdGhJbnQ6cC0mZ3Q7d2hpY2hdXTsKIAogICBpZiAoYm1wID09IG5p
bAogICAgICAgJmFtcDsmYW1wOyBwLSZndDt3aGljaCAmbHQ7IG1heF91c2VkX2ZyaW5nZV9iaXRt
YXApCiAgICAgewogICAgICAgZ3VpX2RlZmluZV9mcmluZ2VfYml0bWFwIChmLCBwLSZndDt3aGlj
aCk7Ci0gICAgICBibXAgPSBbZnJpbmdlX2JtcCBvYmplY3RGb3JLZXk6IFtOU051bWJlciBudW1i
ZXJXaXRoSW50OiBwLSZndDt3aGljaF1dOworICAgICAgYm1wID0gKENHSW1hZ2VSZWYpW2ZyaW5n
ZV9ibXAgb2JqZWN0Rm9yS2V5OiBbTlNOdW1iZXIgbnVtYmVyV2l0aEludDogcC0mZ3Q7d2hpY2hd
XTsKICAgICB9CiAKICAgaWYgKGJtcCkKICAgICB7Ci0gICAgICBOU0FmZmluZVRyYW5zZm9ybSAq
dHJhbnNmb3JtID0gW05TQWZmaW5lVHJhbnNmb3JtIHRyYW5zZm9ybV07Ci0gICAgICBOU0NvbG9y
ICpibV9jb2xvcjsKKyAgICAgIENHUmVjdCBib3VuZHMgPSBDR1JlY3RNYWtlIChwLSZndDt4LCBw
LSZndDt5IC0gcC0mZ3Q7ZGgsCisJCQkgICBDR0ltYWdlR2V0V2lkdGggKGJtcCksIENHSW1hZ2VH
ZXRIZWlnaHQgKGJtcCkpOwogCi0gICAgICAvKiBCZWNhdXNlIHRoZSBpbWFnZSBpcyBkZWZpbmVk
IGF0ICgwLCAwKSB3ZSBuZWVkIHRvIHRha2UgYSBjb3B5Ci0gICAgICAgICBhbmQgdGhlbiB0cmFu
c2Zvcm0gdGhhdCBjb3B5IHRvIHRoZSBuZXcgb3JpZ2luLiAgKi8KLSAgICAgIGJtcCA9IFtibXAg
Y29weV07Ci0gICAgICBbdHJhbnNmb3JtIHRyYW5zbGF0ZVhCeTpwLSZndDt4IHlCeTpwLSZndDt5
IC0gcC0mZ3Q7ZGhdOwotICAgICAgW2JtcCB0cmFuc2Zvcm1Vc2luZ0FmZmluZVRyYW5zZm9ybTp0
cmFuc2Zvcm1dOworICAgICAgTlNHcmFwaGljc0NvbnRleHQgKmN0eCA9IFtOU0dyYXBoaWNzQ29u
dGV4dCBjdXJyZW50Q29udGV4dF07CisgICAgICBDR0NvbnRleHRSZWYgY29udGV4dCA9IFtjdHgg
Q0dDb250ZXh0XTsKIAotICAgICAgaWYgKCFwLSZndDtjdXJzb3JfcCkKLSAgICAgICAgYm1fY29s
b3IgPSBbTlNDb2xvciBjb2xvcldpdGhVbnNpZ25lZExvbmc6ZmFjZS0mZ3Q7Zm9yZWdyb3VuZF07
Ci0gICAgICBlbHNlIGlmIChwLSZndDtvdmVybGF5X3ApCi0gICAgICAgIGJtX2NvbG9yID0gW05T
Q29sb3IgY29sb3JXaXRoVW5zaWduZWRMb25nOmZhY2UtJmd0O2JhY2tncm91bmRdOwotICAgICAg
ZWxzZQotICAgICAgICBibV9jb2xvciA9IGYtJmd0O291dHB1dF9kYXRhLm5zLSZndDtjdXJzb3Jf
Y29sb3I7CisgICAgICBDR0NvbnRleHRUcmFuc2xhdGVDVE0gKGNvbnRleHQsCisJCQkgICAgIENH
UmVjdEdldE1pblggKGJvdW5kcyksIENHUmVjdEdldE1heFkgKGJvdW5kcykpOworICAgICAgQ0dD
b250ZXh0U2NhbGVDVE0gKGNvbnRleHQsIDEsIC0xKTsKIAotICAgICAgW2JtX2NvbG9yIHNldF07
Ci0gICAgICBbYm1wIGZpbGxdOwotCi0gICAgICBbYm1wIHJlbGVhc2VdOworICAgICAgQ0dDb250
ZXh0U2V0RmlsbENvbG9yV2l0aENvbG9yIChjb250ZXh0LCBbW05TQ29sb3IgY29sb3JXaXRoVW5z
aWduZWRMb25nOmZhY2UtJmd0O2ZvcmVncm91bmRdIENHQ29sb3JdKTsKKyAgICAgIGJvdW5kcy5v
cmlnaW4gPSBDR1BvaW50WmVybzsKKyAgICAgIENHQ29udGV4dERyYXdJbWFnZSAoY29udGV4dCwg
Ym91bmRzLCBibXApOwogICAgIH0KICAgbnNfdW5mb2N1cyAoZik7CiB9Ci0tIAoyLjQ1LjE8L3By
ZT48L2Rpdj48L2Rpdj48YnIgY2xlYXI9ImFsbCI+PGRpdj48YnI+PC9kaXY+PHNwYW4gY2xhc3M9
ImdtYWlsX3NpZ25hdHVyZV9wcmVmaXgiPi0tIDwvc3Bhbj48YnI+PGRpdiBkaXI9Imx0ciIgY2xh
c3M9ImdtYWlsX3NpZ25hdHVyZSIgZGF0YS1zbWFydG1haWw9ImdtYWlsX3NpZ25hdHVyZSI+PGRp
diBkaXI9Imx0ciI+PGRpdj48ZGl2IGRpcj0ibHRyIj48ZGl2PjxkaXYgZGlyPSJsdHIiPjxzcGFu
IHN0eWxlPSJmb250LWZhbWlseTphcmlhbCxoZWx2ZXRpY2Esc2Fucy1zZXJpZiI+PGRpdj48ZGl2
IGRpcj0ibHRyIj5CZW4gU2ltbXM8L2Rpdj48L2Rpdj48L3NwYW4+PC9kaXY+PC9kaXY+PC9kaXY+
PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+Cg==
--0000000000002a887a0623510c8e--




Acknowledgement sent to Stefan Kangas <stefankangas@HIDDEN>:
New bug report received and forwarded. Copy sent to ben@HIDDEN, bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to ben@HIDDEN, bug-gnu-emacs@HIDDEN:
bug#73563; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Sat, 17 May 2025 11:30:05 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.