From 64e2bcdf4395a1c65cd9faca81f98c4c5d974bd6 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Tue, 11 Feb 2020 01:54:05 +0200 Subject: [core] Loading images to style optimization This change enables attaching images to the style with batches and avoids massive re-allocations. Thus, it improves UI performance especially at start-up time. --- src/mbgl/sprite/sprite_loader.cpp | 2 +- src/mbgl/sprite/sprite_loader.hpp | 5 +-- src/mbgl/sprite/sprite_loader_observer.hpp | 7 +-- src/mbgl/sprite/sprite_parser.cpp | 72 ++++++++++++++++-------------- src/mbgl/sprite/sprite_parser.hpp | 2 +- 5 files changed, 46 insertions(+), 42 deletions(-) (limited to 'src/mbgl/sprite') diff --git a/src/mbgl/sprite/sprite_loader.cpp b/src/mbgl/sprite/sprite_loader.cpp index d4b1cade13..56f7abd50b 100644 --- a/src/mbgl/sprite/sprite_loader.cpp +++ b/src/mbgl/sprite/sprite_loader.cpp @@ -90,7 +90,7 @@ void SpriteLoader::emitSpriteLoadedIfComplete() { loader->worker.self().invoke(&SpriteLoaderWorker::parse, loader->image, loader->json); } -void SpriteLoader::onParsed(std::vector>&& result) { +void SpriteLoader::onParsed(std::vector> result) { observer->onSpriteLoaded(std::move(result)); } diff --git a/src/mbgl/sprite/sprite_loader.hpp b/src/mbgl/sprite/sprite_loader.hpp index 0b7d37fa14..d82c51e2da 100644 --- a/src/mbgl/sprite/sprite_loader.hpp +++ b/src/mbgl/sprite/sprite_loader.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -15,7 +14,7 @@ namespace mbgl { class FileSource; class SpriteLoaderObserver; -class SpriteLoader : public util::noncopyable { +class SpriteLoader { public: SpriteLoader(float pixelRatio); ~SpriteLoader(); @@ -29,7 +28,7 @@ private: // Invoked by SpriteAtlasWorker friend class SpriteLoaderWorker; - void onParsed(std::vector>&&); + void onParsed(std::vector>); void onError(std::exception_ptr); const float pixelRatio; diff --git a/src/mbgl/sprite/sprite_loader_observer.hpp b/src/mbgl/sprite/sprite_loader_observer.hpp index c730549c2c..3846d069f0 100644 --- a/src/mbgl/sprite/sprite_loader_observer.hpp +++ b/src/mbgl/sprite/sprite_loader_observer.hpp @@ -1,7 +1,9 @@ #pragma once +#include +#include + #include -#include #include namespace mbgl { @@ -13,8 +15,7 @@ class Image; class SpriteLoaderObserver { public: virtual ~SpriteLoaderObserver() = default; - - virtual void onSpriteLoaded(std::vector>&&) {} + virtual void onSpriteLoaded(std::vector>) {} virtual void onSpriteError(std::exception_ptr) {} }; diff --git a/src/mbgl/sprite/sprite_parser.cpp b/src/mbgl/sprite/sprite_parser.cpp index d39428a848..40e63d2d7d 100644 --- a/src/mbgl/sprite/sprite_parser.cpp +++ b/src/mbgl/sprite/sprite_parser.cpp @@ -149,50 +149,54 @@ optional getContent(const JSValue& value, const char* prope } // namespace -std::vector> parseSprite(const std::string& encodedImage, const std::string& json) { +std::vector> parseSprite(const std::string& encodedImage, const std::string& json) { const PremultipliedImage raster = decodeImage(encodedImage); JSDocument doc; doc.Parse<0>(json.c_str()); if (doc.HasParseError()) { throw std::runtime_error("Failed to parse JSON: " + formatJSONParseError(doc)); - } else if (!doc.IsObject()) { + } + + if (!doc.IsObject()) { throw std::runtime_error("Sprite JSON root must be an object"); - } else { - std::vector> images; - for (const auto& property : doc.GetObject()) { - const std::string name = { property.name.GetString(), property.name.GetStringLength() }; - const JSValue& value = property.value; - - if (value.IsObject()) { - const uint16_t x = getUInt16(value, "x", name.c_str(), 0); - const uint16_t y = getUInt16(value, "y", name.c_str(), 0); - const uint16_t width = getUInt16(value, "width", name.c_str(), 0); - const uint16_t height = getUInt16(value, "height", name.c_str(), 0); - const double pixelRatio = getDouble(value, "pixelRatio", name.c_str(), 1); - const bool sdf = getBoolean(value, "sdf", name.c_str(), false); - style::ImageStretches stretchX = getStretches(value, "stretchX", name.c_str()); - style::ImageStretches stretchY = getStretches(value, "stretchY", name.c_str()); - optional content = getContent(value, "content", name.c_str()); - - auto image = createStyleImage(name, - raster, - x, - y, - width, - height, - pixelRatio, - sdf, - std::move(stretchX), - std::move(stretchY), - std::move(content)); - if (image) { - images.push_back(std::move(image)); - } + } + + const auto& properties = doc.GetObject(); + std::vector> images; + images.reserve(properties.MemberCount()); + for (const auto& property : properties) { + const std::string name = {property.name.GetString(), property.name.GetStringLength()}; + const JSValue& value = property.value; + + if (value.IsObject()) { + const uint16_t x = getUInt16(value, "x", name.c_str(), 0); + const uint16_t y = getUInt16(value, "y", name.c_str(), 0); + const uint16_t width = getUInt16(value, "width", name.c_str(), 0); + const uint16_t height = getUInt16(value, "height", name.c_str(), 0); + const double pixelRatio = getDouble(value, "pixelRatio", name.c_str(), 1); + const bool sdf = getBoolean(value, "sdf", name.c_str(), false); + style::ImageStretches stretchX = getStretches(value, "stretchX", name.c_str()); + style::ImageStretches stretchY = getStretches(value, "stretchY", name.c_str()); + optional content = getContent(value, "content", name.c_str()); + + auto image = createStyleImage(name, + raster, + x, + y, + width, + height, + pixelRatio, + sdf, + std::move(stretchX), + std::move(stretchY), + std::move(content)); + if (image) { + images.push_back(std::move(image->baseImpl)); } } - return images; } + return images; } } // namespace mbgl diff --git a/src/mbgl/sprite/sprite_parser.hpp b/src/mbgl/sprite/sprite_parser.hpp index 9656bcbf2a..f2e7358ac2 100644 --- a/src/mbgl/sprite/sprite_parser.hpp +++ b/src/mbgl/sprite/sprite_parser.hpp @@ -20,6 +20,6 @@ std::unique_ptr createStyleImage(const std::string& id, optional content = nullopt); // Parses an image and an associated JSON file and returns the sprite objects. -std::vector> parseSprite(const std::string& image, const std::string& json); +std::vector> parseSprite(const std::string& image, const std::string& json); } // namespace mbgl -- cgit v1.2.1