Fix edit scope single-element flickering by retaining stale graphics until edited geometry is ready#9208
Draft
markschlosseratbentley wants to merge 1 commit into
Draft
Fix edit scope single-element flickering by retaining stale graphics until edited geometry is ready#9208markschlosseratbentley wants to merge 1 commit into
markschlosseratbentley wants to merge 1 commit into
Conversation
| *--------------------------------------------------------------------------------------------*/ | ||
|
|
||
| import { CompressedId64Set, Id64String } from "@itwin/core-bentley"; | ||
| import { BentleyError, CompressedId64Set, Id64String } from "@itwin/core-bentley"; |
bbastings
reviewed
Apr 16, 2026
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.
Problem
When an element's geometry is modified during a GraphicalEditingScope, the dynamic tile system immediately discards the old graphics and requests new ones. Until the new graphics arrive (which requires tile generation), the element disappears for one or more frames, causing a visible flicker. This is especially noticeable during rapid/continuous edits of complex geometry where new geometry changes arrive before previous tile requests complete.
Solution
When an ElementTile's geometry is updated, retain children that have loaded graphics as stale fallbacks instead of disposing them. During tile selection, fall back to a stale child when no current match is available. Dispose stale children once fresh graphics arrive. When edits arrive faster than graphics can load, preserve the existing stale fallback rather than discarding it.
WIP: The behavior is gated by TileAdmin.retainStaleDynamicTileChildren (
@internal, default true) so it can be toggled at runtime for comparison testing. Not proposing this become a permanent toggle! Just for testing this PR!DTA tooling
dta deform element: New interactive PrimitiveTool that continuously rewrites the GeometryStream of selected elements on every mouse motion (not just placement transform). This exercises the exact code path that triggers flicker — select elements, click an anchor point, then move the mouse to see continuous geometry commits.dta toggle stale children: Toggles the retainStaleDynamicTileChildren flag on/off to A/B compare the old (flicker) vs new (stale fallback) behavior.Tradeoffs
With the fix enabled, there is a visual lag — the stale graphic shows the element at its previous committed position until the new graphic loads. This is an inherent tradeoff vs. the element disappearing entirely. The toggle keyin makes it easy to compare both behaviors.
Dataset / Repro Steps
Download testcase: flicker-test-simple-orig.bim.zip
cd test-apps/display-test-appexport IMJS_READ_WRITE=1npm run startdta editdta deform element. Click element. Begin dragging it around.dta toggle stale childrendta deform element. Click element. Begin dragging it around.Videos
The flickering:
yes-flicker.mov
Avoiding the flickering using this PR's approach:
no-flicker.mov