UnigramDev/Unigram/develop • 27022ab • 1 files, +25/-6
Propagate video render failures out of ImageHelper
RenderSync answers whether it wrote a frame, and three call sites discarded it,
passing a BufferSurface that still held uninitialised memory to Encode or to a
WriteableBitmap.
Each needs a different answer. GetPreviewBitmapAsync returns null, which is
already its contract and which every caller substitutes a placeholder for.
CropAndPreviewAsync throws, because StorageMedia.Refresh recovers by falling
back to the unedited preview and does so from a catch, which a null would slip
past. OpenReadAsync throws, because callers pass the result straight to
BitmapDecoder and there is no null that does not simply move the failure; both
GenerationService and ImageCropper.SetSourceAsync catch it.
The blanket catch in GetPreviewBitmapAsync now logs. A codec the decoder cannot
handle was indistinguishable from a file with no frames.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
UnigramDev/Unigram/develop • d4ac632 • 4 files, +208/-86
Remove per-frame allocations from message layout
Four allocations on paths that run for every message on every layout pass.
ReactionsPanel.ArrangeOverride built a List of rows and a List of rects per row
purely to centre them. A row is a contiguous run of children, complete as soon
as the next child does not fit, at which point its right edge is known, so each
run is now arranged in place. Both overrides also index Children rather than
enumerating it, since foreach over UIElementCollection allocates an
IEnumerator<UIElement> per pass.
LoadingTextBlock rebuilt its skeleton clip on every arrange: a native text
measurement, one D2D geometry per line, a group, a path, a path geometry and a
clip. It is now cached on the inputs it derives from.
ReplyMarkupInlinePanel rebuilt the rect buffers it hands to the native clip
builder, plus the clip itself, on every arrange. The buffers are reused and the
rects compared in place, so the clip is rebuilt only when one moves.
Discern gains an IList<UnreadReaction> overload over a shared core, so
ReactionsPanel no longer projects through Select on a list that is usually
empty.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
UnigramDev/Unigram/develop • a2c8668 • 5 files, +28/-7
Release chart geometries built inside the draw pass
DrawChart and DrawPickerChart called CanvasGeometry.CreatePath once per line on
every frame and never disposed the result, leaving the native D2D geometry to
the finalizer. Seven sites now go through DrawGeometry and FillGeometry on
BaseChartView, which wrap the geometry in a using. The drawing session consumes
it before the call returns, so nothing outlives the scope.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#unigram
Post #20507
62
- 🫡 2