-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix terrain cache not updating on setFeatureState
#11209
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, I think this fix is valid, but I left a comment to investigate whether we could be more granular in the way we invalidate the cache.
src/style/style.js
Outdated
@@ -1120,6 +1120,7 @@ class Style extends Evented { | |||
for (const sourceCache of sourceCaches) { | |||
sourceCache.setFeatureState(sourceLayer, target.id, state); | |||
} | |||
this.fire(new Event('setfeaturestate')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix should also apply when removeFeatureState
is called to clear a value. When you do that, maybe a different name is appropriate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch @asheemmamoowala!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karimnaaji Thoughts on how to get this behavior working now that this is no longer using events? Should removeFeatureState
call a new function tile.removeFeatureState
to trigger this update?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't stepped through the code in debug, but from reading it removeFeatureState
should eventually result in a bucket update. I'd verify that with a step through to confirm.
If we tie a render cache invalidation to a buffer update, we ensure that when something actually changes visually (like you do now in this PR) we invalidate the draping cache entry. bucket.update
should be the end result of any mutation of feature state changes, which is the end result of going through source_state:coalesceChanges
.
But to confirm that some unit test using these cases would be necessary (to check that we invalidate the cache correctly).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debugging shows that source_state:coalesceChanges
(and thus the code in this fix) is indeed being called after removeFeatureState
. I'm not totally sure how that works, but I can confirm that it works as expected in browser testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SnailBones LGTM!
Is it possible to add some unit tests covering this to prevent further regression?
setFeatureState
src/source/tile.js
Outdated
@@ -527,6 +531,12 @@ class Tile { | |||
if (!sourceLayer || !sourceLayerStates || Object.keys(sourceLayerStates).length === 0) continue; | |||
|
|||
bucket.update(sourceLayerStates, sourceLayer, availableImages, this.imageAtlas && this.imageAtlas.patternPositions || {}); | |||
if (bucket instanceof LineBucket || bucket instanceof FillBucket || bucket instanceof FillExtrusionBucket || bucket instanceof CircleBucket) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move this as a function on a bucket, instead of all of these instanceof checks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also is FillExtrusion right here? because thats not draped? same with circle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The instance checks are necessary for Flow. Really we're just checking that it's not a SymbolBucket, since SymbolBucket doesn't have the programConfigurations
.
Good point about draping, should this just be LineBucket
and FillBucket
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well symbols are draped in certain situations 😅 (map aligned)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😓 Hmmm... If this bug exists for symbols then this fix won't work as is. Though we could bypass the check for bucket.programConfigurations.needsUpload
and clear the cache for all tiles.
Do we have an examples of feature-state
on a symbol layer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checked that symbols are not yet draped in any situation on gl-js, pending #10365. The draped layer list is https://github.com/mapbox/mapbox-gl-js/blob/main/src/style/style.js#L116.
So this check should be good now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
Tested that symbol layers don't have this bug and that the fix works with line layers as well as fill layers.
* Invalidating terrain render cache on style.setFeatureState * Changed approach to directly clear render cache from Tile * Only on LineBucket and FillBucket Tests will be in a new PR
Closes https://github.com/mapbox/gl-js-team/issues/312
Currently,
feature-state
doesn't update on terrain until the map is zoomed a certain amount (possibly an integer zoom level).Demonstration here.This is because the terrain render cache doesn't update. This P.R. fixes that.
This issue is a regression introduced in 2.4, probably from #10701. #10302 may be a related issue, but predates this regression.
Launch Checklist
@mapbox/gl-native
if this PR includes shader changes or needs a native portmapbox-gl-js
changelog:<changelog>Fixes
feature-statenot updating when terrain is enabled.</changelog>