UnigramDev/Unigram/develop • b2ec787 • 1 files, +6/-0
Carrying both parsers costs compile time, not binary size
Three x64 bundles built the same way: Reader 77,228,975 bytes, Pointer
77,754,662, Both 77,749,472. Both and Pointer are within 5 KB, because ILC
strips the set nothing calls. The 526 KB between Reader and Pointer is the
pointer parsers being larger native code, the same 40% the line counts show.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
UnigramDev/Unigram/develop • 85ee4c2 • 3 files, +131/-19
Register CompositionTarget.Rendering per view
Verified by Fela: video and lottie both work in the call window again.
CsWinRT keeps one event source per statics object for the whole process, so a
second view's CompositionTarget.Rendering += never reaches add_Rendering - the
delegate is appended to the registration the first view made, and the handler runs
on that view's thread. Every secondary view's frame callback lands on the main
view's thread. Composition objects do not mind, being agile, which is why the call
blobs animated throughout; WriteableBitmap does mind, and DrawFrame died on
RPC_E_WRONG_THREAD.
CompositionTargetRendering registers through the ABI instead, so each view gets a
registration of its own. The statics object is a process-wide agile singleton -
measured, along with its IAgileObject - so the call runs on the calling thread and
registers there. Proved in a throwaway app first: in the same run, the projected
subscription fired on view 1's thread and the ABI one on view 2's.
Reported as https://github.com/microsoft/CsWinRT/issues/2524.
Also drops the marshalling branch added to RegisterRendering earlier, which was
aimed at the wrong cause and never once fired; the presenter's own _loader stays.
Left alone, and noted in the todo: CompositionVSync, VisualUtilities,
PremiumProgressBar, PremiumSlider and GiftCraftPopup still subscribe through the
projection. Same latent bug, invisible so far because they only touch Composition.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
UnigramDev/Unigram/develop • 388e015 • 8 files, +114/-66
Alias CompositionTarget rather than #if every call site
Fela's idea, and a better one: CsWinRT.cs already keeps the global usings, so the
stand-in goes in there and the twenty call sites stay written the way they were.
#if NET9_0_OR_GREATER
global using CompositionTarget = Telegram.Common.CompositionTargetImpl;
#else
global using CompositionTarget = Windows.UI.Xaml.Media.CompositionTarget;
#endif
Aliasing in both directions pays for itself twice: .NET Native binds to the real
type as before, and the alias settles the ambiguity with
Windows.UI.Composition.CompositionTarget, which is the only reason those call sites
spelled the namespace out. They lose the prefix and a comment explaining it, so the
net change is shorter code than before the port.
That also carries the fix to everything else that draws per frame -
CompositionVSync, VisualUtilities, PremiumProgressBar, PremiumSlider,
GiftCraftPopup - which until now was running on the first view's thread in any
secondary window and getting away with it only because Composition objects are
agile.
Rendered goes through the ABI too, via ICompositionTargetStatics3. Forwarding it to
the projection, as it was a commit ago, left one honest half and one broken half in
a type that exists to fix exactly that.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#unigram
Post #20701
51