summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2017-06-07 12:45:35 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2017-06-13 10:18:43 -0700
commit0b687312071305c050d97e04fef1c80193f443c5 (patch)
tree64c20efaa17fefef9f902811a000fd6e425c849b /src
parent92252849c1a2ddf7887d1908841fa3c90dd59766 (diff)
downloadqtlocation-mapboxgl-0b687312071305c050d97e04fef1c80193f443c5.tar.gz
[core] Per-bucket icon atlases
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/layout/symbol_layout.cpp22
-rw-r--r--src/mbgl/layout/symbol_layout.hpp5
-rw-r--r--src/mbgl/programs/fill_extrusion_program.cpp6
-rw-r--r--src/mbgl/programs/fill_extrusion_program.hpp6
-rw-r--r--src/mbgl/programs/fill_program.cpp6
-rw-r--r--src/mbgl/programs/fill_program.hpp6
-rw-r--r--src/mbgl/programs/line_program.cpp6
-rw-r--r--src/mbgl/programs/line_program.hpp6
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.cpp1
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp2
-rw-r--r--src/mbgl/renderer/image_atlas.cpp68
-rw-r--r--src/mbgl/renderer/image_atlas.hpp51
-rw-r--r--src/mbgl/renderer/image_manager.cpp173
-rw-r--r--src/mbgl/renderer/image_manager.hpp94
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp4
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.hpp4
-rw-r--r--src/mbgl/renderer/painter.cpp7
-rw-r--r--src/mbgl/renderer/painter.hpp4
-rw-r--r--src/mbgl/renderer/painters/painter_background.cpp10
-rw-r--r--src/mbgl/renderer/painters/painter_fill.cpp10
-rw-r--r--src/mbgl/renderer/painters/painter_fill_extrusion.cpp12
-rw-r--r--src/mbgl/renderer/painters/painter_line.cpp10
-rw-r--r--src/mbgl/renderer/painters/painter_symbol.cpp8
-rw-r--r--src/mbgl/renderer/render_style.cpp23
-rw-r--r--src/mbgl/renderer/render_style.hpp4
-rw-r--r--src/mbgl/renderer/tile_parameters.hpp4
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp256
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp137
-rw-r--r--src/mbgl/sprite/sprite_loader.cpp4
-rw-r--r--src/mbgl/style/image_impl.hpp8
-rw-r--r--src/mbgl/style/style.cpp9
-rw-r--r--src/mbgl/text/quads.cpp2
-rw-r--r--src/mbgl/text/shaping.cpp2
-rw-r--r--src/mbgl/text/shaping.hpp13
-rw-r--r--src/mbgl/tile/geometry_tile.cpp12
-rw-r--r--src/mbgl/tile/geometry_tile.hpp10
-rw-r--r--src/mbgl/tile/geometry_tile_worker.cpp25
-rw-r--r--src/mbgl/tile/geometry_tile_worker.hpp10
38 files changed, 519 insertions, 521 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 6d769e43c4..b64fc4f66e 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -5,8 +5,8 @@
#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
+#include <mbgl/renderer/image_atlas.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/text/get_anchors.hpp>
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/text/shaping.hpp>
@@ -41,7 +41,7 @@ static bool has(const style::SymbolLayoutProperties::PossiblyEvaluated& layout)
SymbolLayout::SymbolLayout(const BucketParameters& parameters,
const std::vector<const RenderLayer*>& layers,
const GeometryTileLayer& sourceLayer,
- IconDependencies& iconDependencies,
+ ImageDependencies& imageDependencies,
GlyphDependencies& glyphDependencies)
: sourceLayerName(sourceLayer.getName()),
bucketName(layers.at(0)->getID()),
@@ -158,7 +158,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
icon = util::replaceTokens(icon, getValue);
}
ft.icon = icon;
- iconDependencies.insert(*ft.icon);
+ imageDependencies.insert(*ft.icon);
}
if (ft.text || ft.icon) {
@@ -175,7 +175,7 @@ bool SymbolLayout::hasSymbolInstances() const {
return !symbolInstances.empty();
}
-void SymbolLayout::prepare(const GlyphMap& glyphs, const IconMap& icons) {
+void SymbolLayout::prepare(const GlyphMap& glyphs, const ImageMap& images) {
float horizontalAlign = 0.5;
float verticalAlign = 0.5;
@@ -225,6 +225,8 @@ void SymbolLayout::prepare(const GlyphMap& glyphs, const IconMap& icons) {
glyphAtlas = makeGlyphAtlas(glyphPositionsIt->second);
}
+ imageAtlas = makeImageAtlas(images);
+
for (auto it = features.begin(); it != features.end(); ++it) {
auto& feature = *it;
if (feature.geometry.empty()) continue;
@@ -266,15 +268,16 @@ void SymbolLayout::prepare(const GlyphMap& glyphs, const IconMap& icons) {
// if feature has icon, get sprite atlas position
if (feature.icon) {
- auto image = icons.find(*feature.icon);
- if (image != icons.end()) {
- shapedIcon = PositionedIcon::shapeIcon(image->second,
+ auto image = images.find(*feature.icon);
+ if (image != images.end()) {
+ shapedIcon = PositionedIcon::shapeIcon(
+ imageAtlas.positions.at(*feature.icon),
layout.evaluate<IconOffset>(zoom, feature),
layout.evaluate<IconRotate>(zoom, feature) * util::DEG2RAD);
- if (image->second.sdf) {
+ if (image->second->sdf) {
sdfIcons = true;
}
- if (image->second.pixelRatio != pixelRatio) {
+ if (image->second->pixelRatio != pixelRatio) {
iconsNeedLinear = true;
} else if (layout.get<IconRotate>().constantOr(1) != 0) {
iconsNeedLinear = true;
@@ -428,6 +431,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear);
bucket->text.atlasImage = glyphAtlas.image.clone();
+ bucket->icon.atlasImage = imageAtlas.image.clone();
// Calculate which labels can be shown and when they can be shown and
// create the bufers used for rendering.
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index e947ee354b..7d6f2319cd 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -30,10 +30,10 @@ public:
SymbolLayout(const BucketParameters&,
const std::vector<const RenderLayer*>&,
const GeometryTileLayer&,
- IconDependencies&,
+ ImageDependencies&,
GlyphDependencies&);
- void prepare(const GlyphMap& glyphs, const IconMap& icons);
+ void prepare(const GlyphMap& glyphs, const ImageMap& icons);
std::unique_ptr<SymbolBucket> place(CollisionTile&);
@@ -94,6 +94,7 @@ private:
std::vector<SymbolFeature> features;
GlyphAtlas glyphAtlas;
+ ImageAtlas imageAtlas;
BiDi bidi; // Consider moving this up to geometry tile worker to reduce reinstantiation costs; use of BiDi/ubiditransform object must be constrained to one thread
};
diff --git a/src/mbgl/programs/fill_extrusion_program.cpp b/src/mbgl/programs/fill_extrusion_program.cpp
index 3f85d83788..aaf192a843 100644
--- a/src/mbgl/programs/fill_extrusion_program.cpp
+++ b/src/mbgl/programs/fill_extrusion_program.cpp
@@ -1,5 +1,5 @@
#include <mbgl/programs/fill_extrusion_program.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/renderer/image_atlas.hpp>
#include <mbgl/renderer/cross_faded_property_evaluator.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/map/transform_state.hpp>
@@ -46,8 +46,8 @@ FillExtrusionUniforms::values(mat4 matrix,
FillExtrusionPatternUniforms::Values
FillExtrusionPatternUniforms::values(mat4 matrix,
Size atlasSize,
- const SpriteAtlasElement& a,
- const SpriteAtlasElement& b,
+ const ImagePosition& a,
+ const ImagePosition& b,
const Faded<std::string>& fading,
const UnwrappedTileID& tileID,
const TransformState& state,
diff --git a/src/mbgl/programs/fill_extrusion_program.hpp b/src/mbgl/programs/fill_extrusion_program.hpp
index 7f1c76a6ad..820670068e 100644
--- a/src/mbgl/programs/fill_extrusion_program.hpp
+++ b/src/mbgl/programs/fill_extrusion_program.hpp
@@ -16,7 +16,7 @@
namespace mbgl {
-class SpriteAtlasElement;
+class ImagePosition;
class UnwrappedTileID;
class TransformState;
template <class> class Faded;
@@ -68,8 +68,8 @@ struct FillExtrusionPatternUniforms : gl::Uniforms<
{
static Values values(mat4,
Size atlasSize,
- const SpriteAtlasElement&,
- const SpriteAtlasElement&,
+ const ImagePosition&,
+ const ImagePosition&,
const Faded<std::string>&,
const UnwrappedTileID&,
const TransformState&,
diff --git a/src/mbgl/programs/fill_program.cpp b/src/mbgl/programs/fill_program.cpp
index 6c19e503ce..46dc830102 100644
--- a/src/mbgl/programs/fill_program.cpp
+++ b/src/mbgl/programs/fill_program.cpp
@@ -1,5 +1,5 @@
#include <mbgl/programs/fill_program.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/renderer/image_atlas.hpp>
#include <mbgl/renderer/cross_faded_property_evaluator.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/map/transform_state.hpp>
@@ -14,8 +14,8 @@ FillPatternUniforms::Values
FillPatternUniforms::values(mat4 matrix,
Size framebufferSize,
Size atlasSize,
- const SpriteAtlasElement& a,
- const SpriteAtlasElement& b,
+ const ImagePosition& a,
+ const ImagePosition& b,
const Faded<std::string>& fading,
const UnwrappedTileID& tileID,
const TransformState& state)
diff --git a/src/mbgl/programs/fill_program.hpp b/src/mbgl/programs/fill_program.hpp
index 093485fc7f..2dfeea3279 100644
--- a/src/mbgl/programs/fill_program.hpp
+++ b/src/mbgl/programs/fill_program.hpp
@@ -16,7 +16,7 @@
namespace mbgl {
-class SpriteAtlasElement;
+class ImagePosition;
class UnwrappedTileID;
class TransformState;
template <class> class Faded;
@@ -51,8 +51,8 @@ struct FillPatternUniforms : gl::Uniforms<
static Values values(mat4 matrix,
Size framebufferSize,
Size atlasSize,
- const SpriteAtlasElement&,
- const SpriteAtlasElement&,
+ const ImagePosition&,
+ const ImagePosition&,
const Faded<std::string>&,
const UnwrappedTileID&,
const TransformState&);
diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp
index 2c65cb74ed..86645588ca 100644
--- a/src/mbgl/programs/line_program.cpp
+++ b/src/mbgl/programs/line_program.cpp
@@ -1,9 +1,9 @@
#include <mbgl/programs/line_program.hpp>
#include <mbgl/style/layers/line_layer_properties.hpp>
#include <mbgl/renderer/render_tile.hpp>
+#include <mbgl/renderer/image_atlas.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/util/mat2.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/geometry/line_atlas.hpp>
namespace mbgl {
@@ -89,8 +89,8 @@ LinePatternProgram::uniformValues(const LinePaintProperties::PossiblyEvaluated&
const TransformState& state,
const std::array<float, 2>& pixelsToGLUnits,
const Size atlasSize,
- const SpriteAtlasElement& posA,
- const SpriteAtlasElement& posB) {
+ const ImagePosition& posA,
+ const ImagePosition& posB) {
std::array<float, 2> sizeA {{
tile.id.pixelsToTileUnits(posA.displaySize()[0] * properties.get<LinePattern>().fromScale, state.getIntegerZoom()),
posA.displaySize()[1]
diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp
index 6f6ceeb32b..fadd351026 100644
--- a/src/mbgl/programs/line_program.hpp
+++ b/src/mbgl/programs/line_program.hpp
@@ -16,7 +16,7 @@ namespace mbgl {
class RenderTile;
class TransformState;
class LinePatternPos;
-class SpriteAtlasElement;
+class ImagePosition;
namespace uniforms {
MBGL_DEFINE_UNIFORM_SCALAR(float, u_ratio);
@@ -125,8 +125,8 @@ public:
const TransformState&,
const std::array<float, 2>& pixelsToGLUnits,
Size atlasSize,
- const SpriteAtlasElement& posA,
- const SpriteAtlasElement& posB);
+ const ImagePosition& posA,
+ const ImagePosition& posB);
};
class LineSDFProgram : public Program<
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp
index fceffaa5f4..21d463b1fc 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.cpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp
@@ -46,6 +46,7 @@ void SymbolBucket::upload(gl::Context& context) {
if (hasIconData()) {
icon.vertexBuffer = context.createVertexBuffer(std::move(icon.vertices));
icon.indexBuffer = context.createIndexBuffer(std::move(icon.triangles));
+ icon.atlasTexture = context.createTexture(std::move(icon.atlasImage), 0);
iconSizeBinder->upload(context);
}
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index 76b3467a9a..bc9d564aac 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -59,9 +59,11 @@ public:
gl::VertexVector<SymbolLayoutVertex> vertices;
gl::IndexVector<gl::Triangles> triangles;
gl::SegmentVector<SymbolIconAttributes> segments;
+ PremultipliedImage atlasImage;
optional<gl::VertexBuffer<SymbolLayoutVertex>> vertexBuffer;
optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
+ optional<gl::Texture> atlasTexture;
} icon;
struct CollisionBoxBuffer {
diff --git a/src/mbgl/renderer/image_atlas.cpp b/src/mbgl/renderer/image_atlas.cpp
new file mode 100644
index 0000000000..b53c2162ea
--- /dev/null
+++ b/src/mbgl/renderer/image_atlas.cpp
@@ -0,0 +1,68 @@
+#include <mbgl/renderer/image_atlas.hpp>
+
+#include <mapbox/shelf-pack.hpp>
+
+namespace mbgl {
+
+static constexpr uint32_t padding = 1;
+
+ImagePosition::ImagePosition(const mapbox::Bin& bin, const style::Image::Impl& image)
+ : pixelRatio(image.pixelRatio),
+ textureRect(
+ bin.x + padding,
+ bin.y + padding,
+ bin.w - padding * 2,
+ bin.h - padding * 2
+ ) {
+}
+
+ImageAtlas makeImageAtlas(const ImageMap& images) {
+ ImageAtlas result;
+
+ mapbox::ShelfPack::ShelfPackOptions options;
+ options.autoResize = true;
+ mapbox::ShelfPack pack(0, 0, options);
+
+ std::vector<const style::Image::Impl*> pointers;
+ pointers.reserve(images.size());
+
+ std::vector<mapbox::Bin> bins;
+ bins.reserve(images.size());
+
+ for (const auto& entry : images) {
+ const style::Image::Impl& image = *entry.second;
+ pointers.emplace_back(&image);
+ bins.emplace_back(pointers.size() - 1,
+ image.image.size.width + 2 * padding,
+ image.image.size.height + 2 * padding);
+ }
+
+ mapbox::ShelfPack::PackOptions packOptions;
+ packOptions.inPlace = true;
+ pack.pack(bins, packOptions);
+
+ result.image = PremultipliedImage({
+ static_cast<uint32_t>(pack.width()),
+ static_cast<uint32_t>(pack.height())
+ });
+
+ for (const auto& bin : bins) {
+ const style::Image::Impl& image = *pointers.at(bin.id);
+
+ PremultipliedImage::copy(image.image,
+ result.image,
+ { 0, 0 },
+ {
+ bin.x + padding,
+ bin.y + padding
+ },
+ image.image.size);
+
+ result.positions.emplace(image.id,
+ ImagePosition { bin, image });
+ }
+
+ return result;
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/image_atlas.hpp b/src/mbgl/renderer/image_atlas.hpp
new file mode 100644
index 0000000000..b3cc166eff
--- /dev/null
+++ b/src/mbgl/renderer/image_atlas.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <mbgl/style/image_impl.hpp>
+#include <mbgl/util/rect.hpp>
+
+#include <mapbox/shelf-pack.hpp>
+
+#include <array>
+
+namespace mbgl {
+
+class ImagePosition {
+public:
+ ImagePosition(const mapbox::Bin&, const style::Image::Impl&);
+
+ float pixelRatio;
+ Rect<uint16_t> textureRect;
+
+ std::array<uint16_t, 2> tl() const {
+ return {{
+ textureRect.x,
+ textureRect.y
+ }};
+ }
+
+ std::array<uint16_t, 2> br() const {
+ return {{
+ static_cast<uint16_t>(textureRect.x + textureRect.w),
+ static_cast<uint16_t>(textureRect.y + textureRect.h)
+ }};
+ }
+
+ std::array<float, 2> displaySize() const {
+ return {{
+ textureRect.w / pixelRatio,
+ textureRect.h / pixelRatio,
+ }};
+ }
+};
+
+using ImagePositions = std::map<std::string, ImagePosition>;
+
+class ImageAtlas {
+public:
+ PremultipliedImage image;
+ ImagePositions positions;
+};
+
+ImageAtlas makeImageAtlas(const ImageMap&);
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp
new file mode 100644
index 0000000000..be47004b69
--- /dev/null
+++ b/src/mbgl/renderer/image_manager.cpp
@@ -0,0 +1,173 @@
+#include <mbgl/renderer/image_manager.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/gl/context.hpp>
+
+namespace mbgl {
+
+void ImageManager::onSpriteLoaded() {
+ loaded = true;
+ for (const auto& entry : requestors) {
+ notify(*entry.first, entry.second);
+ }
+ requestors.clear();
+}
+
+void ImageManager::addImage(Immutable<style::Image::Impl> image_) {
+ assert(images.find(image_->id) == images.end());
+ images.emplace(image_->id, std::move(image_));
+}
+
+void ImageManager::updateImage(Immutable<style::Image::Impl> image_) {
+ removeImage(image_->id);
+ addImage(std::move(image_));
+}
+
+void ImageManager::removeImage(const std::string& id) {
+ assert(images.find(id) != images.end());
+ images.erase(id);
+
+ auto it = patterns.find(id);
+ if (it != patterns.end()) {
+ shelfPack.unref(*it->second.bin);
+ patterns.erase(it);
+ }
+}
+
+const style::Image::Impl* ImageManager::getImage(const std::string& id) const {
+ const auto it = images.find(id);
+ if (it != images.end()) {
+ return it->second.get();
+ }
+ return nullptr;
+}
+
+void ImageManager::getImages(ImageRequestor& requestor, ImageDependencies dependencies) {
+ // If the sprite has been loaded, or if all the icon dependencies are already present
+ // (i.e. if they've been addeded via runtime styling), then notify the requestor immediately.
+ // Otherwise, delay notification until the sprite is loaded. At that point, if any of the
+ // dependencies are still unavailable, we'll just assume they are permanently missing.
+ bool hasAllDependencies = true;
+ if (!isLoaded()) {
+ for (const auto& dependency : dependencies) {
+ if (images.find(dependency) == images.end()) {
+ hasAllDependencies = false;
+ }
+ }
+ }
+ if (isLoaded() || hasAllDependencies) {
+ notify(requestor, dependencies);
+ } else {
+ requestors.emplace(&requestor, std::move(dependencies));
+ }
+}
+
+void ImageManager::removeRequestor(ImageRequestor& requestor) {
+ requestors.erase(&requestor);
+}
+
+void ImageManager::notify(ImageRequestor& requestor, const ImageDependencies& dependencies) const {
+ ImageMap response;
+
+ for (const auto& dependency : dependencies) {
+ auto it = images.find(dependency);
+ if (it != images.end()) {
+ response.emplace(*it);
+ }
+ }
+
+ requestor.onImagesAvailable(response);
+}
+
+void ImageManager::dumpDebugLogs() const {
+ Log::Info(Event::General, "ImageManager::loaded: %d", loaded);
+}
+
+// When copied into the atlas texture, image data is padded by one pixel on each side. Icon
+// images are padded with fully transparent pixels, while pattern images are padded with a
+// copy of the image data wrapped from the opposite side. In both cases, this ensures the
+// correct behavior of GL_LINEAR texture sampling mode.
+static constexpr uint16_t padding = 1;
+
+static mapbox::ShelfPack::ShelfPackOptions shelfPackOptions() {
+ mapbox::ShelfPack::ShelfPackOptions options;
+ options.autoResize = true;
+ return options;
+}
+
+ImageManager::ImageManager()
+ : shelfPack(64, 64, shelfPackOptions()) {
+}
+
+ImageManager::~ImageManager() = default;
+
+optional<ImagePosition> ImageManager::getPattern(const std::string& id) {
+ auto it = patterns.find(id);
+ if (it != patterns.end()) {
+ return it->second.position;
+ }
+
+ const style::Image::Impl* image = getImage(id);
+ if (!image) {
+ return {};
+ }
+
+ const uint16_t width = image->image.size.width + padding * 2;
+ const uint16_t height = image->image.size.height + padding * 2;
+
+ mapbox::Bin* bin = shelfPack.packOne(-1, width, height);
+ if (!bin) {
+ return {};
+ }
+
+ if (!atlasImage.valid()) {
+ atlasImage = PremultipliedImage(getPixelSize());
+ atlasImage.fill(0);
+ } else if (atlasImage.size != getPixelSize()) {
+ PremultipliedImage newImage(getPixelSize());
+ PremultipliedImage::copy(atlasImage, newImage, { 0, 0 }, { 0, 0 }, atlasImage.size);
+ atlasImage = std::move(newImage);
+ }
+
+ const PremultipliedImage& src = image->image;
+
+ const uint32_t x = bin->x + padding;
+ const uint32_t y = bin->y + padding;
+ const uint32_t w = src.size.width;
+ const uint32_t h = src.size.height;
+
+ PremultipliedImage::copy(src, atlasImage, { 0, 0 }, { x, y }, { w, h });
+
+ // Add 1 pixel wrapped padding on each side of the image.
+ PremultipliedImage::copy(src, atlasImage, { 0, h - 1 }, { x, y - 1 }, { w, 1 }); // T
+ PremultipliedImage::copy(src, atlasImage, { 0, 0 }, { x, y + h }, { w, 1 }); // B
+ PremultipliedImage::copy(src, atlasImage, { w - 1, 0 }, { x - 1, y }, { 1, h }); // L
+ PremultipliedImage::copy(src, atlasImage, { 0, 0 }, { x + w, y }, { 1, h }); // R
+
+ dirty = true;
+
+ return patterns.emplace(id, Pattern { bin, { *bin, *image } }).first->second.position;
+}
+
+Size ImageManager::getPixelSize() const {
+ return Size {
+ static_cast<uint32_t>(shelfPack.width()),
+ static_cast<uint32_t>(shelfPack.height())
+ };
+}
+
+void ImageManager::upload(gl::Context& context, gl::TextureUnit unit) {
+ if (!atlasTexture) {
+ atlasTexture = context.createTexture(atlasImage, unit);
+ } else if (dirty) {
+ context.updateTexture(*atlasTexture, atlasImage, unit);
+ }
+
+ dirty = false;
+}
+
+void ImageManager::bind(gl::Context& context, gl::TextureUnit unit) {
+ upload(context, unit);
+ context.bindTexture(*atlasTexture, unit, gl::TextureFilter::Linear);
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/image_manager.hpp b/src/mbgl/renderer/image_manager.hpp
new file mode 100644
index 0000000000..9a9a4ce997
--- /dev/null
+++ b/src/mbgl/renderer/image_manager.hpp
@@ -0,0 +1,94 @@
+#pragma once
+
+#include <mbgl/style/image_impl.hpp>
+#include <mbgl/renderer/image_atlas.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/immutable.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/gl/texture.hpp>
+
+#include <mapbox/shelf-pack.hpp>
+
+#include <set>
+#include <string>
+
+namespace mbgl {
+
+namespace gl {
+class Context;
+} // namespace gl
+
+class ImageRequestor {
+public:
+ virtual ~ImageRequestor() = default;
+ virtual void onImagesAvailable(ImageMap) = 0;
+};
+
+/*
+ ImageManager does two things:
+
+ 1. Tracks requests for icon images from tile workers and sends responses when the requests are fulfilled.
+ 2. Builds a texture atlas for pattern images.
+
+ These are disparate responsibilities and should eventually be handled by different classes. When we implement
+ data-driven support for `*-pattern`, we'll likely use per-bucket pattern atlases, and that would be a good time
+ to refactor this.
+*/
+class ImageManager : public util::noncopyable {
+public:
+ ImageManager();
+ ~ImageManager();
+
+ void onSpriteLoaded();
+
+ bool isLoaded() const {
+ return loaded;
+ }
+
+ void dumpDebugLogs() const;
+
+ const style::Image::Impl* getImage(const std::string&) const;
+
+ void addImage(Immutable<style::Image::Impl>);
+ void updateImage(Immutable<style::Image::Impl>);
+ void removeImage(const std::string&);
+
+ void getImages(ImageRequestor&, ImageDependencies);
+ void removeRequestor(ImageRequestor&);
+
+private:
+ void notify(ImageRequestor&, const ImageDependencies&) const;
+
+ bool loaded = false;
+
+ std::unordered_map<ImageRequestor*, ImageDependencies> requestors;
+ ImageMap images;
+
+// Pattern stuff
+public:
+ optional<ImagePosition> getPattern(const std::string& name);
+
+ void bind(gl::Context&, gl::TextureUnit unit);
+ void upload(gl::Context&, gl::TextureUnit unit);
+
+ Size getPixelSize() const;
+
+ // Only for use in tests.
+ const PremultipliedImage& getAtlasImage() const {
+ return atlasImage;
+ }
+
+private:
+ struct Pattern {
+ mapbox::Bin* bin;
+ ImagePosition position;
+ };
+
+ mapbox::ShelfPack shelfPack;
+ std::unordered_map<std::string, Pattern> patterns;
+ PremultipliedImage atlasImage;
+ mbgl::optional<gl::Texture> atlasTexture;
+ bool dirty = true;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp
index 0054d9f874..395cf283d5 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.cpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp
@@ -25,11 +25,11 @@ std::unique_ptr<SymbolLayout> RenderSymbolLayer::createLayout(const BucketParame
const std::vector<const RenderLayer*>& group,
const GeometryTileLayer& layer,
GlyphDependencies& glyphDependencies,
- IconDependencies& iconDependencies) const {
+ ImageDependencies& imageDependencies) const {
return std::make_unique<SymbolLayout>(parameters,
group,
layer,
- iconDependencies,
+ imageDependencies,
glyphDependencies);
}
diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp
index 42205496d9..8c7d43bf3a 100644
--- a/src/mbgl/renderer/layers/render_symbol_layer.hpp
+++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp
@@ -2,7 +2,7 @@
#include <mbgl/text/glyph.hpp>
#include <mbgl/renderer/render_layer.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/style/image_impl.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
@@ -76,7 +76,7 @@ public:
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
std::unique_ptr<SymbolLayout> createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&,
- const GeometryTileLayer&, GlyphDependencies&, IconDependencies&) const;
+ const GeometryTileLayer&, GlyphDependencies&, ImageDependencies&) const;
// Paint properties
style::SymbolPaintProperties::Unevaluated unevaluated;
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 6f0ddf8467..673bf66901 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -21,7 +21,7 @@
#include <mbgl/style/layers/custom_layer_impl.hpp>
#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/geometry/line_atlas.hpp>
#include <mbgl/programs/program_parameters.hpp>
@@ -137,7 +137,7 @@ void Painter::render(RenderStyle& style, const FrameData& frame_, View& view) {
view
};
- spriteAtlas = style.spriteAtlas.get();
+ imageManager = style.imageManager.get();
lineAtlas = style.lineAtlas.get();
evaluatedLight = style.getRenderLight().getEvaluated();
@@ -167,8 +167,7 @@ void Painter::render(RenderStyle& style, const FrameData& frame_, View& view) {
{
MBGL_DEBUG_GROUP(context, "upload");
- spriteAtlas->upload(context, 0);
-
+ imageManager->upload(context, 0);
lineAtlas->upload(context, 0);
frameHistory.upload(context, 0);
}
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index c8b61c6bf8..f2d06a0e20 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -32,7 +32,7 @@ namespace mbgl {
class RenderStyle;
class RenderTile;
-class SpriteAtlas;
+class ImageManager;
class View;
class LineAtlas;
struct FrameData;
@@ -151,7 +151,7 @@ public:
float depthRangeSize;
const float depthEpsilon = 1.0f / (1 << 16);
- SpriteAtlas* spriteAtlas = nullptr;
+ ImageManager* imageManager = nullptr;
LineAtlas* lineAtlas = nullptr;
optional<OffscreenTexture> extrusionTexture;
diff --git a/src/mbgl/renderer/painters/painter_background.cpp b/src/mbgl/renderer/painters/painter_background.cpp
index 9cbc3d516c..7ebb735df8 100644
--- a/src/mbgl/renderer/painters/painter_background.cpp
+++ b/src/mbgl/renderer/painters/painter_background.cpp
@@ -1,10 +1,10 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/layers/render_background_layer.hpp>
+#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/fill_program.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/util/tile_cover.hpp>
namespace mbgl {
@@ -24,13 +24,13 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou
const FillProgram::PaintPropertyBinders paintAttibuteData(properties, 0);
if (!background.get<BackgroundPattern>().to.empty()) {
- optional<SpriteAtlasElement> imagePosA = spriteAtlas->getPattern(background.get<BackgroundPattern>().from);
- optional<SpriteAtlasElement> imagePosB = spriteAtlas->getPattern(background.get<BackgroundPattern>().to);
+ optional<ImagePosition> imagePosA = imageManager->getPattern(background.get<BackgroundPattern>().from);
+ optional<ImagePosition> imagePosB = imageManager->getPattern(background.get<BackgroundPattern>().to);
if (!imagePosA || !imagePosB)
return;
- spriteAtlas->bind(true, context, 0);
+ imageManager->bind(context, 0);
for (const auto& tileID : util::tileCover(state, state.getIntegerZoom())) {
parameters.programs.fillPattern.draw(
@@ -42,7 +42,7 @@ void Painter::renderBackground(PaintParameters& parameters, const RenderBackgrou
FillPatternUniforms::values(
matrixForTile(tileID),
context.viewport.getCurrentValue().size,
- spriteAtlas->getPixelSize(),
+ imageManager->getPixelSize(),
*imagePosA,
*imagePosB,
background.get<BackgroundPattern>(),
diff --git a/src/mbgl/renderer/painters/painter_fill.cpp b/src/mbgl/renderer/painters/painter_fill.cpp
index d15a871d98..b7e0077ed0 100644
--- a/src/mbgl/renderer/painters/painter_fill.cpp
+++ b/src/mbgl/renderer/painters/painter_fill.cpp
@@ -3,8 +3,8 @@
#include <mbgl/renderer/buckets/fill_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/layers/render_fill_layer.hpp>
+#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/style/layers/fill_layer_impl.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/fill_program.hpp>
#include <mbgl/util/convert.hpp>
@@ -24,14 +24,14 @@ void Painter::renderFill(PaintParameters& parameters,
return;
}
- optional<SpriteAtlasElement> imagePosA = spriteAtlas->getPattern(properties.get<FillPattern>().from);
- optional<SpriteAtlasElement> imagePosB = spriteAtlas->getPattern(properties.get<FillPattern>().to);
+ optional<ImagePosition> imagePosA = imageManager->getPattern(properties.get<FillPattern>().from);
+ optional<ImagePosition> imagePosB = imageManager->getPattern(properties.get<FillPattern>().to);
if (!imagePosA || !imagePosB) {
return;
}
- spriteAtlas->bind(true, context, 0);
+ imageManager->bind(context, 0);
auto draw = [&] (uint8_t sublayer,
auto& program,
@@ -49,7 +49,7 @@ void Painter::renderFill(PaintParameters& parameters,
properties.get<FillTranslateAnchor>(),
state),
context.viewport.getCurrentValue().size,
- spriteAtlas->getPixelSize(),
+ imageManager->getPixelSize(),
*imagePosA,
*imagePosB,
properties.get<FillPattern>(),
diff --git a/src/mbgl/renderer/painters/painter_fill_extrusion.cpp b/src/mbgl/renderer/painters/painter_fill_extrusion.cpp
index c28cb76bff..55e56554dc 100644
--- a/src/mbgl/renderer/painters/painter_fill_extrusion.cpp
+++ b/src/mbgl/renderer/painters/painter_fill_extrusion.cpp
@@ -3,8 +3,8 @@
#include <mbgl/renderer/buckets/fill_extrusion_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp>
+#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/fill_extrusion_program.hpp>
#include <mbgl/util/constants.hpp>
@@ -25,16 +25,14 @@ void Painter::renderFillExtrusion(PaintParameters& parameters,
}
if (!properties.get<FillExtrusionPattern>().from.empty()) {
- optional<SpriteAtlasElement> imagePosA =
- spriteAtlas->getPattern(properties.get<FillExtrusionPattern>().from);
- optional<SpriteAtlasElement> imagePosB =
- spriteAtlas->getPattern(properties.get<FillExtrusionPattern>().to);
+ optional<ImagePosition> imagePosA = imageManager->getPattern(properties.get<FillExtrusionPattern>().from);
+ optional<ImagePosition> imagePosB = imageManager->getPattern(properties.get<FillExtrusionPattern>().to);
if (!imagePosA || !imagePosB) {
return;
}
- spriteAtlas->bind(true, context, 0);
+ imageManager->bind(context, 0);
parameters.programs.fillExtrusionPattern.draw(
context,
@@ -46,7 +44,7 @@ void Painter::renderFillExtrusion(PaintParameters& parameters,
tile.translatedClipMatrix(properties.get<FillExtrusionTranslate>(),
properties.get<FillExtrusionTranslateAnchor>(),
state),
- spriteAtlas->getPixelSize(),
+ imageManager->getPixelSize(),
*imagePosA,
*imagePosB,
properties.get<FillExtrusionPattern>(),
diff --git a/src/mbgl/renderer/painters/painter_line.cpp b/src/mbgl/renderer/painters/painter_line.cpp
index 40076726af..ea2a63529d 100644
--- a/src/mbgl/renderer/painters/painter_line.cpp
+++ b/src/mbgl/renderer/painters/painter_line.cpp
@@ -3,10 +3,10 @@
#include <mbgl/renderer/buckets/line_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/layers/render_line_layer.hpp>
+#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/style/layers/line_layer_impl.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/line_program.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/geometry/line_atlas.hpp>
namespace mbgl {
@@ -61,13 +61,13 @@ void Painter::renderLine(PaintParameters& parameters,
lineAtlas->getSize().width));
} else if (!properties.get<LinePattern>().from.empty()) {
- optional<SpriteAtlasElement> posA = spriteAtlas->getPattern(properties.get<LinePattern>().from);
- optional<SpriteAtlasElement> posB = spriteAtlas->getPattern(properties.get<LinePattern>().to);
+ optional<ImagePosition> posA = imageManager->getPattern(properties.get<LinePattern>().from);
+ optional<ImagePosition> posB = imageManager->getPattern(properties.get<LinePattern>().to);
if (!posA || !posB)
return;
- spriteAtlas->bind(true, context, 0);
+ imageManager->bind(context, 0);
draw(parameters.programs.linePattern,
LinePatternProgram::uniformValues(
@@ -75,7 +75,7 @@ void Painter::renderLine(PaintParameters& parameters,
tile,
state,
pixelsToGLUnits,
- spriteAtlas->getPixelSize(),
+ imageManager->getPixelSize(),
*posA,
*posB));
diff --git a/src/mbgl/renderer/painters/painter_symbol.cpp b/src/mbgl/renderer/painters/painter_symbol.cpp
index 5a5264d178..13baa1a514 100644
--- a/src/mbgl/renderer/painters/painter_symbol.cpp
+++ b/src/mbgl/renderer/painters/painter_symbol.cpp
@@ -5,7 +5,6 @@
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/text/glyph_atlas.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/symbol_program.hpp>
#include <mbgl/programs/collision_box_program.hpp>
@@ -69,9 +68,12 @@ void Painter::renderSymbol(PaintParameters& parameters,
const bool iconScaled = layout.get<IconSize>().constantOr(1.0) != 1.0 || bucket.iconsNeedLinear;
const bool iconTransformed = values.rotationAlignment == AlignmentType::Map || state.getPitch() != 0;
- spriteAtlas->bind(bucket.sdfIcons || state.isChanging() || iconScaled || iconTransformed, context, 0);
- const Size texsize = spriteAtlas->getPixelSize();
+ context.bindTexture(*bucket.icon.atlasTexture, 0,
+ bucket.sdfIcons || state.isChanging() || iconScaled || iconTransformed
+ ? gl::TextureFilter::Linear : gl::TextureFilter::Nearest);
+
+ const Size texsize = bucket.icon.atlasTexture->size;
if (bucket.sdfIcons) {
if (values.hasHalo) {
diff --git a/src/mbgl/renderer/render_style.cpp b/src/mbgl/renderer/render_style.cpp
index 845bdbe63b..f76d1f48d8 100644
--- a/src/mbgl/renderer/render_style.cpp
+++ b/src/mbgl/renderer/render_style.cpp
@@ -16,14 +16,13 @@
#include <mbgl/renderer/layers/render_raster_layer.hpp>
#include <mbgl/renderer/layers/render_symbol_layer.hpp>
#include <mbgl/renderer/style_diff.hpp>
+#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/source_impl.hpp>
#include <mbgl/style/transition_options.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/sprite/sprite_loader.hpp>
#include <mbgl/text/glyph_manager.hpp>
#include <mbgl/geometry/line_atlas.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/map/query.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/util/math.hpp>
@@ -39,7 +38,7 @@ RenderStyle::RenderStyle(Scheduler& scheduler_, FileSource& fileSource_)
: scheduler(scheduler_),
fileSource(fileSource_),
glyphManager(std::make_unique<GlyphManager>(fileSource)),
- spriteAtlas(std::make_unique<SpriteAtlas>()),
+ imageManager(std::make_unique<ImageManager>()),
lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })),
imageImpls(makeMutable<std::vector<Immutable<style::Image::Impl>>>()),
sourceImpls(makeMutable<std::vector<Immutable<style::Source::Impl>>>()),
@@ -100,7 +99,7 @@ void RenderStyle::update(const UpdateParameters& parameters) {
parameters.fileSource,
parameters.mode,
parameters.annotationManager,
- *spriteAtlas,
+ *imageManager,
*glyphManager
};
@@ -124,21 +123,21 @@ void RenderStyle::update(const UpdateParameters& parameters) {
// Remove removed images from sprite atlas.
for (const auto& entry : imageDiff.removed) {
- spriteAtlas->removeImage(entry.first);
+ imageManager->removeImage(entry.first);
}
// Add added images to sprite atlas.
for (const auto& entry : imageDiff.added) {
- spriteAtlas->addImage(entry.second);
+ imageManager->addImage(entry.second);
}
// Update changed images.
for (const auto& entry : imageDiff.changed) {
- spriteAtlas->updateImage(entry.second.after);
+ imageManager->updateImage(entry.second.after);
}
- if (parameters.spriteLoaded && !spriteAtlas->isLoaded()) {
- spriteAtlas->onSpriteLoaded();
+ if (parameters.spriteLoaded && !imageManager->isLoaded()) {
+ imageManager->onSpriteLoaded();
}
@@ -208,7 +207,7 @@ void RenderStyle::update(const UpdateParameters& parameters) {
needsRendering = true;
}
- if (hasLayoutDifference(layerDiff, layer->id)) {
+ if (hasLayoutDifference(layerDiff, layer->id) || !imageDiff.changed.empty()) {
needsRelayout = true;
}
@@ -249,7 +248,7 @@ bool RenderStyle::isLoaded() const {
}
}
- if (!spriteAtlas->isLoaded()) {
+ if (!imageManager->isLoaded()) {
return false;
}
@@ -442,7 +441,7 @@ void RenderStyle::dumpDebugLogs() const {
entry.second->dumpDebugLogs();
}
- spriteAtlas->dumpDebugLogs();
+ imageManager->dumpDebugLogs();
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/render_style.hpp b/src/mbgl/renderer/render_style.hpp
index 26aebda3ab..dc33e7b2f4 100644
--- a/src/mbgl/renderer/render_style.hpp
+++ b/src/mbgl/renderer/render_style.hpp
@@ -17,7 +17,7 @@ namespace mbgl {
class FileSource;
class GlyphManager;
-class SpriteAtlas;
+class ImageManager;
class LineAtlas;
class RenderData;
class TransformState;
@@ -67,7 +67,7 @@ public:
Scheduler& scheduler;
FileSource& fileSource;
std::unique_ptr<GlyphManager> glyphManager;
- std::unique_ptr<SpriteAtlas> spriteAtlas;
+ std::unique_ptr<ImageManager> imageManager;
std::unique_ptr<LineAtlas> lineAtlas;
private:
diff --git a/src/mbgl/renderer/tile_parameters.hpp b/src/mbgl/renderer/tile_parameters.hpp
index 88def11585..cf7a5b100a 100644
--- a/src/mbgl/renderer/tile_parameters.hpp
+++ b/src/mbgl/renderer/tile_parameters.hpp
@@ -8,7 +8,7 @@ class TransformState;
class Scheduler;
class FileSource;
class AnnotationManager;
-class SpriteAtlas;
+class ImageManager;
class GlyphManager;
class TileParameters {
@@ -20,7 +20,7 @@ public:
FileSource& fileSource;
const MapMode mode;
AnnotationManager& annotationManager;
- SpriteAtlas& spriteAtlas;
+ ImageManager& imageManager;
GlyphManager& glyphManager;
};
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
deleted file mode 100644
index 69f2b0ce71..0000000000
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-#include <mbgl/sprite/sprite_atlas.hpp>
-#include <mbgl/style/image_impl.hpp>
-#include <mbgl/gl/context.hpp>
-#include <mbgl/util/logging.hpp>
-#include <mbgl/util/platform.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/util/std.hpp>
-#include <mbgl/util/constants.hpp>
-#include <mbgl/util/exception.hpp>
-
-#include <cassert>
-#include <cmath>
-#include <algorithm>
-
-namespace mbgl {
-
-// When copied into the atlas texture, image data is padded by one pixel on each side. Icon
-// images are padded with fully transparent pixels, while pattern images are padded with a
-// copy of the image data wrapped from the opposite side. In both cases, this ensures the
-// correct behavior of GL_LINEAR texture sampling mode.
-static constexpr uint16_t padding = 1;
-
-SpriteAtlasElement::SpriteAtlasElement(const mapbox::Bin& bin, const style::Image::Impl& image)
- : sdf(image.sdf),
- pixelRatio(image.pixelRatio),
- textureRect(
- bin.x + padding,
- bin.y + padding,
- bin.w - padding * 2,
- bin.h - padding * 2
- ) {
-}
-
-static mapbox::ShelfPack::ShelfPackOptions shelfPackOptions() {
- mapbox::ShelfPack::ShelfPackOptions options;
- options.autoResize = true;
- return options;
-}
-
-SpriteAtlas::SpriteAtlas()
- : shelfPack(64, 64, shelfPackOptions()) {
-}
-
-SpriteAtlas::~SpriteAtlas() = default;
-
-void SpriteAtlas::onSpriteLoaded() {
- loaded = true;
- for (auto requestor : requestors) {
- requestor->onIconsAvailable(buildIconMap());
- }
- requestors.clear();
-}
-
-void SpriteAtlas::addImage(Immutable<style::Image::Impl> image_) {
- assert(entries.find(image_->id) == entries.end());
- entries.emplace(image_->id, Entry { image_ });
- icons.clear();
-}
-
-void SpriteAtlas::updateImage(Immutable<style::Image::Impl> image_) {
- assert(entries.find(image_->id) != entries.end());
- Entry& entry = entries.at(image_->id);
-
- // Style::addImage should prevent changing size.
- assert(entry.image->image.size == image_->image.size);
-
- entry.image = std::move(image_);
-
- if (entry.iconBin) {
- copy(entry, &Entry::iconBin);
- }
-
- if (entry.patternBin) {
- copy(entry, &Entry::patternBin);
- }
-
- icons.clear();
-}
-
-void SpriteAtlas::removeImage(const std::string& id) {
- assert(entries.find(id) != entries.end());
- Entry& entry = entries.at(id);
-
- if (entry.iconBin) {
- shelfPack.unref(*entry.iconBin);
- }
-
- if (entry.patternBin) {
- shelfPack.unref(*entry.patternBin);
- }
-
- entries.erase(id);
- icons.clear();
-}
-
-const style::Image::Impl* SpriteAtlas::getImage(const std::string& id) const {
- const auto it = entries.find(id);
- if (it != entries.end()) {
- return it->second.image.get();
- }
- if (!entries.empty()) {
- Log::Info(Event::Sprite, "Can't find sprite named '%s'", id.c_str());
- }
- return nullptr;
-}
-
-void SpriteAtlas::getIcons(IconRequestor& requestor, IconDependencies dependencies) {
- // If the sprite has been loaded, or if all the icon dependencies are already present
- // (i.e. if they've been addeded via runtime styling), then notify the requestor immediately.
- // Otherwise, delay notification until the sprite is loaded. At that point, if any of the
- // dependencies are still unavailable, we'll just assume they are permanently missing.
- bool hasAllDependencies = true;
- if (!isLoaded()) {
- for (const auto& dependency : dependencies) {
- if (entries.find(dependency) == entries.end()) {
- hasAllDependencies = false;
- }
- }
- }
- if (isLoaded() || hasAllDependencies) {
- requestor.onIconsAvailable(buildIconMap());
- } else {
- requestors.insert(&requestor);
- }
-}
-
-void SpriteAtlas::removeRequestor(IconRequestor& requestor) {
- requestors.erase(&requestor);
-}
-
-optional<SpriteAtlasElement> SpriteAtlas::getIcon(const std::string& id) {
- return getImage(id, &Entry::iconBin);
-}
-
-optional<SpriteAtlasElement> SpriteAtlas::getPattern(const std::string& id) {
- return getImage(id, &Entry::patternBin);
-}
-
-optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& id, mapbox::Bin* Entry::*entryBin) {
- auto it = entries.find(id);
- if (it == entries.end()) {
- if (!entries.empty()) {
- Log::Info(Event::Sprite, "Can't find sprite named '%s'", id.c_str());
- }
- return {};
- }
-
- Entry& entry = it->second;
-
- if (entry.*entryBin) {
- assert(entry.image.get());
- return SpriteAtlasElement {
- *(entry.*entryBin),
- *entry.image
- };
- }
-
- const uint16_t width = entry.image->image.size.width + padding * 2;
- const uint16_t height = entry.image->image.size.height + padding * 2;
-
- mapbox::Bin* bin = shelfPack.packOne(-1, width, height);
- if (!bin) {
- if (debug::spriteWarnings) {
- Log::Warning(Event::Sprite, "sprite atlas bitmap overflow");
- }
- return {};
- }
-
- entry.*entryBin = bin;
- copy(entry, entryBin);
-
- return SpriteAtlasElement {
- *bin,
- *entry.image
- };
-}
-
-Size SpriteAtlas::getPixelSize() const {
- return Size {
- static_cast<uint32_t>(shelfPack.width()),
- static_cast<uint32_t>(shelfPack.height())
- };
-}
-
-void SpriteAtlas::copy(const Entry& entry, mapbox::Bin* Entry::*entryBin) {
- if (!image.valid()) {
- image = PremultipliedImage(getPixelSize());
- image.fill(0);
- } else if (image.size != getPixelSize()) {
- PremultipliedImage newImage(getPixelSize());
- PremultipliedImage::copy(image, newImage, { 0, 0 }, { 0, 0 }, image.size);
- image = std::move(newImage);
- }
-
- const PremultipliedImage& src = entry.image->image;
- const mapbox::Bin& bin = *(entry.*entryBin);
-
- const uint32_t x = bin.x + padding;
- const uint32_t y = bin.y + padding;
- const uint32_t w = src.size.width;
- const uint32_t h = src.size.height;
-
- PremultipliedImage::copy(src, image, { 0, 0 }, { x, y }, { w, h });
-
- if (entryBin == &Entry::patternBin) {
- // Add 1 pixel wrapped padding on each side of the image.
- PremultipliedImage::copy(src, image, { 0, h - 1 }, { x, y - 1 }, { w, 1 }); // T
- PremultipliedImage::copy(src, image, { 0, 0 }, { x, y + h }, { w, 1 }); // B
- PremultipliedImage::copy(src, image, { w - 1, 0 }, { x - 1, y }, { 1, h }); // L
- PremultipliedImage::copy(src, image, { 0, 0 }, { x + w, y }, { 1, h }); // R
- }
-
- dirty = true;
-}
-
-IconMap SpriteAtlas::buildIconMap() {
- if (icons.empty()) {
- for (const auto& entry : entries) {
- icons.emplace(std::piecewise_construct,
- std::forward_as_tuple(entry.first),
- std::forward_as_tuple(*getIcon(entry.first)));
-
- }
- }
- return icons;
-}
-
-void SpriteAtlas::upload(gl::Context& context, gl::TextureUnit unit) {
- if (!texture) {
- texture = context.createTexture(image, unit);
- } else if (dirty) {
- context.updateTexture(*texture, image, unit);
- }
-
-#if not MBGL_USE_GLES2
-// if (dirty) {
-// platform::showColorDebugImage("Sprite Atlas",
-// reinterpret_cast<const char*>(image.data.get()), size.width,
-// size.height, image.size.width, image.size.height);
-// }
-#endif // MBGL_USE_GLES2
-
- dirty = false;
-}
-
-void SpriteAtlas::bind(bool linear, gl::Context& context, gl::TextureUnit unit) {
- upload(context, unit);
- context.bindTexture(*texture, unit,
- linear ? gl::TextureFilter::Linear : gl::TextureFilter::Nearest);
-}
-
-void SpriteAtlas::dumpDebugLogs() const {
- Log::Info(Event::General, "SpriteAtlas::loaded: %d", loaded);
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp
deleted file mode 100644
index 1dbef86f7e..0000000000
--- a/src/mbgl/sprite/sprite_atlas.hpp
+++ /dev/null
@@ -1,137 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/texture.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/optional.hpp>
-#include <mbgl/util/rect.hpp>
-#include <mbgl/style/image.hpp>
-
-#include <mapbox/shelf-pack.hpp>
-
-#include <string>
-#include <set>
-#include <unordered_map>
-#include <array>
-#include <memory>
-
-namespace mbgl {
-
-namespace gl {
-class Context;
-} // namespace gl
-
-class SpriteAtlasElement {
-public:
- SpriteAtlasElement(const mapbox::Bin&, const style::Image::Impl&);
-
- bool sdf;
- float pixelRatio;
- Rect<uint16_t> textureRect;
-
- std::array<uint16_t, 2> tl() const {
- return {{
- textureRect.x,
- textureRect.y
- }};
- }
-
- std::array<uint16_t, 2> br() const {
- return {{
- static_cast<uint16_t>(textureRect.x + textureRect.w),
- static_cast<uint16_t>(textureRect.y + textureRect.h)
- }};
- }
-
- std::array<float, 2> displaySize() const {
- return {{
- textureRect.w / pixelRatio,
- textureRect.h / pixelRatio,
- }};
- }
-};
-
-using IconMap = std::unordered_map<std::string, SpriteAtlasElement>;
-using IconDependencies = std::set<std::string>;
-
-class IconRequestor {
-public:
- virtual ~IconRequestor() = default;
- virtual void onIconsAvailable(IconMap) = 0;
-};
-
-class SpriteAtlas : public util::noncopyable {
-public:
- SpriteAtlas();
- ~SpriteAtlas();
-
- void onSpriteLoaded();
-
- bool isLoaded() const {
- return loaded;
- }
-
- void dumpDebugLogs() const;
-
- const style::Image::Impl* getImage(const std::string&) const;
-
- void addImage(Immutable<style::Image::Impl>);
- void updateImage(Immutable<style::Image::Impl>);
- void removeImage(const std::string&);
-
- void getIcons(IconRequestor&, IconDependencies);
- void removeRequestor(IconRequestor&);
-
- // Ensure that the atlas contains the named image suitable for rendering as an icon, and
- // return its metrics. The image will be padded on each side with a one pixel wide transparent
- // strip, but the returned metrics are exclusive of this padding.
- optional<SpriteAtlasElement> getIcon(const std::string& name);
-
- // Ensure that the atlas contains the named image suitable for rendering as an pattern, and
- // return its metrics. The image will be padded on each side with a one pixel wide copy of
- // pixels from the opposite side, but the returned metrics are exclusive of this padding.
- optional<SpriteAtlasElement> getPattern(const std::string& name);
-
- // Binds the atlas texture to the GPU, and uploads data if it is out of date.
- void bind(bool linear, gl::Context&, gl::TextureUnit unit);
-
- // Uploads the texture to the GPU to be available when we need it. This is a lazy operation;
- // the texture is only bound when the data is out of date (=dirty).
- void upload(gl::Context&, gl::TextureUnit unit);
-
- Size getPixelSize() const;
-
- // Only for use in tests.
- const PremultipliedImage& getAtlasImage() const {
- return image;
- }
-
-private:
- bool loaded = false;
-
- struct Entry {
- Immutable<style::Image::Impl> image;
-
- // One sprite image might be used as both an icon image and a pattern image. If so,
- // it must have two distinct entries in the texture. The one for the icon image has
- // a single pixel transparent border, and the one for the pattern image has a single
- // pixel border wrapped from the opposite side.
- mapbox::Bin* iconBin = nullptr;
- mapbox::Bin* patternBin = nullptr;
- };
-
- optional<SpriteAtlasElement> getImage(const std::string& name, mapbox::Bin* Entry::*bin);
- void copy(const Entry&, mapbox::Bin* Entry::*bin);
-
- IconMap buildIconMap();
-
- std::unordered_map<std::string, Entry> entries;
- mapbox::ShelfPack shelfPack;
- PremultipliedImage image;
- mbgl::optional<gl::Texture> texture;
- bool dirty = true;
-
- std::set<IconRequestor*> requestors;
- IconMap icons;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/sprite/sprite_loader.cpp b/src/mbgl/sprite/sprite_loader.cpp
index 7c5fe40e05..60ece5ed73 100644
--- a/src/mbgl/sprite/sprite_loader.cpp
+++ b/src/mbgl/sprite/sprite_loader.cpp
@@ -20,9 +20,9 @@ namespace mbgl {
static SpriteLoaderObserver nullObserver;
struct SpriteLoader::Loader {
- Loader(Scheduler& scheduler, SpriteLoader& spriteAtlas)
+ Loader(Scheduler& scheduler, SpriteLoader& imageManager)
: mailbox(std::make_shared<Mailbox>(*util::RunLoop::Get())),
- worker(scheduler, ActorRef<SpriteLoader>(spriteAtlas, mailbox)) {
+ worker(scheduler, ActorRef<SpriteLoader>(imageManager, mailbox)) {
}
std::shared_ptr<const std::string> image;
diff --git a/src/mbgl/style/image_impl.hpp b/src/mbgl/style/image_impl.hpp
index aa2cad8278..75dc83206c 100644
--- a/src/mbgl/style/image_impl.hpp
+++ b/src/mbgl/style/image_impl.hpp
@@ -2,6 +2,10 @@
#include <mbgl/style/image.hpp>
+#include <string>
+#include <unordered_map>
+#include <set>
+
namespace mbgl {
namespace style {
@@ -21,4 +25,8 @@ public:
};
} // namespace style
+
+using ImageMap = std::unordered_map<std::string, Immutable<style::Image::Impl>>;
+using ImageDependencies = std::set<std::string>;
+
} // namespace mbgl
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 69a6d401ed..27ca58e85d 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -232,14 +232,7 @@ bool Style::isLoaded() const {
}
void Style::addImage(std::unique_ptr<style::Image> image) {
- if (style::Image* existing = images.get(image->getID())) {
- if (existing->getImage().size != image->getImage().size) {
- Log::Warning(Event::Sprite, "Can't change sprite dimensions for '%s'", image->getID().c_str());
- return;
- }
- images.remove(image->getID());
- }
-
+ images.remove(image->getID()); // We permit using addImage to update.
images.add(std::move(image));
}
diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp
index ad57342b82..81827ca32e 100644
--- a/src/mbgl/text/quads.cpp
+++ b/src/mbgl/text/quads.cpp
@@ -22,7 +22,7 @@ SymbolQuad getIconQuad(const Anchor& anchor,
const float layoutTextSize,
const style::SymbolPlacementType placement,
const Shaping& shapedText) {
- const SpriteAtlasElement& image = shapedIcon.image();
+ const ImagePosition& image = shapedIcon.image();
// If you have a 10px icon that isn't perfectly aligned to the pixel grid it will cover 11 actual
// pixels. The quad needs to be padded to account for this, otherwise they'll look slightly clipped
diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp
index 0ef347ba0b..338abe2e43 100644
--- a/src/mbgl/text/shaping.cpp
+++ b/src/mbgl/text/shaping.cpp
@@ -10,7 +10,7 @@
namespace mbgl {
-PositionedIcon PositionedIcon::shapeIcon(const SpriteAtlasElement& image, const std::array<float, 2>& iconOffset, const float iconRotation) {
+PositionedIcon PositionedIcon::shapeIcon(const ImagePosition& image, const std::array<float, 2>& iconOffset, const float iconRotation) {
float dx = iconOffset[0];
float dy = iconOffset[1];
float x1 = dx - image.displaySize()[0] / 2.0f;
diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp
index 1984b14e1d..ca475e2a6c 100644
--- a/src/mbgl/text/shaping.hpp
+++ b/src/mbgl/text/shaping.hpp
@@ -1,30 +1,29 @@
#pragma once
#include <mbgl/text/glyph.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/renderer/image_atlas.hpp>
namespace mbgl {
-class SpriteAtlasElement;
class SymbolFeature;
class BiDi;
class PositionedIcon {
private:
- PositionedIcon(const SpriteAtlasElement& image_,
+ PositionedIcon(ImagePosition image_,
float top_,
float bottom_,
float left_,
float right_,
float angle_)
- : _image(image_),
+ : _image(std::move(image_)),
_top(top_),
_bottom(bottom_),
_left(left_),
_right(right_),
_angle(angle_) {}
- SpriteAtlasElement _image;
+ ImagePosition _image;
float _top;
float _bottom;
float _left;
@@ -32,9 +31,9 @@ private:
float _angle;
public:
- static PositionedIcon shapeIcon(const SpriteAtlasElement&, const std::array<float, 2>& iconOffset, const float iconRotation);
+ static PositionedIcon shapeIcon(const ImagePosition&, const std::array<float, 2>& iconOffset, const float iconRotation);
- const SpriteAtlasElement& image() const { return _image; }
+ const ImagePosition& image() const { return _image; }
float top() const { return _top; }
float bottom() const { return _bottom; }
float left() const { return _left; }
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 13034910a4..b7561d677c 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -39,13 +39,13 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_,
parameters.mode,
parameters.pixelRatio),
glyphManager(parameters.glyphManager),
- spriteAtlas(parameters.spriteAtlas),
+ imageManager(parameters.imageManager),
placementThrottler(Milliseconds(300), [this] { invokePlacement(); }) {
}
GeometryTile::~GeometryTile() {
glyphManager.removeRequestor(*this);
- spriteAtlas.removeRequestor(*this);
+ imageManager.removeRequestor(*this);
markObsolete();
}
@@ -153,12 +153,12 @@ void GeometryTile::getGlyphs(GlyphDependencies glyphDependencies) {
glyphManager.getGlyphs(*this, std::move(glyphDependencies));
}
-void GeometryTile::onIconsAvailable(IconMap icons) {
- worker.invoke(&GeometryTileWorker::onIconsAvailable, std::move(icons));
+void GeometryTile::onImagesAvailable(ImageMap images) {
+ worker.invoke(&GeometryTileWorker::onImagesAvailable, std::move(images));
}
-void GeometryTile::getIcons(IconDependencies iconDependencies) {
- spriteAtlas.getIcons(*this, std::move(iconDependencies));
+void GeometryTile::getImages(ImageDependencies imageDependencies) {
+ imageManager.getImages(*this, std::move(imageDependencies));
}
void GeometryTile::upload(gl::Context& context) {
diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index 659f4f7e9f..f2510e317b 100644
--- a/src/mbgl/tile/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
@@ -1,8 +1,8 @@
#pragma once
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/tile/geometry_tile_worker.hpp>
+#include <mbgl/renderer/image_manager.hpp>
#include <mbgl/text/glyph_manager.hpp>
#include <mbgl/text/placement_config.hpp>
#include <mbgl/util/feature.hpp>
@@ -24,7 +24,7 @@ class RenderLayer;
class SourceQueryOptions;
class TileParameters;
-class GeometryTile : public Tile, public GlyphRequestor, IconRequestor {
+class GeometryTile : public Tile, public GlyphRequestor, ImageRequestor {
public:
GeometryTile(const OverscaledTileID&,
std::string sourceID,
@@ -39,10 +39,10 @@ public:
void setLayers(const std::vector<Immutable<style::Layer::Impl>>&) override;
void onGlyphsAvailable(GlyphMap) override;
- void onIconsAvailable(IconMap) override;
+ void onImagesAvailable(ImageMap) override;
void getGlyphs(GlyphDependencies);
- void getIcons(IconDependencies);
+ void getImages(ImageDependencies);
void upload(gl::Context&) override;
Bucket* getBucket(const style::Layer::Impl&) const override;
@@ -97,7 +97,7 @@ private:
Actor<GeometryTileWorker> worker;
GlyphManager& glyphManager;
- SpriteAtlas& spriteAtlas;
+ ImageManager& imageManager;
uint64_t correlationID = 0;
optional<PlacementConfig> requestedConfig;
diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp
index 8eaea161d2..d67cbca76b 100644
--- a/src/mbgl/tile/geometry_tile_worker.cpp
+++ b/src/mbgl/tile/geometry_tile_worker.cpp
@@ -3,7 +3,6 @@
#include <mbgl/tile/geometry_tile.hpp>
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/layout/symbol_layout.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/renderer/bucket_parameters.hpp>
#include <mbgl/renderer/group_by_layout.hpp>
#include <mbgl/style/filter.hpp>
@@ -217,9 +216,9 @@ void GeometryTileWorker::onGlyphsAvailable(GlyphMap newGlyphMap) {
symbolDependenciesChanged();
}
-void GeometryTileWorker::onIconsAvailable(IconMap newIconMap) {
- iconMap = std::move(newIconMap);
- pendingIconDependencies.clear();
+void GeometryTileWorker::onImagesAvailable(ImageMap newImageMap) {
+ imageMap = std::move(newImageMap);
+ pendingImageDependencies.clear();
symbolDependenciesChanged();
}
@@ -237,10 +236,10 @@ void GeometryTileWorker::requestNewGlyphs(const GlyphDependencies& glyphDependen
}
}
-void GeometryTileWorker::requestNewIcons(const IconDependencies& iconDependencies) {
- pendingIconDependencies = iconDependencies;
- if (!pendingIconDependencies.empty()) {
- parent.invoke(&GeometryTile::getIcons, pendingIconDependencies);
+void GeometryTileWorker::requestNewImages(const ImageDependencies& imageDependencies) {
+ pendingImageDependencies = imageDependencies;
+ if (!pendingImageDependencies.empty()) {
+ parent.invoke(&GeometryTile::getImages, pendingImageDependencies);
}
}
@@ -280,7 +279,7 @@ void GeometryTileWorker::redoLayout() {
BucketParameters parameters { id, mode, pixelRatio };
GlyphDependencies glyphDependencies;
- IconDependencies iconDependencies;
+ ImageDependencies imageDependencies;
// Create render layers and group by layout
std::vector<std::unique_ptr<RenderLayer>> renderLayers = toRenderLayers(*layers, id.overscaledZ);
@@ -311,7 +310,7 @@ void GeometryTileWorker::redoLayout() {
if (leader.is<RenderSymbolLayer>()) {
symbolLayoutMap.emplace(leader.getID(),
- leader.as<RenderSymbolLayer>()->createLayout(parameters, group, *geometryLayer, glyphDependencies, iconDependencies));
+ leader.as<RenderSymbolLayer>()->createLayout(parameters, group, *geometryLayer, glyphDependencies, imageDependencies));
} else {
const Filter& filter = leader.baseImpl->filter;
const std::string& sourceLayerID = leader.baseImpl->sourceLayer;
@@ -347,7 +346,7 @@ void GeometryTileWorker::redoLayout() {
}
requestNewGlyphs(glyphDependencies);
- requestNewIcons(iconDependencies);
+ requestNewImages(imageDependencies);
parent.invoke(&GeometryTile::onLayout, GeometryTile::LayoutResult {
std::move(buckets),
@@ -375,7 +374,7 @@ bool GeometryTileWorker::hasPendingSymbolDependencies() const {
return true;
}
}
- return !pendingIconDependencies.empty();
+ return !pendingImageDependencies.empty();
}
@@ -393,7 +392,7 @@ void GeometryTileWorker::attemptPlacement() {
}
if (symbolLayout->state == SymbolLayout::Pending) {
- symbolLayout->prepare(glyphMap, iconMap);
+ symbolLayout->prepare(glyphMap, imageMap);
symbolLayout->state = SymbolLayout::Placed;
}
diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp
index c07c16dd9b..194477e7b8 100644
--- a/src/mbgl/tile/geometry_tile_worker.hpp
+++ b/src/mbgl/tile/geometry_tile_worker.hpp
@@ -2,7 +2,7 @@
#include <mbgl/map/mode.hpp>
#include <mbgl/tile/tile_id.hpp>
-#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/style/image_impl.hpp>
#include <mbgl/text/glyph.hpp>
#include <mbgl/text/placement_config.hpp>
#include <mbgl/actor/actor_ref.hpp>
@@ -38,7 +38,7 @@ public:
void setPlacementConfig(PlacementConfig, uint64_t correlationID);
void onGlyphsAvailable(GlyphMap glyphs);
- void onIconsAvailable(IconMap icons);
+ void onImagesAvailable(ImageMap images);
private:
void coalesced();
@@ -48,7 +48,7 @@ private:
void coalesce();
void requestNewGlyphs(const GlyphDependencies&);
- void requestNewIcons(const IconDependencies&);
+ void requestNewImages(const ImageDependencies&);
void symbolDependenciesChanged();
bool hasPendingSymbolDependencies() const;
@@ -79,9 +79,9 @@ private:
std::vector<std::unique_ptr<SymbolLayout>> symbolLayouts;
GlyphDependencies pendingGlyphDependencies;
- IconDependencies pendingIconDependencies;
+ ImageDependencies pendingImageDependencies;
GlyphMap glyphMap;
- IconMap iconMap;
+ ImageMap imageMap;
};
} // namespace mbgl