Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/mbgl/platform/event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ enum class Event : uint8_t {
OpenGL,
JNI,
Android,
Crash
Crash,
Glyph,
};

MBGL_DEFINE_ENUM_CLASS(EventClass, Event, {
Expand All @@ -56,6 +57,7 @@ MBGL_DEFINE_ENUM_CLASS(EventClass, Event, {
{ Event::JNI, "JNI" },
{ Event::Android, "Android" },
{ Event::Crash, "Crash" },
{ Event::Glyph, "Glyph" },
{ Event(-1), "Unknown" },
});

Expand Down
4 changes: 2 additions & 2 deletions platform/linux/scripts/after_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then

REPO_NAME=$(basename $TRAVIS_REPO_SLUG)

aws s3 cp --recursive --acl public-read test/fixtures/annotations \
s3://mapbox/$REPO_NAME/render-tests/$TRAVIS_JOB_NUMBER/annotations
aws s3 cp --recursive --acl public-read --exclude "*" --include "*/actual.png" test/fixtures \
s3://mapbox/$REPO_NAME/render-tests/$TRAVIS_JOB_NUMBER
fi
15 changes: 6 additions & 9 deletions src/mbgl/map/map_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,6 @@ void MapContext::setStyleURL(const std::string& url) {

FileSource* fs = util::ThreadContext::getFileSource();
styleRequest = fs->request({ Resource::Kind::Style, styleURL }, [this, base](Response res) {
if (res.stale) {
// Only handle fresh responses.
return;
}
styleRequest = nullptr;

if (res.error) {
if (res.error->reason == Response::Error::Reason::NotFound &&
util::mapbox::isMapboxURL(styleURL)) {
Expand All @@ -120,9 +114,11 @@ void MapContext::setStyleURL(const std::string& url) {
data.loading = false;
}
} else {
loadStyleJSON(*res.data, base);
// We got a new stylesheet; only update when it's different from the previous one.
if (styleJSON != *res.data) {
loadStyleJSON(*res.data, base);
}
}

});
}

Expand All @@ -132,7 +128,7 @@ void MapContext::setStyleJSON(const std::string& json, const std::string& base)
}

styleURL.clear();
styleJSON = json;
styleJSON.clear();

style = std::make_unique<Style>(data);

Expand All @@ -144,6 +140,7 @@ void MapContext::loadStyleJSON(const std::string& json, const std::string& base)

style->setJSON(json, base);
style->setObserver(this);
styleJSON = json;

// force style cascade, causing all pending transitions to complete.
style->cascade();
Expand Down
30 changes: 18 additions & 12 deletions src/mbgl/map/raster_tile_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,26 @@ void RasterTileData::request(const std::string& url,

FileSource* fs = util::ThreadContext::getFileSource();
req = fs->request({ Resource::Kind::Tile, url }, [url, callback, this](Response res) {
if (res.stale) {
// Only handle fresh responses.
return;
}
req = nullptr;

if (res.error) {
std::exception_ptr error;
if (res.error->reason == Response::Error::Reason::NotFound) {
// This is a 404 response. We're treating these as empty tiles.
workRequest.reset();
state = State::parsed;
bucket.reset();
} else {
// This is a different error, e.g. a connection or server error.
error = std::make_exception_ptr(std::runtime_error(res.error->message));
state = State::obsolete;
}
callback();
callback(error);
return;
}

modified = res.modified;
expires = res.expires;

if (res.notModified) {
// We got the same data again. Abort early.
return;
}

Expand All @@ -48,24 +54,24 @@ void RasterTileData::request(const std::string& url,
state = State::loaded;
}

modified = res.modified;
expires = res.expires;

workRequest.reset();
workRequest = worker.parseRasterTile(std::make_unique<RasterBucket>(texturePool), res.data, [this, callback] (RasterTileParseResult result) {
workRequest.reset();
if (state != State::loaded) {
return;
}

std::exception_ptr error;
if (result.is<std::unique_ptr<Bucket>>()) {
state = State::parsed;
bucket = std::move(result.get<std::unique_ptr<Bucket>>());
} else {
error = result.get<std::exception_ptr>();
state = State::obsolete;
bucket.reset();
}

callback();
callback(error);
});
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/map/raster_tile_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class RasterTileData : public TileData {
RasterTileData(const TileID&, TexturePool&, Worker&);
~RasterTileData();

using Callback = std::function<void()>;
using Callback = std::function<void(std::exception_ptr)>;

void request(const std::string& url,
const Callback& callback);
Expand Down
59 changes: 49 additions & 10 deletions src/mbgl/map/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,13 @@ void Source::load() {
// URL may either be a TileJSON file, or a GeoJSON file.
FileSource* fs = util::ThreadContext::getFileSource();
req = fs->request({ Resource::Kind::Source, url }, [this](Response res) {
if (res.stale) {
// Only handle fresh responses.
if (res.error) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
return;
}
req = nullptr;

if (res.error) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
if (res.notModified) {
// We got the same data back as last time. Abort early.
return;
}

Expand All @@ -111,6 +110,7 @@ void Source::load() {
return;
}

bool reloadTiles = false;
if (type == SourceType::Vector || type == SourceType::Raster) {
// Create a new copy of the SourceInfo object that holds the base values we've parsed
// from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved
Expand All @@ -124,10 +124,39 @@ void Source::load() {
std::transform(newInfo->tiles.begin(), newInfo->tiles.end(), newInfo->tiles.begin(),
util::mapbox::normalizeRasterTileURL);
}

// Check whether previous information specifies different tile
if (info && info->tiles != newInfo->tiles) {
reloadTiles = true;

// Tile size changed: We need to recalculate the tiles we need to load because we
// might have to load tiles for a different zoom level
// This is done automatically when we trigger the onSourceLoaded observer below.

// Min/Max zoom changed: We need to recalculate what tiles to load, if we have tiles
// loaded that are outside the new zoom range
// This is done automatically when we trigger the onSourceLoaded observer below.

// Attribution changed: We need to notify the embedding application that this
// changed. See https://github.com/mapbox/mapbox-gl-native/issues/2723
// This is not yet implemented.

// Center/bounds changed: We're not using these values currently
}

info = std::move(newInfo);
} else if (type == SourceType::GeoJSON) {
info = std::make_unique<SourceInfo>();
geojsonvt = StyleParser::parseGeoJSON(d);
reloadTiles = true;
}

if (reloadTiles) {
// Tile information changed because we got new GeoJSON data, or a new tile URL.
tilePtrs.clear();
tileDataMap.clear();
tiles.clear();
cache.clear();
}

loaded = true;
Expand Down Expand Up @@ -196,7 +225,12 @@ bool Source::handlePartialTile(const TileID& tileID, Worker&) {
return true;
}

return tileData->parsePending([this, tileID]() {
return tileData->parsePending([this, tileID](std::exception_ptr error) {
if (error) {
observer->onTileError(*this, tileID, error);
return;
}

observer->onTileLoaded(*this, tileID, false);
});
}
Expand Down Expand Up @@ -230,7 +264,9 @@ TileData::State Source::addTile(const TileID& tileID, const StyleUpdateParameter
}

if (!newTile->data) {
auto callback = std::bind(&Source::tileLoadingCompleteCallback, this, normalizedID, parameters.transformState, parameters.debugOptions & MapDebugOptions::Collision);
auto callback = std::bind(&Source::tileLoadingCompleteCallback, this, normalizedID,
std::placeholders::_1, parameters.transformState,
parameters.debugOptions & MapDebugOptions::Collision);

// If we don't find working tile data, we're just going to load it.
if (type == SourceType::Raster) {
Expand Down Expand Up @@ -491,7 +527,10 @@ void Source::setObserver(Observer* observer_) {
observer = observer_;
}

void Source::tileLoadingCompleteCallback(const TileID& tileID, const TransformState& transformState, bool collisionDebug) {
void Source::tileLoadingCompleteCallback(const TileID& tileID,
std::exception_ptr error,
const TransformState& transformState,
bool collisionDebug) {
auto it = tileDataMap.find(tileID);
if (it == tileDataMap.end()) {
return;
Expand All @@ -502,8 +541,8 @@ void Source::tileLoadingCompleteCallback(const TileID& tileID, const TransformSt
return;
}

if (tileData->getState() == TileData::State::obsolete && tileData->getError()) {
observer->onTileError(*this, tileID, tileData->getError());
if (error) {
observer->onTileError(*this, tileID, error);
return;
}

Expand Down
5 changes: 4 additions & 1 deletion src/mbgl/map/source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ class Source : private util::noncopyable {
bool enabled = false;

private:
void tileLoadingCompleteCallback(const TileID&, const TransformState&, bool collisionDebug);
void tileLoadingCompleteCallback(const TileID&,
std::exception_ptr,
const TransformState&,
bool collisionDebug);
bool handlePartialTile(const TileID&, Worker& worker);
bool findLoadedChildren(const TileID&, int32_t maxCoveringZoom, std::forward_list<TileID>& retain);
void findLoadedParent(const TileID&, int32_t minCoveringZoom, std::forward_list<TileID>& retain);
Expand Down
4 changes: 0 additions & 4 deletions src/mbgl/map/tile_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ const char* TileData::StateToString(const State state) {
void TileData::dumpDebugLogs() const {
Log::Info(Event::General, "TileData::id: %s", std::string(id).c_str());
Log::Info(Event::General, "TileData::state: %s", TileData::StateToString(state));

if (error) {
Log::Info(Event::General, "TileData::error: %s", util::toString(error).c_str());
}
}

} // namespace mbgl
7 changes: 1 addition & 6 deletions src/mbgl/map/tile_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class TileData : private util::noncopyable {

virtual Bucket* getBucket(const StyleLayer&) = 0;

virtual bool parsePending(std::function<void ()>) { return true; }
virtual bool parsePending(std::function<void (std::exception_ptr)>) { return true; }
virtual void redoPlacement(PlacementConfig) {}

bool isReady() const {
Expand All @@ -88,10 +88,6 @@ class TileData : private util::noncopyable {
return state;
}

std::exception_ptr getError() const {
return error;
}

void dumpDebugLogs() const;

const TileID id;
Expand All @@ -103,7 +99,6 @@ class TileData : private util::noncopyable {

protected:
std::atomic<State> state;
std::exception_ptr error;
};

} // namespace mbgl
Expand Down
24 changes: 13 additions & 11 deletions src/mbgl/map/vector_tile_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ VectorTileData::VectorTileData(const TileID& id_,
std::string sourceID,
Style& style_,
const MapMode mode_,
const std::function<void()>& callback)
const std::function<void(std::exception_ptr)>& callback)
: TileData(id_),
style(style_),
worker(style_.workers),
Expand All @@ -32,16 +32,19 @@ VectorTileData::VectorTileData(const TileID& id_,
Seconds modified_,
Seconds expires_) {
if (err) {
error = err;
state = State::obsolete;
callback();
callback(err);
return;
}

modified = modified_;
expires = expires_;

if (!tile) {
// This is a 404 response. We're treating these as empty tiles.
workRequest.reset();
state = State::parsed;
buckets.clear();
callback();
callback(err);
return;
}

Expand All @@ -51,9 +54,6 @@ VectorTileData::VectorTileData(const TileID& id_,
state = State::partial;
}

modified = modified_;
expires = expires_;

// Kick off a fresh parse of this tile. This happens when the tile is new, or
// when tile data changed. Replacing the workdRequest will cancel a pending work
// request in case there is one.
Expand All @@ -64,6 +64,7 @@ VectorTileData::VectorTileData(const TileID& id_,
return;
}

std::exception_ptr error;
if (result.is<TileParseResultBuckets>()) {
auto& resultBuckets = result.get<TileParseResultBuckets>();
state = resultBuckets.state;
Expand All @@ -86,7 +87,7 @@ VectorTileData::VectorTileData(const TileID& id_,
state = State::obsolete;
}

callback();
callback(error);
});
});
}
Expand All @@ -95,7 +96,7 @@ VectorTileData::~VectorTileData() {
cancel();
}

bool VectorTileData::parsePending(std::function<void()> callback) {
bool VectorTileData::parsePending(std::function<void(std::exception_ptr)> callback) {
if (workRequest) {
// There's already parsing or placement going on.
return false;
Expand All @@ -108,6 +109,7 @@ bool VectorTileData::parsePending(std::function<void()> callback) {
return;
}

std::exception_ptr error;
if (result.is<TileParseResultBuckets>()) {
auto& resultBuckets = result.get<TileParseResultBuckets>();
state = resultBuckets.state;
Expand All @@ -132,7 +134,7 @@ bool VectorTileData::parsePending(std::function<void()> callback) {
state = State::obsolete;
}

callback();
callback(error);
});

return true;
Expand Down
Loading