From 9a70e755dcc52a661ac29715b048afee5d938bee Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 23 Apr 2019 08:21:09 +0200 Subject: [core] Track missing style images that were provided by client - Track images provided by client thruough onStyleImageMissing API - Handle reduceMemoryUsage in ImageManager, via Renderer API - Release client provided images when no tiles are using them --- src/mbgl/renderer/image_manager.cpp | 35 ++++++++++++++++++++++++++++++----- src/mbgl/renderer/image_manager.hpp | 3 +++ src/mbgl/renderer/renderer_impl.cpp | 3 +++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp index 25acd6bd25..f373167493 100644 --- a/src/mbgl/renderer/image_manager.cpp +++ b/src/mbgl/renderer/image_manager.cpp @@ -48,8 +48,8 @@ bool ImageManager::updateImage(Immutable image_) { updatedImageVersions[image_->id]++; } - removeImage(image_->id); - addImage(std::move(image_)); + removePattern(image_->id); + oldImage->second = std::move(image_); return sizeChanged; } @@ -57,7 +57,11 @@ bool ImageManager::updateImage(Immutable image_) { void ImageManager::removeImage(const std::string& id) { assert(images.find(id) != images.end()); images.erase(id); + requestedImages.erase(id); + removePattern(id); +} +void ImageManager::removePattern(const std::string& id) { auto it = patterns.find(id); if (it != patterns.end()) { // Clear pattern from the atlas image. @@ -95,7 +99,12 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair) for (const auto& dependency : pair.first) { if (images.find(dependency.first) == images.end()) { hasAllDependencies = false; - break; + } else { + // Associate requestor with an image that was provided by the client. + auto it = requestedImages.find(dependency.first); + if (it != requestedImages.end()) { + it->second.emplace(&requestor); + } } } @@ -112,15 +121,30 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair) void ImageManager::removeRequestor(ImageRequestor& requestor) { requestors.erase(&requestor); missingImageRequestors.erase(&requestor); + for (auto& requestedImage : requestedImages) { + requestedImage.second.erase(&requestor); + } } void ImageManager::notifyIfMissingImageAdded() { for (auto it = missingImageRequestors.begin(); it != missingImageRequestors.end();) { if (it->second.callbacksRemaining == 0) { notify(*it->first, it->second.pair); - missingImageRequestors.erase(it++); + it = missingImageRequestors.erase(it); + } else { + ++it; + } + } +} + +void ImageManager::reduceMemoryUse() { + for (auto it = requestedImages.cbegin(); it != requestedImages.cend();) { + if (it->second.empty() && images.find(it->first) != images.end()) { + images.erase(it->first); + removePattern(it->first); + it = requestedImages.erase(it); } else { - it++; + ++it; } } } @@ -131,6 +155,7 @@ void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageR auto it = images.find(dependency.first); if (it == images.end()) { missing++; + requestedImages[dependency.first].emplace(&requestor); } } diff --git a/src/mbgl/renderer/image_manager.hpp b/src/mbgl/renderer/image_manager.hpp index 99887ae384..f52808b614 100644 --- a/src/mbgl/renderer/image_manager.hpp +++ b/src/mbgl/renderer/image_manager.hpp @@ -56,12 +56,14 @@ public: void getImages(ImageRequestor&, ImageRequestPair&&); void removeRequestor(ImageRequestor&); void notifyIfMissingImageAdded(); + void reduceMemoryUse(); ImageVersionMap updatedImageVersions; private: void checkMissingAndNotify(ImageRequestor&, const ImageRequestPair&); void notify(ImageRequestor&, const ImageRequestPair&) const; + void removePattern(const std::string&); bool loaded = false; @@ -71,6 +73,7 @@ private: unsigned int callbacksRemaining; }; std::map missingImageRequestors; + std::map> requestedImages; ImageMap images; ImageManagerObserver* observer = nullptr; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 4ba1fc6bbc..9f376e7cf5 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -685,6 +685,9 @@ void Renderer::Impl::reduceMemoryUse() { } backend.getContext().performCleanup(); observer->onInvalidate(); + if (imageManager) { + imageManager->reduceMemoryUse(); + } } void Renderer::Impl::dumDebugLogs() { -- cgit v1.2.1