diff options
-rw-r--r-- | src/mbgl/renderer/image_atlas.cpp | 41 | ||||
-rw-r--r-- | src/mbgl/renderer/image_atlas.hpp | 14 | ||||
-rw-r--r-- | src/mbgl/renderer/render_orchestrator.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/render_source.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/render_tile.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.cpp | 26 |
6 files changed, 58 insertions, 29 deletions
diff --git a/src/mbgl/renderer/image_atlas.cpp b/src/mbgl/renderer/image_atlas.cpp index da7f5a30be..c9cedb3386 100644 --- a/src/mbgl/renderer/image_atlas.cpp +++ b/src/mbgl/renderer/image_atlas.cpp @@ -1,6 +1,4 @@ #include <mbgl/renderer/image_atlas.hpp> -#include <mbgl/gfx/upload_pass.hpp> -#include <mbgl/gfx/context.hpp> #include <mbgl/renderer/image_manager.hpp> #include <mapbox/shelf-pack.hpp> @@ -53,27 +51,36 @@ const mapbox::Bin& _packImage(mapbox::ShelfPack& pack, const style::Image::Impl& return bin; } -void ImageAtlas::patchUpdatedImages(gfx::UploadPass& uploadPass, gfx::Texture& atlasTexture, const ImageManager& imageManager) { +namespace { + +void populateImagePatches( + ImagePositions& imagePositions, + const ImageManager& imageManager, + std::vector<ImagePatch>& /*out*/ patches) { for (auto& updatedImageVersion : imageManager.updatedImageVersions) { - auto iconPosition = iconPositions.find(updatedImageVersion.first); - if (iconPosition != iconPositions.end()) { - patchUpdatedImage(uploadPass, atlasTexture, iconPosition->second, imageManager, updatedImageVersion.first, updatedImageVersion.second); - } - auto patternPosition = patternPositions.find(updatedImageVersion.first); - if (patternPosition != patternPositions.end()) { - patchUpdatedImage(uploadPass, atlasTexture, patternPosition->second, imageManager, updatedImageVersion.first, updatedImageVersion.second); + const std::string& name = updatedImageVersion.first; + const uint32_t version = updatedImageVersion.second; + auto it = imagePositions.find(updatedImageVersion.first); + if (it != imagePositions.end()) { + auto& position = it->second; + if (position.version == version) continue; + + auto updatedImage = imageManager.getSharedImage(name); + if (updatedImage == nullptr) continue; + + patches.emplace_back(*updatedImage, position.textureRect); + position.version = version; } } } -void ImageAtlas::patchUpdatedImage(gfx::UploadPass& uploadPass, gfx::Texture& atlasTexture, ImagePosition& position, const ImageManager& imageManager, const std::string& name, uint16_t version) { - if (position.version == version) return; - - auto updatedImage = imageManager.getImage(name); - if (updatedImage == nullptr) return; +} // namespace - uploadPass.updateTextureSub(atlasTexture, updatedImage->image, position.textureRect.x, position.textureRect.y); - position.version = version; +std::vector<ImagePatch> ImageAtlas::getImagePatchesAndUpdateVersions(const ImageManager& imageManager) { + std::vector<ImagePatch> imagePatches; + populateImagePatches(iconPositions, imageManager, imagePatches); + populateImagePatches(patternPositions, imageManager, imagePatches); + return imagePatches; } ImageAtlas makeImageAtlas(const ImageMap& icons, const ImageMap& patterns, const std::unordered_map<std::string, uint32_t>& versionMap) { diff --git a/src/mbgl/renderer/image_atlas.hpp b/src/mbgl/renderer/image_atlas.hpp index b59153c4a6..56d7406a0a 100644 --- a/src/mbgl/renderer/image_atlas.hpp +++ b/src/mbgl/renderer/image_atlas.hpp @@ -54,15 +54,23 @@ public: using ImagePositions = std::map<std::string, ImagePosition>; +class ImagePatch { +public: + ImagePatch(Immutable<style::Image::Impl> image_, + const Rect<uint16_t>& textureRect_) + : image(std::move(image_)) + , textureRect(textureRect_) {} + Immutable<style::Image::Impl> image; + Rect<uint16_t> textureRect; +}; + class ImageAtlas { public: PremultipliedImage image; ImagePositions iconPositions; ImagePositions patternPositions; - void patchUpdatedImages(gfx::UploadPass&, gfx::Texture&, const ImageManager&); -private: - void patchUpdatedImage(gfx::UploadPass&, gfx::Texture&, ImagePosition& position, const ImageManager& imageManager, const std::string& name, uint16_t version); + std::vector<ImagePatch> getImagePatchesAndUpdateVersions(const ImageManager&); }; ImageAtlas makeImageAtlas(const ImageMap&, const ImageMap&, const std::unordered_map<std::string, uint32_t>& versionMap); diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index acc50318d6..b980efcff8 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -343,7 +343,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar // Update all matrices and generate data that we should upload to the GPU. for (const auto& entry : renderSources) { if (entry.second->isEnabled()) { - entry.second->prepare({renderTreeParameters->transformParams, updateParameters.debugOptions}); + entry.second->prepare({renderTreeParameters->transformParams, updateParameters.debugOptions, *imageManager}); sourceRenderItems.emplace_back(*entry.second); } } diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index f0da360dd0..57c5b6fb7f 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -28,6 +28,7 @@ class RenderSourceObserver; class TileParameters; class CollisionIndex; class TransformParameters; +class ImageManager; namespace gfx { class UploadPass; @@ -37,6 +38,7 @@ class SourcePrepareParameters { public: const TransformParameters& transform; const MapDebugOptions& debugOptions; + const ImageManager& imageManager; }; class RenderSource : protected TileObserver { diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index a0230a6511..3c61e7d7a3 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -103,6 +103,8 @@ void RenderTile::upload(gfx::UploadPass& uploadPass) { void RenderTile::prepare(const SourcePrepareParameters& parameters) { renderData = tile.createRenderData(); assert(renderData); + renderData->prepare(parameters); + needsRendering = tile.usedByRenderedLayers; if (parameters.debugOptions != MapDebugOptions::NoDebug && diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 0b9ba263f5..e87d21503a 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -6,6 +6,7 @@ #include <mbgl/style/layer_impl.hpp> #include <mbgl/style/layers/background_layer.hpp> #include <mbgl/style/layers/custom_layer.hpp> +#include <mbgl/renderer/render_source.hpp> #include <mbgl/renderer/tile_parameters.hpp> #include <mbgl/renderer/layers/render_background_layer.hpp> #include <mbgl/renderer/layers/render_custom_layer.hpp> @@ -20,6 +21,8 @@ #include <mbgl/actor/scheduler.hpp> #include <mbgl/renderer/tile_render_data.hpp> +#include <mbgl/gfx/upload_pass.hpp> + namespace mbgl { LayerRenderData* GeometryTile::LayoutResult::getLayerRenderData(const style::Layer::Impl& layerImpl) { @@ -39,11 +42,9 @@ class GeometryTileRenderData final : public TileRenderData { public: GeometryTileRenderData( std::shared_ptr<GeometryTile::LayoutResult> layoutResult_, - std::shared_ptr<TileAtlasTextures> atlasTextures_, - ImageManager& imageManager_) + std::shared_ptr<TileAtlasTextures> atlasTextures_) : TileRenderData(std::move(atlasTextures_)) - , layoutResult(std::move(layoutResult_)) - , imageManager(imageManager_) { + , layoutResult(std::move(layoutResult_)) { } private: @@ -52,9 +53,10 @@ private: const LayerRenderData* getLayerRenderData(const style::Layer::Impl&) const override; Bucket* getBucket(const style::Layer::Impl&) const override; void upload(gfx::UploadPass&) override; + void prepare(const SourcePrepareParameters&) override; std::shared_ptr<GeometryTile::LayoutResult> layoutResult; - ImageManager& imageManager; + std::vector<ImagePatch> imagePatches; }; using namespace style; @@ -95,11 +97,19 @@ void GeometryTileRenderData::upload(gfx::UploadPass& uploadPass) { layoutResult->iconAtlas.image = {}; } - if (atlasTextures->icon) { - layoutResult->iconAtlas.patchUpdatedImages(uploadPass, *atlasTextures->icon, imageManager); + if (atlasTextures->icon && !imagePatches.empty()) { + for (const auto& imagePatch : imagePatches) { // patch updated images. + uploadPass.updateTextureSub(*atlasTextures->icon, imagePatch.image->image, imagePatch.textureRect.x, imagePatch.textureRect.y); + } + imagePatches.clear(); } } +void GeometryTileRenderData::prepare(const SourcePrepareParameters& parameters) { + if (!layoutResult) return; + imagePatches = layoutResult->iconAtlas.getImagePatchesAndUpdateVersions(parameters.imageManager); +} + Bucket* GeometryTileRenderData::getBucket(const Layer::Impl& layer) const { const LayerRenderData* data = getLayerRenderData(layer); return data ? data->bucket.get() : nullptr; @@ -176,7 +186,7 @@ void GeometryTile::setData(std::unique_ptr<const GeometryTileData> data_) { } std::unique_ptr<TileRenderData> GeometryTile::createRenderData() { - return std::make_unique<GeometryTileRenderData>(layoutResult, atlasTextures, imageManager); + return std::make_unique<GeometryTileRenderData>(layoutResult, atlasTextures); } void GeometryTile::setLayers(const std::vector<Immutable<LayerProperties>>& layers) { |