diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2017-06-07 12:45:35 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2017-06-13 10:18:43 -0700 |
commit | 0b687312071305c050d97e04fef1c80193f443c5 (patch) | |
tree | 64c20efaa17fefef9f902811a000fd6e425c849b /src/mbgl/renderer | |
parent | 92252849c1a2ddf7887d1908841fa3c90dd59766 (diff) | |
download | qtlocation-mapboxgl-0b687312071305c050d97e04fef1c80193f443c5.tar.gz |
[core] Per-bucket icon atlases
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/image_atlas.cpp | 68 | ||||
-rw-r--r-- | src/mbgl/renderer/image_atlas.hpp | 51 | ||||
-rw-r--r-- | src/mbgl/renderer/image_manager.cpp | 173 | ||||
-rw-r--r-- | src/mbgl/renderer/image_manager.hpp | 94 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 7 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/painters/painter_background.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/renderer/painters/painter_fill.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/renderer/painters/painter_fill_extrusion.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/renderer/painters/painter_line.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/renderer/painters/painter_symbol.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/render_style.cpp | 23 | ||||
-rw-r--r-- | src/mbgl/renderer/render_style.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/tile_parameters.hpp | 4 |
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; }; |