Paint Windows image panes from a cached composite, and decode off the UI thread - #896
Merged
Merged
Conversation
… UI thread - The checkerboard and the scaled picture are composed once per picture and size (ImageCache.Composite) and copied on every paint after. Scaling a pair of 2000 by 1500 pictures and drawing the checkerboard under them on every paint cost 46 to 66 ms a paint, on every wheel notch and resize; the copy costs about 1 ms. Composing costs about 50 ms, once. - The window decodes on the pool and paints the picture when the decode is handed back through BeginInvoke. It started when the screen arrives, and a decode that finishes for a picture no longer on screen is dropped. The pair above took 77 to 102 ms to decode on the UI thread. A capture still decodes synchronously (LoadPictures), having no later paint to wait for. - Footer buttons are sized to their current label (GrowAndShrink, with the default 75 by 23 as the minimum). The pool relabels them as the screen changes, and at GrowOnly each button kept the width of the longest label it had ever held, so the pixel baselines recorded the order the tests happened to run in: adding any test to FormsHeadTests failed InlineAccepted and Minimal. Six Windows baselines are re-approved; only the footers changed, and they now come out byte identical in either order.
This was referenced Sep 23, 2026
Merged
Merged
Merged
Merged
Merged
This was referenced Sep 24, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the Windows image pane perf item from
todo.md.Paint cost
Measured on a canvas showing a pair of 2000×1500 PNGs, calling
OnPaintdirectly:ImageCache.Compositeholds the checkerboard with the scaled picture over it, per picture and drawn size. It's disposed along with the decoded picture, soKeepstill bounds it to what's on screen. A paint copies the composite; the Windows pixel baselines,Imagesincluded, are unchanged by this.ImageCache.Get(path, hash, loaded)decodes on the pool and hands the result back through the canvas'sBeginInvoke. The decode starts as soon as a screen arrives, not at the first paint. A decode that finishes for a picture no longer on screen, or for an older version of the file, is discarded. The rows draw while it runs, and the picture follows. A capture has no later paint to wait for, so it still decodes synchronously (LoadPictures).Footer buttons (found while adding the tests)
Adding any test to
FormsHeadTestsfailed theInlineAcceptedandMinimalpixel tests, onmaintoo. The footer buttons are pooled and relabelled as the screen changes. At WinForms' defaultAutoSizeMode.GrowOnly, each button kept the width of the longest label it had ever held. So the baselines recorded whichever labels the run happened to show first, and in the app buttons stayed oversized after switching between entry types.The buttons are now
GrowAndShrink, with the default 75×23 as the minimum. Six Windows baselines are re-approved. Only their footers changed, and they now come out byte-identical in either test order.Tests:
ImageCacheTests.ADecodeWithSomewhereToPostItIsHandedBack,ADecodeForAPictureNoLongerOnScreenIsDropped,APictureIsComposedOncePerSize, andFormsHeadTests.RepaintingAPictureComposesItOnce,AFooterButtonIsSizedToItsCurrentLabel.The full solution passes locally in Release: 2,157 passed, 24 skipped.