summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mbgl/renderer/image_atlas.cpp41
-rw-r--r--src/mbgl/renderer/image_atlas.hpp14
-rw-r--r--src/mbgl/renderer/render_orchestrator.cpp2
-rw-r--r--src/mbgl/renderer/render_source.hpp2
-rw-r--r--src/mbgl/renderer/render_tile.cpp2
-rw-r--r--src/mbgl/tile/geometry_tile.cpp26
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) {