Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core] Replace inline SpriteAtlas updates with diffing #9010

Merged
merged 1 commit into from
May 30, 2017
Merged

Conversation

jfirebaugh
Copy link
Contributor

Use style diffing to resolve updates to images and updates that require reloading tiles.

Copy link
Contributor

@kkaefer kkaefer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge target is not master?

};

template <class S, class U>
Immutable<S> staticImmutableCast(const Immutable<U>& u) {
return Immutable<S>(std::static_pointer_cast<const S>(u.ptr));
}

template <class S, class U>
Immutable<S> dynamicImmutableCast(const Immutable<U>& u) {
(void)dynamic_cast<const S&>(*u); // Call for side effect of failure.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the dynamic_cast fails, it'll throw a std::bad_cast exception, since the type is a reference type (rather than a pointer type). Can you please clarify this in the comment?

impl_->visibility != impl().visibility ||
impl_->layout != impl().layout ||
impl_->paint.hasDataDrivenPropertyDifference(impl().paint));
baseImpl = impl_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some implementations use std::swap and some use assignment. Is there a way to unify that?

@@ -33,6 +33,17 @@ std::unique_ptr<SymbolLayout> RenderSymbolLayer::createLayout(const BucketParame
glyphDependencies);
}

bool RenderSymbolLayer::updateImpl(Immutable<style::Layer::Impl> baseImpl_) {
auto impl_ = dynamicImmutableCast<style::SymbolLayer::Impl>(baseImpl_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of introducing yet another cast, can we do auto& impl_ = dynamic_cast<const style::SymbolLayer::Impl&>(*baseImpl_);, and just call std::swap(baseImpl_, baseImpl); below?


// Create render images for newly added images.
for (const auto& entry : imageDiff.added) {
spriteAtlas->addImage(entry.second);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creates a copy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, of the Immutable reference.

@jfirebaugh jfirebaugh force-pushed the image-id branch 2 times, most recently from 71cc762 to 4aa786d Compare May 16, 2017 18:56
@jfirebaugh jfirebaugh changed the base branch from image-id to render-sprite-atlas May 16, 2017 19:38
@kkaefer kkaefer added the Core The cross-platform C++ core, aka mbgl label May 17, 2017
@ivovandongen ivovandongen mentioned this pull request May 17, 2017
28 tasks
@jfirebaugh jfirebaugh force-pushed the render-sprite-atlas branch 2 times, most recently from 957e6e0 to f3dbb82 Compare May 22, 2017 20:33
@jfirebaugh jfirebaugh force-pushed the render-sprite-atlas branch 4 times, most recently from ad1d78c to b2886db Compare May 23, 2017 22:51
@jfirebaugh jfirebaugh force-pushed the render-sprite-atlas branch 6 times, most recently from 4faedf6 to ac2f1f3 Compare May 26, 2017 17:44
@jfirebaugh jfirebaugh changed the base branch from render-sprite-atlas to master May 26, 2017 18:32
@jfirebaugh
Copy link
Contributor Author

This is ready for re-review.

ImageDifference diffImages(const std::vector<ImmutableImage>& a,
const std::vector<ImmutableImage>& b) {
return diff(a, b, [] (const ImmutableImage& lhs, const ImmutableImage& rhs) {
return lhs->id == rhs->id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks down when two styles have sprites with image names that are identical, but actually refer to different images.

Copy link
Contributor Author

@jfirebaugh jfirebaugh May 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, the image will be added to the "changed" list, and subsequently passed to SpriteAtlas::addImage.

  • If the image is the same size, this will work.
  • If the image is a different size, this will fail an assertion.

#7618 is the underlying issue that should be fixed; I'm planning on working on that this week. In the meantime, I'll change the assertion to a regular conditional, mirroring this check.

Copy link
Contributor Author

@jfirebaugh jfirebaugh May 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleaned this up in b2e7794 but left the assertion; I don't believe there's currently a way to trigger it.

return diff(a, b);
return diff(a, b, [] (const ImmutableSource& lhs, const ImmutableSource& rhs) {
return std::tie(lhs->id, lhs->type)
== std::tie(rhs->id, rhs->type);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, this breaks down when id/type match, but different styles use the same source name (composite is the leading contender) to point to different underlying tilesets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, what needs to happen in this situation is that the source reloads its existing tiles and clears the cache. Refactoring Source::{reload,updateTiles,invalidate,remove}Tiles is also on my list this week, and I think that will be the best way to address this. Currently I don't think there's a way to trigger this -- we don't expose an API for changing a source's tileset, and we don't (yet) use diffing to morph between two completely separate styles. (Same for the image issue in fact.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and we don't (yet) use diffing to morph between two completely separate styles.

Ah, I thought we already did that, hence the comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: after thinking about how to handle this case once we do support smart set style, I decided I want to rework the "Eliminate Style::updateBatch in favor of diffing" part of this PR significantly. I'll land just the SpriteAtlas portion for now.

@jfirebaugh jfirebaugh force-pushed the style-diff branch 2 times, most recently from 9d94da0 to a8900b7 Compare May 29, 2017 18:27
@jfirebaugh jfirebaugh changed the title More style diffing [core] Replace inline SpriteAtlas updates with diffing May 30, 2017
@jfirebaugh jfirebaugh merged commit 6be6263 into master May 30, 2017
@jfirebaugh jfirebaugh deleted the style-diff branch May 30, 2017 21:24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants