Repository navigation
perf(blur): keep blurred backdrops, clip damage, opaque regions - #28
Merged
Merged
Conversation
A BackgroundBlur shape was repainted whole for any damage in the scene, and every repaint blurred again. Expand damage to a blur shape only for damage painted beneath it (earlier in paint order) within reach, and keep the pixels the blur produced so a repaint caused by the layer's own content or by content above it draws them instead. Claude-Session: https://claude.ai/code/session_01NQwfuVAHbrQx7UUyEUgd54
3 tasks done
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.
Summary
Three changes that make a frosted layer (
BlendMode::BackgroundBlur) cheaper to repaint when little has changed. The first is the main one, and the other two follow from it.1. Keep a blurred backdrop until something beneath it changes (
e0ece8b)Before: any damage that reached a blur shape repainted the whole shape and ran the blur again. That included the layer's own content changing, or something drawn on top of it. So a frosted window blurred its backdrop again on every frame that its text or a scroll changed.
Now: the blurred result is a function of what lies beneath the shape, so the engine only invalidates it for that.
cached_paint_order), which is the scene's z-order.blur_expansionreplaces both older Phase 8 expansions (the whole-scene one inupdate_nodesand the one insubtree_damage). A blur shape is repainted whole, and itsbackdrop_generationbumped, only when damage lands:BLUR_CACHE, 32 entries, LRU).paint_nodedraws the kept pixels (BlendMode::Src) instead of running thesave_layerbackdrop blur.clear_blur_cache()is public so a render context can drop the images before it is torn down.2. Clip damage to clipping ancestors (
eff46de)A node's damage is intersected with every
clip_childrenancestor's bounds before it is recorded. A scrolled band is content much taller than the clip it moves inside. Without this it reported its full height as damage on every scroll step, and that damage then reached blur shapes elsewhere on screen.3. Opaque region (
4f9731e)New
Layer::set_opaque_region(Vec<Rect>), in layer-local coordinates. The backdrop of aBackgroundBlurlayer is clipped out (ClipOp::Difference) where the layer's own content is opaque, because that area gets painted over straight away. A window whose opaque listing covers most of it then seeds, blurs and replays only its translucent edges. The region is part of the blur cache key.It's a promise about the pixels: a rect that isn't really opaque shows whatever was on the surface before.
Tests
New integration tests, each with its own scene:
tests/blur_damage.rs: the blur shape is repainted whole for damage beneath it, and when the frosted layer moves (old and new shape). It is not repainted for its own content, content above it, or damage out of reach.tests/blur_cache_pixels.rs: a partial repaint (own content changed, or content above) draws the kept blur and matches a full render pixel for pixel. A changed backdrop blurs again.tests/frosted_band.rs: a band moving inside a frosted window damages only its clip, both in the scene damage and insubtree_damage.tests/clip_damage.rs: moving content inside a clip damages only what the clip shows. Without a clip the whole move is damaged, and a move entirely outside the clip damages nothing.tests/opaque_region.rs: leaving the region out changes no pixel, a partial repaint with a region matches a full render, and changing the region does not replay a stale blur.Test plan
cargo testfor the five new test files (16 tests)