summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer
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/mbgl/renderer
parent92252849c1a2ddf7887d1908841fa3c90dd59766 (diff)
downloadqtlocation-mapboxgl-0b687312071305c050d97e04fef1c80193f443c5.tar.gz
[core] Per-bucket icon atlases
Diffstat (limited to 'src/mbgl/renderer')
-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
18 files changed, 438 insertions, 51 deletions
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;
};