summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/algorithm/update_renderables.hpp4
-rw-r--r--src/mbgl/annotation/annotation_tile.cpp3
-rw-r--r--src/mbgl/map/map.cpp24
-rw-r--r--src/mbgl/renderer/buckets/debug_bucket.cpp6
-rw-r--r--src/mbgl/renderer/buckets/debug_bucket.hpp4
-rw-r--r--src/mbgl/renderer/render_source.cpp4
-rw-r--r--src/mbgl/renderer/render_source.hpp2
-rw-r--r--src/mbgl/renderer/render_source_observer.hpp7
-rw-r--r--src/mbgl/renderer/render_style.cpp25
-rw-r--r--src/mbgl/renderer/render_style.hpp4
-rw-r--r--src/mbgl/renderer/render_style_observer.hpp4
-rw-r--r--src/mbgl/renderer/render_tile.cpp4
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp5
-rw-r--r--src/mbgl/renderer/renderer_impl.hpp2
-rw-r--r--src/mbgl/renderer/renderer_observer.hpp4
-rw-r--r--src/mbgl/renderer/tile_pyramid.cpp2
-rw-r--r--src/mbgl/sprite/sprite_loader.cpp45
-rw-r--r--src/mbgl/sprite/sprite_loader.hpp6
-rw-r--r--src/mbgl/sprite/sprite_loader_observer.hpp4
-rw-r--r--src/mbgl/sprite/sprite_loader_worker.cpp7
-rw-r--r--src/mbgl/sprite/sprite_loader_worker.hpp4
-rw-r--r--src/mbgl/storage/resource.cpp12
-rw-r--r--src/mbgl/storage/response.cpp31
-rw-r--r--src/mbgl/style/observer.hpp4
-rw-r--r--src/mbgl/style/source_observer.hpp4
-rw-r--r--src/mbgl/style/sources/vector_source.cpp17
-rw-r--r--src/mbgl/style/style_impl.cpp48
-rw-r--r--src/mbgl/style/style_impl.hpp6
-rw-r--r--src/mbgl/text/glyph_manager_observer.hpp6
-rw-r--r--src/mbgl/tile/geojson_tile.cpp2
-rw-r--r--src/mbgl/tile/geometry_tile.cpp49
-rw-r--r--src/mbgl/tile/raster_tile.cpp36
-rw-r--r--src/mbgl/tile/raster_tile.hpp1
-rw-r--r--src/mbgl/tile/raster_tile_worker.cpp1
-rw-r--r--src/mbgl/tile/tile.cpp19
-rw-r--r--src/mbgl/tile/tile.hpp56
-rw-r--r--src/mbgl/tile/tile_loader_impl.hpp15
-rw-r--r--src/mbgl/tile/tile_observer.hpp4
-rw-r--r--src/mbgl/tile/vector_tile.cpp10
-rw-r--r--src/mbgl/util/event.cpp1
40 files changed, 322 insertions, 170 deletions
diff --git a/src/mbgl/algorithm/update_renderables.hpp b/src/mbgl/algorithm/update_renderables.hpp
index 0c2266ff47..cc3d2c79f2 100644
--- a/src/mbgl/algorithm/update_renderables.hpp
+++ b/src/mbgl/algorithm/update_renderables.hpp
@@ -44,7 +44,6 @@ void updateRenderables(GetTileFn getTile,
renderTile(idealRenderTileID, *tile);
} else {
// We are now attempting to load child and parent tiles.
- bool parentHasTriedOptional = tile->hasTriedOptional();
bool parentIsLoaded = tile->isLoaded();
// The tile isn't loaded yet, but retain it anyway because it's an ideal tile.
@@ -92,7 +91,7 @@ void updateRenderables(GetTileFn getTile,
}
tile = getTile(parentDataTileID);
- if (!tile && (parentHasTriedOptional || parentIsLoaded)) {
+ if (!tile && parentIsLoaded) {
tile = createTile(parentDataTileID);
}
@@ -102,7 +101,6 @@ void updateRenderables(GetTileFn getTile,
// Save the current values, since they're the parent of the next iteration
// of the parent tile ascent loop.
- parentHasTriedOptional = tile->hasTriedOptional();
parentIsLoaded = tile->isLoaded();
if (tile->isRenderable()) {
diff --git a/src/mbgl/annotation/annotation_tile.cpp b/src/mbgl/annotation/annotation_tile.cpp
index f2520b75c3..1687ee29e6 100644
--- a/src/mbgl/annotation/annotation_tile.cpp
+++ b/src/mbgl/annotation/annotation_tile.cpp
@@ -23,9 +23,12 @@ void AnnotationTile::setNecessity(Necessity) {
}
void AnnotationTile::setData(std::unique_ptr<const GeometryTileData> data_) {
+ loaded = true;
+ logDebug("AnnotationTile::setData");
GeometryTile::setData(std::move(data_));
}
+
class AnnotationTileFeatureData {
public:
AnnotationTileFeatureData(const AnnotationID id_,
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 7d57f6863e..f4f1f9373a 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -11,10 +11,12 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
+#include <mbgl/storage/resource_error.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/mapbox.hpp>
+#include <mbgl/util/enum.hpp>
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/util/logging.hpp>
@@ -53,11 +55,11 @@ public:
void onUpdate(Update) override;
void onStyleLoading() override;
void onStyleLoaded() override;
- void onStyleError(std::exception_ptr) override;
+ void onStyleError(std::exception_ptr, EventSeverity) override;
// RendererObserver
void onInvalidate() override;
- void onResourceError(std::exception_ptr) override;
+ void onResourceError(std::exception_ptr, EventSeverity) override;
void onWillStartRenderingFrame() override;
void onDidFinishRenderingFrame(RenderMode, bool) override;
void onWillStartRenderingMap() override;
@@ -703,7 +705,7 @@ void Map::Impl::onUpdate(Update flags) {
timePoint,
transform.getState(),
style->impl->getGlyphURL(),
- style->impl->spriteLoaded,
+ style->impl->isSpriteLoaded(),
style->impl->getTransitionOptions(),
style->impl->getLight()->impl,
style->impl->getImageImpls(),
@@ -738,12 +740,22 @@ void Map::Impl::onStyleLoaded() {
observer.onDidFinishLoadingStyle();
}
-void Map::Impl::onStyleError(std::exception_ptr error) {
+void Map::Impl::onStyleError(std::exception_ptr error, const EventSeverity) {
observer.onDidFailLoadingMap(error);
}
-void Map::Impl::onResourceError(std::exception_ptr error) {
- if (mode == MapMode::Still && stillImageRequest) {
+void Map::Impl::onResourceError(std::exception_ptr error, const EventSeverity severity) {
+ try {
+ std::rethrow_exception(error);
+ } catch (const util::ResourceError& err) {
+ Log::Record(severity, Event::Resource, "%s loading %s from %s: %s",
+ Enum<ResourceStatus>::toString(err.status),
+ Enum<ResourceKind>::toString(err.kind), err.url.c_str(), err.what());
+ } catch (const std::exception& err) {
+ Log::Record(severity, Event::Resource, err.what());
+ }
+
+ if (severity == EventSeverity::Error && mode == MapMode::Still && stillImageRequest) {
auto request = std::move(stillImageRequest);
request->callback(error);
}
diff --git a/src/mbgl/renderer/buckets/debug_bucket.cpp b/src/mbgl/renderer/buckets/debug_bucket.cpp
index 53c751c443..763ae270ed 100644
--- a/src/mbgl/renderer/buckets/debug_bucket.cpp
+++ b/src/mbgl/renderer/buckets/debug_bucket.cpp
@@ -12,13 +12,13 @@ namespace mbgl {
DebugBucket::DebugBucket(const OverscaledTileID& id,
const bool renderable_,
- const bool complete_,
+ const bool loaded_,
optional<Timestamp> modified_,
optional<Timestamp> expires_,
MapDebugOptions debugMode_,
gl::Context& context)
: renderable(renderable_),
- complete(complete_),
+ loaded(loaded_),
modified(std::move(modified_)),
expires(std::move(expires_)),
debugMode(debugMode_) {
@@ -61,7 +61,7 @@ DebugBucket::DebugBucket(const OverscaledTileID& id,
double baseline = 200;
if (debugMode & MapDebugOptions::ParseStatus) {
const std::string text = util::toString(id) + " - " +
- (complete ? "complete" : renderable ? "renderable" : "pending");
+ (loaded ? "loaded" : renderable ? "renderable" : "pending");
addText(text, 50, baseline, 5);
baseline += 200;
}
diff --git a/src/mbgl/renderer/buckets/debug_bucket.hpp b/src/mbgl/renderer/buckets/debug_bucket.hpp
index fc3128e944..128d432b4b 100644
--- a/src/mbgl/renderer/buckets/debug_bucket.hpp
+++ b/src/mbgl/renderer/buckets/debug_bucket.hpp
@@ -21,14 +21,14 @@ class DebugBucket : private util::noncopyable {
public:
DebugBucket(const OverscaledTileID& id,
bool renderable,
- bool complete,
+ bool loaded,
optional<Timestamp> modified,
optional<Timestamp> expires,
MapDebugOptions,
gl::Context&);
const bool renderable;
- const bool complete;
+ const bool loaded;
const optional<Timestamp> modified;
const optional<Timestamp> expires;
const MapDebugOptions debugMode;
diff --git a/src/mbgl/renderer/render_source.cpp b/src/mbgl/renderer/render_source.cpp
index 7723a1c7ca..d07d8020a8 100644
--- a/src/mbgl/renderer/render_source.cpp
+++ b/src/mbgl/renderer/render_source.cpp
@@ -49,8 +49,8 @@ void RenderSource::onTileChanged(Tile& tile) {
observer->onTileChanged(*this, tile.id);
}
-void RenderSource::onTileError(Tile& tile, std::exception_ptr error) {
- observer->onTileError(*this, tile.id, error);
+void RenderSource::onTileError(Tile& tile, std::exception_ptr error, const EventSeverity severity) {
+ observer->onTileError(*this, tile.id, error, severity);
}
bool RenderSource::isEnabled() const {
diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp
index b565439588..6bc19a9e64 100644
--- a/src/mbgl/renderer/render_source.hpp
+++ b/src/mbgl/renderer/render_source.hpp
@@ -84,7 +84,7 @@ protected:
bool enabled = false;
void onTileChanged(Tile&) final;
- void onTileError(Tile&, std::exception_ptr) final;
+ void onTileError(Tile&, std::exception_ptr, EventSeverity) final;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/render_source_observer.hpp b/src/mbgl/renderer/render_source_observer.hpp
index 792a18db2b..1494337dd6 100644
--- a/src/mbgl/renderer/render_source_observer.hpp
+++ b/src/mbgl/renderer/render_source_observer.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/util/event.hpp>
+
#include <exception>
namespace mbgl {
@@ -12,7 +14,10 @@ public:
virtual ~RenderSourceObserver() = default;
virtual void onTileChanged(RenderSource&, const OverscaledTileID&) {}
- virtual void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) {}
+ virtual void onTileError(RenderSource&,
+ const OverscaledTileID&,
+ std::exception_ptr,
+ EventSeverity = EventSeverity::Error) {}
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp
index 3d95b12bc4..f84e6987aa 100644
--- a/src/mbgl/renderer/render_style.cpp
+++ b/src/mbgl/renderer/render_style.cpp
@@ -422,16 +422,25 @@ void RenderStyle::onLowMemory() {
}
}
-void RenderStyle::onGlyphsError(const FontStack& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) {
- Log::Error(Event::Style, "Failed to load glyph range %d-%d for font stack %s: %s",
- glyphRange.first, glyphRange.second, fontStackToString(fontStack).c_str(), util::toString(error).c_str());
- observer->onResourceError(error);
+void RenderStyle::onGlyphsError(const FontStack& fontStack,
+ const GlyphRange& glyphRange,
+ std::exception_ptr error,
+ const EventSeverity severity) {
+ Log::Record(severity, Event::Style, "Failed to load glyph range %d-%d for font stack %s: %s",
+ glyphRange.first, glyphRange.second, fontStackToString(fontStack).c_str(),
+ util::toString(error).c_str());
+ observer->onResourceError(error, severity);
}
-void RenderStyle::onTileError(RenderSource& source, const OverscaledTileID& tileID, std::exception_ptr error) {
- Log::Error(Event::Style, "Failed to load tile %s for source %s: %s",
- util::toString(tileID).c_str(), source.baseImpl->id.c_str(), util::toString(error).c_str());
- observer->onResourceError(error);
+void RenderStyle::onTileError(RenderSource& source,
+ const OverscaledTileID& tileID,
+ std::exception_ptr error,
+ const EventSeverity severity) {
+ Log::Record(severity, Event::Style, "Failed to load tile %s for source %s: %s",
+ util::toString(tileID).c_str(), source.baseImpl->id.c_str(),
+ util::toString(error).c_str());
+ observer->onResourceError(error, severity);
+ observer->onInvalidate();
}
void RenderStyle::onTileChanged(RenderSource&, const OverscaledTileID&) {
diff --git a/src/mbgl/renderer/render_style.hpp b/src/mbgl/renderer/render_style.hpp
index 23a640c482..3b45fde834 100644
--- a/src/mbgl/renderer/render_style.hpp
+++ b/src/mbgl/renderer/render_style.hpp
@@ -79,11 +79,11 @@ private:
RenderLight renderLight;
// GlyphManagerObserver implementation.
- void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) override;
+ void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr, EventSeverity) override;
// RenderSourceObserver implementation.
void onTileChanged(RenderSource&, const OverscaledTileID&) override;
- void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override;
+ void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr, EventSeverity) override;
RenderStyleObserver* observer;
ZoomHistory zoomHistory;
diff --git a/src/mbgl/renderer/render_style_observer.hpp b/src/mbgl/renderer/render_style_observer.hpp
index 5852dd68b8..095d7d53e4 100644
--- a/src/mbgl/renderer/render_style_observer.hpp
+++ b/src/mbgl/renderer/render_style_observer.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/util/event.hpp>
+
#include <exception>
namespace mbgl {
@@ -8,7 +10,7 @@ class RenderStyleObserver {
public:
virtual ~RenderStyleObserver() = default;
virtual void onInvalidate() {}
- virtual void onResourceError(std::exception_ptr) {}
+ virtual void onResourceError(std::exception_ptr, EventSeverity = EventSeverity::Error) {}
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp
index c9912f0563..c6670893ad 100644
--- a/src/mbgl/renderer/render_tile.cpp
+++ b/src/mbgl/renderer/render_tile.cpp
@@ -97,12 +97,12 @@ void RenderTile::finishRender(PaintParameters& parameters) {
if (parameters.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) {
if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() ||
- tile.debugBucket->complete != tile.isComplete() ||
+ tile.debugBucket->loaded != tile.isLoaded() ||
!(tile.debugBucket->modified == tile.modified) ||
!(tile.debugBucket->expires == tile.expires) ||
tile.debugBucket->debugMode != parameters.debugOptions) {
tile.debugBucket = std::make_unique<DebugBucket>(
- tile.id, tile.isRenderable(), tile.isComplete(), tile.modified,
+ tile.id, tile.isRenderable(), tile.isLoaded(), tile.modified,
tile.expires, parameters.debugOptions, parameters.context);
}
diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp
index 981c09e806..6e79f46ebe 100644
--- a/src/mbgl/renderer/renderer_impl.cpp
+++ b/src/mbgl/renderer/renderer_impl.cpp
@@ -69,6 +69,7 @@ void Renderer::Impl::render(View& view, const UpdateParameters& updateParameters
};
bool loaded = updateParameters.styleLoaded && renderStyle->isLoaded();
+ // fprintf(stderr, "loaded: %d\n", loaded);
if (updateParameters.mode == MapMode::Continuous) {
if (renderState == RenderState::Never) {
@@ -343,8 +344,8 @@ void Renderer::Impl::onInvalidate() {
observer->onInvalidate();
}
-void Renderer::Impl::onResourceError(std::exception_ptr ptr) {
- observer->onResourceError(ptr);
+void Renderer::Impl::onResourceError(std::exception_ptr ptr, const EventSeverity severity) {
+ observer->onResourceError(ptr, severity);
}
void Renderer::Impl::onLowMemory() {
diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp
index 521df6ca63..be10962174 100644
--- a/src/mbgl/renderer/renderer_impl.hpp
+++ b/src/mbgl/renderer/renderer_impl.hpp
@@ -37,7 +37,7 @@ public:
// RenderStyleObserver implementation
void onInvalidate() override;
- void onResourceError(std::exception_ptr) override;
+ void onResourceError(std::exception_ptr, EventSeverity) override;
private:
void doRender(PaintParameters&);
diff --git a/src/mbgl/renderer/renderer_observer.hpp b/src/mbgl/renderer/renderer_observer.hpp
index 551b5c803e..0cb4c69cef 100644
--- a/src/mbgl/renderer/renderer_observer.hpp
+++ b/src/mbgl/renderer/renderer_observer.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/util/event.hpp>
+
#include <exception>
namespace mbgl {
@@ -17,7 +19,7 @@ public:
virtual void onInvalidate() {}
// Resource failed to download / parse
- virtual void onResourceError(std::exception_ptr) {}
+ virtual void onResourceError(std::exception_ptr, EventSeverity = EventSeverity::Error) {}
// First frame
virtual void onWillStartRenderingMap() {}
diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp
index 219f154675..106f82b737 100644
--- a/src/mbgl/renderer/tile_pyramid.cpp
+++ b/src/mbgl/renderer/tile_pyramid.cpp
@@ -31,7 +31,7 @@ TilePyramid::~TilePyramid() = default;
bool TilePyramid::isLoaded() const {
for (const auto& pair : tiles) {
- if (!pair.second->isComplete()) {
+ if (!pair.second->isLoaded()) {
return false;
}
}
diff --git a/src/mbgl/sprite/sprite_loader.cpp b/src/mbgl/sprite/sprite_loader.cpp
index 60ece5ed73..d70f7b9597 100644
--- a/src/mbgl/sprite/sprite_loader.cpp
+++ b/src/mbgl/sprite/sprite_loader.cpp
@@ -10,6 +10,7 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
+#include <mbgl/storage/resource_error.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/actor/actor.hpp>
@@ -31,6 +32,10 @@ struct SpriteLoader::Loader {
std::unique_ptr<AsyncRequest> spriteRequest;
std::shared_ptr<Mailbox> mailbox;
Actor<SpriteLoaderWorker> worker;
+ uint64_t correlationID = 0;
+
+ bool parsed = false;
+ bool pending = false;
};
SpriteLoader::SpriteLoader(float pixelRatio_)
@@ -43,15 +48,20 @@ SpriteLoader::~SpriteLoader() = default;
void SpriteLoader::load(const std::string& url, Scheduler& scheduler, FileSource& fileSource) {
if (url.empty()) {
// Treat a non-existent sprite as a successfully loaded empty sprite.
+ loader.reset();
observer->onSpriteLoaded({});
return;
}
loader = std::make_unique<Loader>(scheduler, *this);
- loader->jsonRequest = fileSource.request(Resource::spriteJSON(url, pixelRatio), [this](Response res) {
+ const auto jsonResource = Resource::spriteJSON(url, pixelRatio);
+ loader->jsonRequest = fileSource.request(jsonResource, [this, url = jsonResource.url](Response res) {
if (res.error) {
- observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ const auto severity = loader->json ? EventSeverity::Warning : EventSeverity::Error;
+ util::ResourceError err(res.error->message, ResourceKind::SpriteJSON, res.error->status,
+ url);
+ observer->onSpriteError(std::make_exception_ptr(err), severity);
} else if (res.notModified) {
return;
} else if (res.noContent) {
@@ -64,9 +74,13 @@ void SpriteLoader::load(const std::string& url, Scheduler& scheduler, FileSource
}
});
- loader->spriteRequest = fileSource.request(Resource::spriteImage(url, pixelRatio), [this](Response res) {
+ const auto spriteResource = Resource::spriteImage(url, pixelRatio);
+ loader->spriteRequest = fileSource.request(spriteResource, [this, url = spriteResource.url](Response res) {
if (res.error) {
- observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ const auto severity = loader->json ? EventSeverity::Warning : EventSeverity::Error;
+ util::ResourceError err(res.error->message, ResourceKind::SpriteImage,
+ res.error->status, url);
+ observer->onSpriteError(std::make_exception_ptr(err), severity);
} else if (res.notModified) {
return;
} else if (res.noContent) {
@@ -79,6 +93,10 @@ void SpriteLoader::load(const std::string& url, Scheduler& scheduler, FileSource
});
}
+bool SpriteLoader::isLoaded() const {
+ return !loader || (loader->parsed && !loader->pending);
+}
+
void SpriteLoader::emitSpriteLoadedIfComplete() {
assert(loader);
@@ -86,14 +104,26 @@ void SpriteLoader::emitSpriteLoadedIfComplete() {
return;
}
- loader->worker.invoke(&SpriteLoaderWorker::parse, loader->image, loader->json);
+ loader->pending = true;
+
+ ++loader->correlationID;
+ loader->worker.invoke(&SpriteLoaderWorker::parse, loader->image, loader->json,
+ loader->correlationID);
}
-void SpriteLoader::onParsed(std::vector<std::unique_ptr<style::Image>>&& result) {
+void SpriteLoader::onParsed(std::vector<std::unique_ptr<style::Image>>&& result, const uint64_t resultCorrelationID) {
+ loader->parsed = true;
+ if (resultCorrelationID == loader->correlationID) {
+ loader->pending = false;
+ }
observer->onSpriteLoaded(std::move(result));
}
-void SpriteLoader::onError(std::exception_ptr err) {
+void SpriteLoader::onError(std::exception_ptr err, uint64_t const resultCorrelationID) {
+ loader->parsed = true;
+ if (resultCorrelationID == loader->correlationID) {
+ loader->pending = false;
+ }
observer->onSpriteError(err);
}
@@ -102,3 +132,4 @@ void SpriteLoader::setObserver(SpriteLoaderObserver* observer_) {
}
} // namespace mbgl
+
diff --git a/src/mbgl/sprite/sprite_loader.hpp b/src/mbgl/sprite/sprite_loader.hpp
index 0daf46be9c..f095084c8c 100644
--- a/src/mbgl/sprite/sprite_loader.hpp
+++ b/src/mbgl/sprite/sprite_loader.hpp
@@ -23,6 +23,8 @@ public:
void load(const std::string& url, Scheduler&, FileSource&);
+ bool isLoaded() const;
+
void setObserver(SpriteLoaderObserver*);
private:
@@ -30,8 +32,8 @@ private:
// Invoked by SpriteAtlasWorker
friend class SpriteLoaderWorker;
- void onParsed(std::vector<std::unique_ptr<style::Image>>&&);
- void onError(std::exception_ptr);
+ void onParsed(std::vector<std::unique_ptr<style::Image>>&&, uint64_t resultCorrelationID);
+ void onError(std::exception_ptr, uint64_t resultCorrelationID);
const float pixelRatio;
diff --git a/src/mbgl/sprite/sprite_loader_observer.hpp b/src/mbgl/sprite/sprite_loader_observer.hpp
index c730549c2c..9df94199d7 100644
--- a/src/mbgl/sprite/sprite_loader_observer.hpp
+++ b/src/mbgl/sprite/sprite_loader_observer.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/util/event.hpp>
+
#include <exception>
#include <memory>
#include <vector>
@@ -15,7 +17,7 @@ public:
virtual ~SpriteLoaderObserver() = default;
virtual void onSpriteLoaded(std::vector<std::unique_ptr<style::Image>>&&) {}
- virtual void onSpriteError(std::exception_ptr) {}
+ virtual void onSpriteError(std::exception_ptr, EventSeverity = EventSeverity::Error) {}
};
} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_loader_worker.cpp b/src/mbgl/sprite/sprite_loader_worker.cpp
index 4bded33d53..8258923aa5 100644
--- a/src/mbgl/sprite/sprite_loader_worker.cpp
+++ b/src/mbgl/sprite/sprite_loader_worker.cpp
@@ -9,7 +9,8 @@ SpriteLoaderWorker::SpriteLoaderWorker(ActorRef<SpriteLoaderWorker>, ActorRef<Sp
}
void SpriteLoaderWorker::parse(std::shared_ptr<const std::string> image,
- std::shared_ptr<const std::string> json) {
+ std::shared_ptr<const std::string> json,
+ const uint64_t correlationID) {
try {
if (!image) {
// This shouldn't happen, since we always invoke it with a non-empty pointer.
@@ -20,9 +21,9 @@ void SpriteLoaderWorker::parse(std::shared_ptr<const std::string> image,
throw std::runtime_error("missing sprite metadata");
}
- parent.invoke(&SpriteLoader::onParsed, parseSprite(*image, *json));
+ parent.invoke(&SpriteLoader::onParsed, parseSprite(*image, *json), correlationID);
} catch (...) {
- parent.invoke(&SpriteLoader::onError, std::current_exception());
+ parent.invoke(&SpriteLoader::onError, std::current_exception(), correlationID);
}
}
diff --git a/src/mbgl/sprite/sprite_loader_worker.hpp b/src/mbgl/sprite/sprite_loader_worker.hpp
index d61e07d14f..8bdcdd6139 100644
--- a/src/mbgl/sprite/sprite_loader_worker.hpp
+++ b/src/mbgl/sprite/sprite_loader_worker.hpp
@@ -14,7 +14,9 @@ class SpriteLoaderWorker {
public:
SpriteLoaderWorker(ActorRef<SpriteLoaderWorker>, ActorRef<SpriteLoader>);
- void parse(std::shared_ptr<const std::string> image, std::shared_ptr<const std::string> json);
+ void parse(std::shared_ptr<const std::string> image,
+ std::shared_ptr<const std::string> json,
+ uint64_t correlationID);
private:
ActorRef<SpriteLoader> parent;
diff --git a/src/mbgl/storage/resource.cpp b/src/mbgl/storage/resource.cpp
index 96fe5c0f4f..d5bb35b831 100644
--- a/src/mbgl/storage/resource.cpp
+++ b/src/mbgl/storage/resource.cpp
@@ -4,11 +4,23 @@
#include <mbgl/util/string.hpp>
#include <mbgl/util/token.hpp>
#include <mbgl/util/url.hpp>
+#include <mbgl/util/enum.hpp>
#include <cmath>
namespace mbgl {
+MBGL_DEFINE_ENUM(ResourceKind, {
+ { ResourceKind::Unknown, "Unknown" },
+ { ResourceKind::Style, "Style" },
+ { ResourceKind::Source, "Source" },
+ { ResourceKind::Tile, "Tile" },
+ { ResourceKind::Glyphs, "Glyphs" },
+ { ResourceKind::SpriteImage, "SpriteImage" },
+ { ResourceKind::SpriteJSON, "SpriteJSON" },
+ { ResourceKind::Image, "Image" },
+});
+
static std::string getQuadKey(int32_t x, int32_t y, int8_t z) {
std::string quadKey;
quadKey.reserve(z);
diff --git a/src/mbgl/storage/response.cpp b/src/mbgl/storage/response.cpp
index a40446a8a0..a8bfbd43d9 100644
--- a/src/mbgl/storage/response.cpp
+++ b/src/mbgl/storage/response.cpp
@@ -1,11 +1,21 @@
#include <mbgl/storage/response.hpp>
#include <mbgl/util/chrono.hpp>
+#include <mbgl/util/enum.hpp>
#include <iostream>
#include <cassert>
namespace mbgl {
+MBGL_DEFINE_ENUM(ResourceStatus, {
+ { ResourceStatus::Success, "Success" },
+ { ResourceStatus::NotFoundError, "NotFoundError" },
+ { ResourceStatus::ServerError, "ServerError" },
+ { ResourceStatus::ConnectionError, "ConnectionError" },
+ { ResourceStatus::RateLimitError, "RateLimitError" },
+ { ResourceStatus::OtherError, "OtherError" },
+});
+
Response::Response(const Response& res) {
*this = res;
}
@@ -25,25 +35,4 @@ Response::Error::Error(ResourceStatus reason_, std::string message_, optional<Ti
: status(reason_), message(std::move(message_)), retryAfter(std::move(retryAfter_)) {
}
-std::ostream& operator<<(std::ostream& os, ResourceStatus r) {
- switch (r) {
- case ResourceStatus::Success:
- return os << "ResourceStatus::Success";
- case ResourceStatus::NotFoundError:
- return os << "ResourceStatus::NotFoundError";
- case ResourceStatus::ServerError:
- return os << "ResourceStatus::ServerError";
- case ResourceStatus::ConnectionError:
- return os << "ResourceStatus::ConnectionError";
- case ResourceStatus::RateLimitError:
- return os << "ResourceStatus::RateLimitError";
- case ResourceStatus::OtherError:
- return os << "ResourceStatus::OtherError";
- }
-
- // The above switch is exhaustive, but placate GCC nonetheless:
- assert(false);
- return os;
-}
-
} // namespace mbgl
diff --git a/src/mbgl/style/observer.hpp b/src/mbgl/style/observer.hpp
index ea19c599e9..d9dee0344b 100644
--- a/src/mbgl/style/observer.hpp
+++ b/src/mbgl/style/observer.hpp
@@ -13,8 +13,8 @@ public:
virtual void onStyleLoading() {}
virtual void onStyleLoaded() {}
virtual void onUpdate(Update) {}
- virtual void onStyleError(std::exception_ptr) {}
- virtual void onResourceError(std::exception_ptr) {}
+ virtual void onStyleError(std::exception_ptr, EventSeverity = EventSeverity::Error) {}
+ virtual void onResourceError(std::exception_ptr, EventSeverity = EventSeverity::Error) {}
};
} // namespace style
diff --git a/src/mbgl/style/source_observer.hpp b/src/mbgl/style/source_observer.hpp
index c99eda955e..610897c4ce 100644
--- a/src/mbgl/style/source_observer.hpp
+++ b/src/mbgl/style/source_observer.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/util/event.hpp>
+
#include <exception>
namespace mbgl {
@@ -13,7 +15,7 @@ public:
virtual void onSourceLoaded(Source&) {}
virtual void onSourceChanged(Source&) {}
- virtual void onSourceError(Source&, std::exception_ptr) {}
+ virtual void onSourceError(Source&, std::exception_ptr, EventSeverity = EventSeverity::Error) {}
// Source description needs to be reloaded
virtual void onSourceDescriptionChanged(Source&) {}
diff --git a/src/mbgl/style/sources/vector_source.cpp b/src/mbgl/style/sources/vector_source.cpp
index ccdd453c75..b7ba869384 100644
--- a/src/mbgl/style/sources/vector_source.cpp
+++ b/src/mbgl/style/sources/vector_source.cpp
@@ -4,6 +4,7 @@
#include <mbgl/style/conversion/json.hpp>
#include <mbgl/style/conversion/tileset.hpp>
#include <mbgl/storage/file_source.hpp>
+#include <mbgl/storage/resource_error.hpp>
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/constants.hpp>
@@ -46,17 +47,21 @@ void VectorSource::loadDescription(FileSource& fileSource) {
const std::string& url = urlOrTileset.get<std::string>();
req = fileSource.request(Resource::source(url), [this, url](Response res) {
- if (res.error) {
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
- } else if (res.notModified) {
+ if (!res.error && res.notModified) {
return;
- } else if (res.noContent) {
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
+ } else if (res.error || res.noContent) {
+ const auto severity = loaded ? EventSeverity::Warning : EventSeverity::Error;
+ const std::string& message =
+ res.error ? res.error->message : "unexpectedly empty TileJSON";
+ const util::ResourceError err(message, ResourceKind::Source, res.error->status, url);
+ observer->onSourceError(*this, std::make_exception_ptr(err), severity);
} else {
conversion::Error error;
optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
if (!tileset) {
- observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
+ const auto severity = loaded ? EventSeverity::Warning : EventSeverity::Error;
+ observer->onSourceError(
+ *this, std::make_exception_ptr(std::runtime_error(error.message)), severity);
return;
}
diff --git a/src/mbgl/style/style_impl.cpp b/src/mbgl/style/style_impl.cpp
index 9cc2588ca7..f469769406 100644
--- a/src/mbgl/style/style_impl.cpp
+++ b/src/mbgl/style/style_impl.cpp
@@ -19,6 +19,7 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
+#include <mbgl/storage/resource_error.hpp>
namespace mbgl {
namespace style {
@@ -62,10 +63,15 @@ void Style::Impl::loadURL(const std::string& url_) {
}
if (res.error) {
- const std::string message = "loading style failed: " + res.error->message;
- Log::Error(Event::Setup, message.c_str());
- observer->onStyleError(std::make_exception_ptr(util::StyleLoadException(message)));
- observer->onResourceError(std::make_exception_ptr(std::runtime_error(res.error->message)));
+ const std::string message = "Failed to load style: " + res.error->message;
+ const auto severity = loaded ? EventSeverity::Warning : EventSeverity::Error;
+ Log::Record(severity, Event::Setup, message.c_str());
+ observer->onStyleError(std::make_exception_ptr(util::StyleLoadException(message)),
+ severity);
+ observer->onResourceError(
+ std::make_exception_ptr(util::ResourceError(res.error->message, ResourceKind::Style,
+ res.error->status, url)),
+ severity);
} else if (res.notModified || res.noContent) {
return;
} else {
@@ -111,7 +117,6 @@ void Style::Impl::parse(const std::string& json_) {
defaultPitch = parser.pitch;
setLight(std::make_unique<Light>(parser.light));
- spriteLoaded = false;
spriteLoader->load(parser.spriteURL, scheduler, fileSource);
glyphURL = parser.glyphURL;
@@ -264,7 +269,7 @@ bool Style::Impl::isLoaded() const {
return false;
}
- if (!spriteLoaded) {
+ if (!isSpriteLoaded()) {
return false;
}
@@ -277,6 +282,10 @@ bool Style::Impl::isLoaded() const {
return true;
}
+bool Style::Impl::isSpriteLoaded() const {
+ return spriteLoader->isLoaded();
+}
+
void Style::Impl::addImage(std::unique_ptr<style::Image> image) {
images.remove(image->getID()); // We permit using addImage to update.
images.add(std::move(image));
@@ -306,12 +315,16 @@ void Style::Impl::onSourceChanged(Source& source) {
observer->onUpdate(Update::Repaint);
}
-void Style::Impl::onSourceError(Source& source, std::exception_ptr error) {
- lastError = error;
- Log::Error(Event::Style, "Failed to load source %s: %s",
- source.getID().c_str(), util::toString(error).c_str());
- observer->onSourceError(source, error);
- observer->onResourceError(error);
+void Style::Impl::onSourceError(Source& source,
+ std::exception_ptr error,
+ const EventSeverity severity) {
+ if (severity == EventSeverity::Error) {
+ lastError = error;
+ }
+ Log::Record(severity, Event::Style, "Failed to load source %s: %s", source.getID().c_str(),
+ util::toString(error).c_str());
+ observer->onSourceError(source, error, severity);
+ observer->onResourceError(error, severity);
}
void Style::Impl::onSourceDescriptionChanged(Source& source) {
@@ -326,14 +339,15 @@ void Style::Impl::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_)
for (auto& image : images_) {
addImage(std::move(image));
}
- spriteLoaded = true;
observer->onUpdate(Update::Repaint); // For *-pattern properties.
}
-void Style::Impl::onSpriteError(std::exception_ptr error) {
- lastError = error;
- Log::Error(Event::Style, "Failed to load sprite: %s", util::toString(error).c_str());
- observer->onResourceError(error);
+void Style::Impl::onSpriteError(std::exception_ptr error, const EventSeverity severity) {
+ if (severity == EventSeverity::Error) {
+ lastError = error;
+ }
+ Log::Record(severity, Event::Style, "Failed to load sprite: %s", util::toString(error).c_str());
+ observer->onResourceError(error, severity);
}
void Style::Impl::onLayerChanged(Layer& layer) {
diff --git a/src/mbgl/style/style_impl.hpp b/src/mbgl/style/style_impl.hpp
index 76f244d5a4..4eead24ca1 100644
--- a/src/mbgl/style/style_impl.hpp
+++ b/src/mbgl/style/style_impl.hpp
@@ -48,6 +48,7 @@ public:
void setObserver(Observer*);
bool isLoaded() const;
+ bool isSpriteLoaded() const;
std::exception_ptr getLastError() const {
return lastError;
@@ -94,7 +95,6 @@ public:
bool mutated = false;
bool loaded = false;
- bool spriteLoaded = false;
private:
void parse(const std::string&);
@@ -124,12 +124,12 @@ private:
// SpriteLoaderObserver implementation.
void onSpriteLoaded(std::vector<std::unique_ptr<Image>>&&) override;
- void onSpriteError(std::exception_ptr) override;
+ void onSpriteError(std::exception_ptr, EventSeverity) override;
// SourceObserver implementation.
void onSourceLoaded(Source&) override;
void onSourceChanged(Source&) override;
- void onSourceError(Source&, std::exception_ptr) override;
+ void onSourceError(Source&, std::exception_ptr, EventSeverity) override;
void onSourceDescriptionChanged(Source&) override;
// LayerObserver implementation.
diff --git a/src/mbgl/text/glyph_manager_observer.hpp b/src/mbgl/text/glyph_manager_observer.hpp
index b8678e060a..134998b890 100644
--- a/src/mbgl/text/glyph_manager_observer.hpp
+++ b/src/mbgl/text/glyph_manager_observer.hpp
@@ -3,6 +3,7 @@
#include <mbgl/style/types.hpp>
#include <mbgl/text/glyph_range.hpp>
#include <mbgl/util/font_stack.hpp>
+#include <mbgl/util/event.hpp>
#include <exception>
@@ -13,7 +14,10 @@ public:
virtual ~GlyphManagerObserver() = default;
virtual void onGlyphsLoaded(const FontStack&, const GlyphRange&) {}
- virtual void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) {}
+ virtual void onGlyphsError(const FontStack&,
+ const GlyphRange&,
+ std::exception_ptr,
+ EventSeverity = EventSeverity::Error) {}
};
} // namespace mbgl
diff --git a/src/mbgl/tile/geojson_tile.cpp b/src/mbgl/tile/geojson_tile.cpp
index 6b0cd8f947..366ee28ac1 100644
--- a/src/mbgl/tile/geojson_tile.cpp
+++ b/src/mbgl/tile/geojson_tile.cpp
@@ -106,6 +106,8 @@ GeoJSONTile::GeoJSONTile(const OverscaledTileID& overscaledTileID,
}
void GeoJSONTile::updateData(mapbox::geometry::feature_collection<int16_t> features) {
+ loaded = true;
+ logDebug("GeoJSONTile::setData");
GeometryTile::setData(std::make_unique<GeoJSONTileData>(std::move(features)));
}
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index fdbad8bd40..f097001af4 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -61,8 +61,7 @@ void GeometryTile::markObsolete() {
}
void GeometryTile::setError(std::exception_ptr err) {
- loaded = true;
- renderable = false;
+ logDebug("GeometryTile::setError");
observer->onTileError(*this, err);
}
@@ -71,6 +70,8 @@ void GeometryTile::setData(std::unique_ptr<const GeometryTileData> data_) {
// state despite pending parse operations.
pending = true;
+ logDebug("GeometryTile::setData");
+
++correlationID;
worker.invoke(&GeometryTileWorker::setData, std::move(data_), correlationID);
}
@@ -81,8 +82,13 @@ void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) {
}
// Mark the tile as pending again if it was complete before to prevent signaling a complete
- // state despite pending parse operations.
- pending = true;
+ // state despite pending parse operations. However, we only need to worry about this when we
+ // know that there's data, merely sending layers over doesn't qualify.
+ if (parsed) {
+ pending = true;
+ }
+
+ logDebug("GeometryTile::setPlacementConfig");
++correlationID;
requestedConfig = desiredConfig;
@@ -97,8 +103,13 @@ void GeometryTile::invokePlacement() {
void GeometryTile::setLayers(const std::vector<Immutable<Layer::Impl>>& layers) {
// Mark the tile as pending again if it was complete before to prevent signaling a complete
- // state despite pending parse operations.
- pending = true;
+ // state despite pending parse operations. However, we only need to worry about this when we
+ // know that there's data, merely sending layers over doesn't qualify.
+ if (parsed) {
+ pending = true;
+ }
+
+ logDebug("GeometryTile::setLayers");
std::vector<Immutable<Layer::Impl>> impls;
@@ -121,22 +132,19 @@ void GeometryTile::setLayers(const std::vector<Immutable<Layer::Impl>>& layers)
}
void GeometryTile::onLayout(LayoutResult result, const uint64_t resultCorrelationID) {
- loaded = true;
- renderable = true;
nonSymbolBuckets = std::move(result.nonSymbolBuckets);
featureIndex = std::move(result.featureIndex);
data = std::move(result.tileData);
collisionTile.reset();
+ parsed = true;
+ renderable = true;
+ // We're waiting on a onPlacement event for this correlation ID to reset the pending state.
(void)resultCorrelationID;
+ logDebug("GeometryTile::onLayout");
observer->onTileChanged(*this);
}
void GeometryTile::onPlacement(PlacementResult result, const uint64_t resultCorrelationID) {
- loaded = true;
- renderable = true;
- if (resultCorrelationID == correlationID) {
- pending = false;
- }
symbolBuckets = std::move(result.symbolBuckets);
collisionTile = std::move(result.collisionTile);
if (result.glyphAtlasImage) {
@@ -148,14 +156,21 @@ void GeometryTile::onPlacement(PlacementResult result, const uint64_t resultCorr
if (collisionTile.get()) {
lastYStretch = collisionTile->yStretch;
}
+ parsed = true;
+ renderable = true;
+ if (resultCorrelationID == correlationID) {
+ pending = false;
+ }
+ logDebug("GeometryTile::onPlacement");
observer->onTileChanged(*this);
}
void GeometryTile::onError(std::exception_ptr err, const uint64_t resultCorrelationID) {
- loaded = true;
- pending = false;
- (void)resultCorrelationID;
- renderable = false;
+ parsed = true;
+ if (resultCorrelationID == correlationID) {
+ pending = false;
+ }
+ logDebug("GeometryTile::onError");
observer->onTileError(*this, err);
}
diff --git a/src/mbgl/tile/raster_tile.cpp b/src/mbgl/tile/raster_tile.cpp
index be78a9988b..c7f0ecae97 100644
--- a/src/mbgl/tile/raster_tile.cpp
+++ b/src/mbgl/tile/raster_tile.cpp
@@ -20,6 +20,7 @@ RasterTile::RasterTile(const OverscaledTileID& id_,
mailbox(std::make_shared<Mailbox>(*util::RunLoop::Get())),
worker(parameters.workerScheduler,
ActorRef<RasterTile>(*this, mailbox)) {
+ logDebug("RasterTile::RasterTile");
}
RasterTile::~RasterTile() = default;
@@ -29,9 +30,10 @@ void RasterTile::cancel() {
// Called instead of setData() when the data source returns an error while loading this tile.
void RasterTile::setError(std::exception_ptr err, const bool complete) {
- (void)complete;
- loaded = true;
- renderable = false;
+ if (complete) {
+ failed = true;
+ }
+ logDebug("RasterTile::setError");
observer->onTileError(*this, err);
}
@@ -41,11 +43,19 @@ void RasterTile::setData(optional<std::shared_ptr<const std::string>> data,
optional<Timestamp> modified_,
optional<Timestamp> expires_,
const bool complete) {
- (void)complete;
modified = modified_;
expires = expires_;
+ if (complete) {
+ loaded = true;
+ }
if (data) {
+ // Mark the tile as pending again if it was complete before to prevent signaling a complete
+ // state despite pending parse operations.
+ pending = true;
+
+ logDebug("RasterTile::setData");
+
++correlationID;
worker.invoke(&RasterTileWorker::parse, *data, correlationID);
}
@@ -53,19 +63,23 @@ void RasterTile::setData(optional<std::shared_ptr<const std::string>> data,
// Invoked once the worker thread finished parsing the image.
void RasterTile::onParsed(std::unique_ptr<RasterBucket> result, const uint64_t resultCorrelationID) {
- (void)resultCorrelationID;
bucket = std::move(result);
- loaded = true;
- renderable = bucket ? true : false;
+ parsed = true;
+ renderable = true;
+ if (resultCorrelationID == correlationID) {
+ pending = false;
+ }
+ logDebug("RasterTile::onParsed");
observer->onTileChanged(*this);
}
// Invoked when the worker thread fails to parse the image.
void RasterTile::onError(std::exception_ptr err, const uint64_t resultCorrelationID) {
- (void)resultCorrelationID;
- bucket.reset();
- loaded = true;
- renderable = false;
+ parsed = true;
+ if (resultCorrelationID == correlationID) {
+ pending = false;
+ }
+ logDebug("RasterTile::onError");
observer->onTileError(*this, err);
}
diff --git a/src/mbgl/tile/raster_tile.hpp b/src/mbgl/tile/raster_tile.hpp
index f5f6ea944c..1c8032e298 100644
--- a/src/mbgl/tile/raster_tile.hpp
+++ b/src/mbgl/tile/raster_tile.hpp
@@ -54,3 +54,4 @@ private:
};
} // namespace mbgl
+
diff --git a/src/mbgl/tile/raster_tile_worker.cpp b/src/mbgl/tile/raster_tile_worker.cpp
index e42a78c26a..80cc57c5d5 100644
--- a/src/mbgl/tile/raster_tile_worker.cpp
+++ b/src/mbgl/tile/raster_tile_worker.cpp
@@ -18,6 +18,7 @@ void RasterTileWorker::parse(std::shared_ptr<const std::string> data, const uint
try {
auto bucket = std::make_unique<RasterBucket>(decodeImage(*data));
+// sleep(2);
parent.invoke(&RasterTile::onParsed, std::move(bucket), correlationID);
} catch (...) {
parent.invoke(&RasterTile::onError, std::current_exception(), correlationID);
diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp
index 35fc31dae1..c060017241 100644
--- a/src/mbgl/tile/tile.cpp
+++ b/src/mbgl/tile/tile.cpp
@@ -5,6 +5,8 @@
#include <mbgl/util/string.hpp>
#include <mbgl/util/logging.hpp>
+#include <iostream>
+
namespace mbgl {
static TileObserver nullObserver;
@@ -18,15 +20,20 @@ void Tile::setObserver(TileObserver* observer_) {
observer = observer_;
}
-void Tile::setTriedOptional() {
- triedOptional = true;
- observer->onTileChanged(*this);
-}
-
void Tile::dumpDebugLogs() const {
Log::Info(Event::General, "Tile::id: %s", util::toString(id).c_str());
+ Log::Info(Event::General, "Tile::loaded: %s", isLoaded() ? "yes" : "no");
Log::Info(Event::General, "Tile::renderable: %s", isRenderable() ? "yes" : "no");
- Log::Info(Event::General, "Tile::complete: %s", isComplete() ? "yes" : "no");
+}
+
+void Tile::logDebug(const char* name) const {
+ // std::cerr << "[" << this << "] " << name << " " << id << " ("
+ // << "loaded: " << loaded << ", "
+ // << "parsed: " << parsed << ", "
+ // << "failed: " << failed << ", "
+ // << "renderable: " << renderable << ", "
+ // << "pending: " << pending << ")" << std::endl;
+ (void)name;
}
void Tile::queryRenderedFeatures(
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index a1ab6a84b7..800752f8c9 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -68,39 +68,29 @@ public:
std::vector<Feature>& result,
const SourceQueryOptions&);
- void setTriedOptional();
-
- // Returns true when the tile source has received a first response, regardless of whether a load
- // error occurred or actual data was loaded.
- bool hasTriedOptional() const {
- return triedOptional;
- }
-
- // Tile data considered "Renderable" can be used for rendering. Data in
- // partial state is still waiting for network resources but can also
- // be rendered, although layers will be missing.
+ // Tile data considered "Renderable" can be used for rendering. It doesn't necessarily mean that
+ // there is anything to render, since tiles can be empty. Tiles that are still waiting for
+ // network resources but can also be rendered, although layers will be missing.
bool isRenderable() const {
return renderable;
}
- // A tile is "Loaded" when we have received a response from a FileSource, and have attempted to
- // parse the tile (if applicable). Tile implementations should set this to true when a load
- // error occurred, or after the tile was parsed successfully.
+ // A tile is "loaded" when we have received a response from a FileSource, and have attempted
+ // to parse the tile (if applicable), and there are no further operations in progress to acquire
+ // more, newer, or better data. Furthermore, it means that there are no pending layout/placement
+ // or parsing operations going on. Completeness doesn't mean that the tile can be rendered, but
+ // merely that we have exhausted all options to get this tile to a renderable state. Some tiles
+ // may not be renderable, but complete, e.g. when a raster tile couldn't be loaded, or parsing
+ // failed.
bool isLoaded() const {
- return loaded;
- }
-
- // "Completion" of a tile means that we have attempted to load it, and parsed it completely,
- // i.e. no parsing or placement operations are pending for that tile.
- // Completeness doesn't mean that the tile can be rendered, but merely that we have exhausted
- // all options to get this tile to a renderable state. Some tiles may not be renderable, but
- // complete, e.g. when a raster tile couldn't be loaded, or parsing failed.
- bool isComplete() const {
- return loaded && !pending;
+ return (loaded ? parsed : failed) && !pending;
}
void dumpDebugLogs() const;
+ void logDebug(const char*) const;
+
+ // This information is only used for displaying debugging information.
const OverscaledTileID id;
optional<Timestamp> modified;
optional<Timestamp> expires;
@@ -111,10 +101,24 @@ public:
virtual float yStretch() const { return 1.0f; }
protected:
- bool triedOptional = false;
+ // A tile is loaded when we acquired data for it, and no further operations to acquire more,
+ // newer, or better data are in progress.
+ bool loaded = false;
+
+ // A tile is marked as failed when we tried to acquire data, but couldn't, and no further
+ // operations to acquire more, newer, or better data are in progress.
+ bool failed = false;
+
+ // A tile is marked as parsed when we attempted to parse its contents. It doesn't necessairly
+ // mean that we *successfully* parsed it, just that there's been an attempt.
+ bool parsed = false;
+
+ // Renderability means that we successfully parsed a tile. Note that it doesn't mean there's
+ // anything to render (e.g. vector tiles may be empty).
bool renderable = false;
+
+ // A tile is pending while parsing or placement operations are going on.
bool pending = false;
- bool loaded = false;
TileObserver* observer = nullptr;
};
diff --git a/src/mbgl/tile/tile_loader_impl.hpp b/src/mbgl/tile/tile_loader_impl.hpp
index 5bf9988485..dc57d61e5a 100644
--- a/src/mbgl/tile/tile_loader_impl.hpp
+++ b/src/mbgl/tile/tile_loader_impl.hpp
@@ -53,11 +53,10 @@ void TileLoader<T>::loadOptional() {
assert(!request);
resource.necessity = Resource::Optional;
+// fprintf(stderr, "requesting %s\n", resource.url.c_str());
request = fileSource.request(resource, [this](Response res) {
request.reset();
- tile.setTriedOptional();
-
if (res.error && res.error->status == ResourceStatus::NotFoundError) {
// When the optional request could not be satisfied, don't treat it as an error.
// Instead, we make sure that the next request knows that there has been an optional
@@ -92,18 +91,18 @@ template <typename T>
void TileLoader<T>::loadedData(const Response& res) {
const bool complete = necessity == Necessity::Optional || resource.necessity == Necessity::Required;
if (res.error) {
- tile.setError(std::make_exception_ptr(util::ResourceError(res.error->message, resource.kind,
- res.error->status, resource.url)),
- complete);
+ util::ResourceError err(res.error->message, resource.kind, res.error->status, resource.url);
+ tile.setError(std::make_exception_ptr(err), complete);
} else if (res.notModified) {
resource.priorExpires = res.expires;
- // Do not notify the tile; when we get this message, it already has the current
+ tile.setData({}, res.modified, res.expires, complete);
+ // Do not notify the tile of new data; when we get this message, it already has the current
// version of the data.
} else {
resource.priorModified = res.modified;
resource.priorExpires = res.expires;
resource.priorEtag = res.etag;
- tile.setData(res.noContent ? nullptr : res.data, res.modified, res.expires, complete);
+ tile.setData({ res.noContent ? nullptr : res.data }, res.modified, res.expires, complete);
}
}
@@ -112,7 +111,9 @@ void TileLoader<T>::loadRequired() {
assert(!request);
resource.necessity = Resource::Required;
+// fprintf(stderr, "requesting %s\n", resource.url.c_str());
request = fileSource.request(resource, [this](Response res) { loadedData(res); });
}
} // namespace mbgl
+
diff --git a/src/mbgl/tile/tile_observer.hpp b/src/mbgl/tile/tile_observer.hpp
index 837b47ae0b..4970ffefb0 100644
--- a/src/mbgl/tile/tile_observer.hpp
+++ b/src/mbgl/tile/tile_observer.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <mbgl/util/event.hpp>
+
#include <exception>
namespace mbgl {
@@ -11,7 +13,7 @@ public:
virtual ~TileObserver() = default;
virtual void onTileChanged(Tile&) {}
- virtual void onTileError(Tile&, std::exception_ptr) {}
+ virtual void onTileError(Tile&, std::exception_ptr, EventSeverity = EventSeverity::Error) {}
};
} // namespace mbgl
diff --git a/src/mbgl/tile/vector_tile.cpp b/src/mbgl/tile/vector_tile.cpp
index e22ccf0d54..9cdf0d47ef 100644
--- a/src/mbgl/tile/vector_tile.cpp
+++ b/src/mbgl/tile/vector_tile.cpp
@@ -10,6 +10,7 @@ VectorTile::VectorTile(const OverscaledTileID& id_,
const TileParameters& parameters,
const Tileset& tileset)
: GeometryTile(id_, sourceID_, parameters), loader(*this, id_, parameters, tileset) {
+ logDebug("VectorTile::VectorTile");
}
void VectorTile::setNecessity(Necessity necessity) {
@@ -17,7 +18,10 @@ void VectorTile::setNecessity(Necessity necessity) {
}
void VectorTile::setError(std::exception_ptr err, const bool complete) {
- (void)complete;
+ if (complete) {
+ failed = true;
+ }
+ logDebug("VectorTile::setError");
GeometryTile::setError(err);
}
@@ -28,6 +32,10 @@ void VectorTile::setData(optional<std::shared_ptr<const std::string>> data,
(void)complete;
modified = modified_;
expires = expires_;
+ if (complete) {
+ loaded = true;
+ }
+ logDebug("VectorTile::setData");
if (data) {
GeometryTile::setData(*data ? std::make_unique<VectorTileData>(*data) : nullptr);
diff --git a/src/mbgl/util/event.cpp b/src/mbgl/util/event.cpp
index 3a3be20f5c..ea534fe412 100644
--- a/src/mbgl/util/event.cpp
+++ b/src/mbgl/util/event.cpp
@@ -28,6 +28,7 @@ MBGL_DEFINE_ENUM(Event, {
{ Event::Android, "Android" },
{ Event::Crash, "Crash" },
{ Event::Glyph, "Glyph" },
+ { Event::Resource, "Resource" },
{ Event(-1), "Unknown" },
});