[core] Don't use a separate SpriteAtlas for annotation images#9003
Conversation
d990b2c to
75fecf2
Compare
|
@jfirebaugh The size/capacity of Style::spriteAtlas should also be changed to 2048x2048 since it now needs to have capacity for style sprite as well as user added annotations. |
There was a problem hiding this comment.
We can now remove this public method and set loaded = true directly.
There was a problem hiding this comment.
I'm worried about how this will interact with image names from the sprite sheet: Removing annotation images that have the same name as images in the sprite sheet means that they will be dangling.
There was a problem hiding this comment.
I went back and forth about this. We could prefix the ids when adding to the style. But using the same namespace would actually fix #4750.
There was a problem hiding this comment.
Could we use some sort of reference counting system?
There was a problem hiding this comment.
What do you have in mind?
There was a problem hiding this comment.
For glyphs, we store the GlyphRequestor in each Entry/GlyphValue, and only remove it from the atlas once all requestors are gone. We could use a similar model for requesting sprite images that were implicitly added to the sprite atlas.
There was a problem hiding this comment.
I elected to use a prefix, as that solves both the removal issue and other issues with ID collisions.
There was a problem hiding this comment.
Can we move images instead of copying them? This will leave the Image object in the unordered_map empty, but we'll never access it again (there's no getImage method on the AnnotationManager). We can treat the mere presence of the key as the availability of this image, and only call style.addImage when we still own the image.
There was a problem hiding this comment.
For clarity, I'd rather copy; it's cheap, because all that's being copied is an Immutable, which is a shared pointer. (Edit: we actually have to copy because annotation images must persist across style replacement.)
There was a problem hiding this comment.
Why are we making a copy here? We already own the style::Image object.
417d118 to
6c6cb2e
Compare
|
In order for this to not reduce the total combined capacity for spite and annotation images, while simultaneously not increasing the base memory consumption and failing the related test, we'll need to implement auto-growing atlas textures. |
6c6cb2e to
7b61b8a
Compare
7b61b8a to
957e6e0
Compare
| if (entry.iconRect) { | ||
| bin.release(*entry.iconRect); | ||
| if (entry.iconBin) { | ||
| // shelfPack.release(*iconBin); |
There was a problem hiding this comment.
Does shelfpack currently support removing bins?
There was a problem hiding this comment.
Not currently, we're waiting on v2 / mapbox/shelf-pack-cpp#5 which @bhousel is working on.
957e6e0 to
f3dbb82
Compare
67d5254 to
f7cd879
Compare
25018c1 to
5dc6a13
Compare
|
This is ready for re-review. |
e9cd79d to
4faedf6
Compare
|
|
||
| layer->setSourceLayer(PointLayerID); | ||
| layer->setIconImage({"{sprite}"}); | ||
| layer->setIconImage({SourceID + ".{sprite}"}); |
|
|
||
| for (const auto& image : images) { | ||
| if (!style.getImage(image.first)) { | ||
| style.addImage(std::make_unique<style::Image>(image.second)); |
There was a problem hiding this comment.
Could we move them instead of copying them? What is the benefit of retaining the image?
| // create a new image with the input ID prefixed by "com.mapbox.annotations". | ||
| std::string id = SourceID + "." + image->getID(); | ||
| images.emplace(id, | ||
| style::Image(id, image->getImage().clone(), image->getPixelRatio(), image->isSdf())); |
There was a problem hiding this comment.
This is a no-op when there is already an image with the same ID. Adding a different image with the same name will thus not have any affect. Is that the intended API behavior?
There was a problem hiding this comment.
Maybe we could have a list of IDs we currently have, a list of IDs to remove, and a map of new sprite images to add, then replace existing entries in the map when calling addImage.
There was a problem hiding this comment.
Good point; I think the existing behavior is to replace the image (if it's the same size). I'll confirm and preserve that if so.
There was a problem hiding this comment.
Keeping a map of new sprite images to add isn't sufficient, because we also need to add all images in the case where there's a fresh style.
Eventually I think we should refactor AnnotationManager so that it updates the style immediately in each operation, and is notified when there's a fresh style, but that's a separate refactor. For now I made it add all images every updateStyle.
We gained a lot of overhead by reducing the initial SpriteAtlas size.
4faedf6 to
ac2f1f3
Compare
Instead, just add them to the Style as needed. Includes changes from #8905 and takes care to avoid regressing #3817.
In order for this to not reduce the total combined capacity for spite and annotation images, while simultaneously not increasing the base memory consumption and failing the related test, it includes a switch to auto-growing the SpriteAtlas texture using shelf-pack-cpp. This also fixes #8247 ("Measured vectorFootprint = 31104204 Bytes").