make sure we retain shared state when destructing the map object

refs #261
This commit is contained in:
Konstantin Käfer
2014-05-30 17:00:47 +02:00
parent 3e7f801de1
commit 78fda8bb62
18 changed files with 174 additions and 110 deletions

View File

@@ -97,13 +97,13 @@ public:
public:
inline const TransformState &getState() const { return state; }
inline const Style &getStyle() const { return style; }
inline GlyphAtlas &getGlyphAtlas() { return glyphAtlas; }
inline GlyphStore &getGlyphStore() { return glyphStore; }
inline SpriteAtlas &getSpriteAtlas() { return spriteAtlas; }
inline std::shared_ptr<const Style> getStyle() const { return style; }
inline std::shared_ptr<GlyphAtlas> getGlyphAtlas() { return glyphAtlas; }
inline std::shared_ptr<GlyphStore> getGlyphStore() { return glyphStore; }
inline std::shared_ptr<SpriteAtlas> getSpriteAtlas() { return spriteAtlas; }
inline std::shared_ptr<Texturepool> getTexturepool() { return texturepool; }
inline uv_loop_t *getLoop() { return loop; }
inline time getAnimationTime() const { return animationTime; }
inline Texturepool &getTexturepool() { return texturepool; }
inline const Sources &getSources() { return sources; }
private:
@@ -151,11 +151,12 @@ private:
Transform transform;
TransformState state;
Texturepool texturepool;
Style style;
GlyphAtlas glyphAtlas;
GlyphStore glyphStore;
SpriteAtlas spriteAtlas;
std::shared_ptr<Style> style;
std::shared_ptr<GlyphAtlas> glyphAtlas;
std::shared_ptr<GlyphStore> glyphStore;
std::shared_ptr<SpriteAtlas> spriteAtlas;
std::shared_ptr<Texturepool> texturepool;
Painter painter;
Sources sources;

View File

@@ -46,7 +46,9 @@ public:
const std::string toString() const;
// Override this in the child class.
virtual void beforeParse();
virtual void parse() = 0;
virtual void afterParse();
virtual void render(Painter &painter, const LayerDescription& layer_desc) = 0;
virtual bool hasData(const LayerDescription& layer_desc) const = 0;

View File

@@ -1,7 +1,6 @@
#ifndef LLMR_MAP_TILE_PARSER
#define LLMR_MAP_TILE_PARSER
#include <llmr/map/vector_tile_data.hpp>
#include <llmr/map/vector_tile.hpp>
#include <llmr/text/placement.hpp>
#include <llmr/text/glyph_store.hpp>
@@ -14,13 +13,21 @@ class Style;
class GlyphAtlas;
class GlyphStore;
class SpriteAtlas;
class VectorTileData;
class LayerDescription;
class Bucket;
class TileParser {
public:
TileParser(const std::string& data, VectorTileData& tile, const Style& style, GlyphAtlas& glyphAtlas, GlyphStore &glyphStore, SpriteAtlas &spriteAtlas);
TileParser(const std::string &data, VectorTileData &tile,
const std::shared_ptr<const Style> &style,
const std::shared_ptr<GlyphAtlas> &glyphAtlas,
const std::shared_ptr<GlyphStore> &glyphStore,
const std::shared_ptr<SpriteAtlas> &spriteAtlas);
public:
void parse();
private:
bool obsolete() const;
@@ -38,10 +45,13 @@ private:
private:
const VectorTile vector_data;
VectorTileData& tile;
const Style& style;
GlyphAtlas& glyphAtlas;
GlyphStore &glyphStore;
SpriteAtlas &spriteAtlas;
// Cross-thread shared data.
std::shared_ptr<const Style> style;
std::shared_ptr<GlyphAtlas> glyphAtlas;
std::shared_ptr<GlyphStore> glyphStore;
std::shared_ptr<SpriteAtlas> spriteAtlas;
Placement placement;
};

View File

@@ -12,6 +12,7 @@
#include <llmr/geometry/line_buffer.hpp>
#include <llmr/geometry/icon_buffer.hpp>
#include <llmr/geometry/text_buffer.hpp>
#include <llmr/map/tile_parser.hpp>
#include <unordered_map>
@@ -25,7 +26,9 @@ public:
VectorTileData(Tile::ID id, Map &map, const std::string url);
~VectorTileData();
virtual void beforeParse();
virtual void parse();
virtual void afterParse();
virtual void render(Painter &painter, const LayerDescription& layer_desc);
virtual bool hasData(const LayerDescription& layer_desc) const;
@@ -44,6 +47,7 @@ protected:
// They contain the location offsets in the buffers stored above
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
std::unique_ptr<TileParser> parser;
};
}

View File

@@ -13,7 +13,7 @@ class VertexArrayObject;
class RasterBucket : public Bucket {
public:
RasterBucket(Texturepool &texturepool);
RasterBucket(const std::shared_ptr<Texturepool> &texturepool);
virtual void render(Painter& painter, const std::string& layer_name, const Tile::ID& id);
virtual bool hasData() const;

View File

@@ -16,7 +16,7 @@ namespace llmr {
class Raster : public std::enable_shared_from_this<Raster> {
public:
Raster(Texturepool &texturepool);
Raster(const std::shared_ptr<Texturepool> &texturepool);
~Raster();
// load image data
@@ -53,7 +53,7 @@ private:
bool loaded = false;
// shared texture pool
Texturepool &texturepool;
std::shared_ptr<Texturepool> texturepool;
// min/mag filter
uint32_t filter = 0;

View File

@@ -19,10 +19,11 @@ using namespace llmr;
Map::Map(View& view)
: view(view),
transform(),
texturepool(),
style(),
glyphAtlas(1024, 1024),
spriteAtlas(512, 512),
style(std::make_shared<Style>()),
glyphAtlas(std::make_shared<GlyphAtlas>(1024, 1024)),
glyphStore(std::make_shared<GlyphStore>()),
spriteAtlas(std::make_shared<SpriteAtlas>(512, 512)),
texturepool(std::make_shared<Texturepool>()),
painter(*this),
loop(uv_loop_new()) {
@@ -35,6 +36,10 @@ Map::Map(View& view)
}
Map::~Map() {
if (async) {
stop();
}
uv_loop_delete(loop);
loop = nullptr;
}
@@ -186,7 +191,7 @@ void Map::setup() {
}
void Map::loadStyle(const uint8_t *const data, uint32_t bytes) {
style.loadJSON(data, bytes);
style->loadJSON(data, bytes);
update();
}
@@ -386,18 +391,18 @@ bool Map::getDebug() const {
}
void Map::toggleRaster() {
style.setDefaultTransitionDuration(300);
style.cancelTransitions();
style->setDefaultTransitionDuration(300);
style->cancelTransitions();
auto it = sources.find("satellite");
if (it != sources.end()) {
Source &satellite_source = *it->second;
if (satellite_source.enabled) {
satellite_source.enabled = false;
style.appliedClasses.erase("satellite");
style->appliedClasses.erase("satellite");
} else {
satellite_source.enabled = true;
style.appliedClasses.insert("satellite");
style->appliedClasses.insert("satellite");
}
}
@@ -451,28 +456,28 @@ void Map::prepare() {
oldState.getFramebufferHeight() != state.getFramebufferHeight();
if (pixelRatioChanged) {
style.sprite = std::make_shared<Sprite>(*this, state.getPixelRatio());
style.sprite->load(kSpriteURL);
style->sprite = std::make_shared<Sprite>(*this, state.getPixelRatio());
style->sprite->load(kSpriteURL);
spriteAtlas.resize(state.getPixelRatio());
spriteAtlas->resize(state.getPixelRatio());
}
if (pixelRatioChanged || dimensionsChanged) {
painter.clearFramebuffers();
}
style.cascade(state.getNormalizedZoom());
style->cascade(state.getNormalizedZoom());
// Update style transitions.
animationTime = util::now();
if (style.needsTransition()) {
style.updateTransitions(animationTime);
if (style->needsTransition()) {
style->updateTransitions(animationTime);
update();
}
// Allow the sprite atlas to potentially pull new sprite images if needed.
if (style.sprite && style.sprite->isLoaded()) {
spriteAtlas.update(*style.sprite);
if (style->sprite && style->sprite->isLoaded()) {
spriteAtlas->update(*style->sprite);
}
updateTiles();
@@ -506,7 +511,7 @@ void Map::render() {
#endif
// Actually render the layers
if (debug::renderTree) { std::cout << "{" << std::endl; indent++; }
renderLayers(style.layers);
renderLayers(style->layers);
if (debug::renderTree) { std::cout << "}" << std::endl; indent--; }
// Finalize the rendering, e.g. by calling debug render calls per tile.
@@ -603,8 +608,8 @@ void Map::renderLayer(const LayerDescription& layer_desc, RenderPass pass) {
if (layer_desc.child_layer.size()) {
// This is a layer group. We render them during our translucent render pass.
if (pass == Translucent) {
auto it = find_style(style.computed.composites, layer_desc);
const CompositeProperties &properties = (it != style.computed.composites.end()) ? it->second : defaultCompositeProperties;
auto it = find_style(style->computed.composites, layer_desc);
const CompositeProperties &properties = (it != style->computed.composites.end()) ? it->second : defaultCompositeProperties;
if (properties.isVisible()) {
gl::group group(std::string("group: ") + layer_desc.name);
@@ -633,31 +638,31 @@ void Map::renderLayer(const LayerDescription& layer_desc, RenderPass pass) {
// This is a singular layer. Try to find the bucket associated with
// this layer and render it.
auto bucket_it = style.buckets.find(layer_desc.bucket_name);
if (bucket_it != style.buckets.end()) {
auto bucket_it = style->buckets.find(layer_desc.bucket_name);
if (bucket_it != style->buckets.end()) {
const BucketDescription &bucket_desc = bucket_it->second;
// Abort early if we can already deduce from the bucket type that
// we're not going to render anything anyway during this pass.
switch (bucket_desc.type) {
case BucketType::Fill:
if (is_invisible(style.computed.fills, layer_desc)) return;
if (is_invisible(style->computed.fills, layer_desc)) return;
break;
case BucketType::Line:
if (pass == Opaque) return;
if (is_invisible(style.computed.lines, layer_desc)) return;
if (is_invisible(style->computed.lines, layer_desc)) return;
break;
case BucketType::Icon:
if (pass == Opaque) return;
if (is_invisible(style.computed.icons, layer_desc)) return;
if (is_invisible(style->computed.icons, layer_desc)) return;
break;
case BucketType::Text:
if (pass == Opaque) return;
if (is_invisible(style.computed.texts, layer_desc)) return;
if (is_invisible(style->computed.texts, layer_desc)) return;
break;
case BucketType::Raster:
if (pass == Translucent) return;
if (is_invisible(style.computed.rasters, layer_desc)) return;
if (is_invisible(style->computed.rasters, layer_desc)) return;
break;
default:
break;

View File

@@ -56,12 +56,23 @@ void TileData::cancel() {
}
}
void TileData::beforeParse() {}
void TileData::reparse() {
beforeParse();
// We're creating a new work request. The work request deletes itself after it executed
// the after work handler
new uv::work<std::shared_ptr<TileData>>(
map.getLoop(),
[](std::shared_ptr<TileData> &tile) { tile->parse(); },
[](std::shared_ptr<TileData> &tile) { tile->map.update(); },
[](std::shared_ptr<TileData> &tile) {
tile->parse();
},
[](std::shared_ptr<TileData> &tile) {
tile->afterParse();
tile->map.update();
},
shared_from_this());
}
void TileData::afterParse() {}

View File

@@ -1,5 +1,6 @@
#include <llmr/map/tile_parser.hpp>
#include <llmr/map/vector_tile_data.hpp>
#include <llmr/style/style.hpp>
#include <llmr/renderer/fill_bucket.hpp>
#include <llmr/renderer/line_bucket.hpp>
@@ -17,7 +18,11 @@
using namespace llmr;
TileParser::TileParser(const std::string& data, VectorTileData& tile, const Style& style, GlyphAtlas& glyphAtlas, GlyphStore &glyphStore, SpriteAtlas &spriteAtlas)
TileParser::TileParser(const std::string &data, VectorTileData &tile,
const std::shared_ptr<const Style> &style,
const std::shared_ptr<GlyphAtlas> &glyphAtlas,
const std::shared_ptr<GlyphStore> &glyphStore,
const std::shared_ptr<SpriteAtlas> &spriteAtlas)
: vector_data(pbf((const uint8_t *)data.data(), data.size())),
tile(tile),
style(style),
@@ -25,14 +30,17 @@ TileParser::TileParser(const std::string& data, VectorTileData& tile, const Styl
glyphStore(glyphStore),
spriteAtlas(spriteAtlas),
placement(tile.id.z) {
parseStyleLayers(style.layers);
}
bool TileParser::obsolete() const {
return tile.state == TileData::State::obsolete;
void TileParser::parse() {
parseStyleLayers(style->layers);
}
void TileParser::addGlyph(uint64_t tileid, const std::string stackname, const std::u32string &string, const FontStack &fontStack, GlyphAtlas &glyphAtlas, GlyphPositions &face) {
bool TileParser::obsolete() const { return tile.state == TileData::State::obsolete; }
void TileParser::addGlyph(uint64_t tileid, const std::string stackname,
const std::u32string &string, const FontStack &fontStack,
GlyphAtlas &glyphAtlas, GlyphPositions &face) {
std::map<uint32_t, SDFGlyph> sdfs = fontStack.getSDFs();
// Loop through all characters and add glyph to atlas, positions.
for (uint32_t chr : string) {
@@ -42,8 +50,8 @@ void TileParser::addGlyph(uint64_t tileid, const std::string stackname, const st
}
}
void TileParser::parseStyleLayers(const std::vector<LayerDescription>& layers) {
for (const LayerDescription& layer_desc : layers) {
void TileParser::parseStyleLayers(const std::vector<LayerDescription> &layers) {
for (const LayerDescription &layer_desc : layers) {
// Cancel early when parsing.
if (obsolete()) {
return;
@@ -59,12 +67,11 @@ void TileParser::parseStyleLayers(const std::vector<LayerDescription>& layers) {
// parse this bucket.
auto bucket_it = tile.buckets.find(layer_desc.bucket_name);
if (bucket_it == tile.buckets.end()) {
auto bucket_it = style.buckets.find(layer_desc.bucket_name);
auto bucket_it = style->buckets.find(layer_desc.bucket_name);
if (layer_desc.bucket_name == "background") {
// background is a special, fake bucket
continue;
}
else if (bucket_it != style.buckets.end()) {
} else if (bucket_it != style->buckets.end()) {
// Only create the new bucket if we have an actual specification
// for it.
std::unique_ptr<Bucket> bucket = createBucket(bucket_it->second);
@@ -86,10 +93,10 @@ void TileParser::parseStyleLayers(const std::vector<LayerDescription>& layers) {
}
}
std::unique_ptr<Bucket> TileParser::createBucket(const BucketDescription& bucket_desc) {
std::unique_ptr<Bucket> TileParser::createBucket(const BucketDescription &bucket_desc) {
auto layer_it = vector_data.layers.find(bucket_desc.source_layer);
if (layer_it != vector_data.layers.end()) {
const VectorTileLayer& layer = layer_it->second;
const VectorTileLayer &layer = layer_it->second;
if (bucket_desc.type == BucketType::Fill) {
return createFillBucket(layer, bucket_desc);
} else if (bucket_desc.type == BucketType::Line) {
@@ -114,10 +121,12 @@ std::unique_ptr<Bucket> TileParser::createBucket(const BucketDescription& bucket
}
template <class Bucket>
void TileParser::addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const BucketDescription& bucket_desc) {
void TileParser::addBucketFeatures(Bucket &bucket, const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
for (pbf feature : filtered_layer) {
if (obsolete()) return;
if (obsolete())
return;
while (feature.next(4)) { // geometry
pbf geometry_pbf = feature.message();
@@ -130,39 +139,45 @@ void TileParser::addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer,
}
}
template <class Bucket, typename ...Args>
void TileParser::addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const BucketDescription& bucket_desc, Args&& ...args) {
template <class Bucket, typename... Args>
void TileParser::addBucketFeatures(Bucket &bucket, const VectorTileLayer &layer,
const BucketDescription &bucket_desc, Args &&... args) {
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
for (const pbf& feature_pbf : filtered_layer) {
if (obsolete()) return;
bucket->addFeature({ feature_pbf, layer }, std::forward<Args>(args)...);
for (const pbf &feature_pbf : filtered_layer) {
if (obsolete())
return;
bucket->addFeature({feature_pbf, layer}, std::forward<Args>(args)...);
}
}
std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) {
std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
std::unique_ptr<FillBucket> bucket = std::make_unique<FillBucket>(
tile.fillVertexBuffer, tile.triangleElementsBuffer, tile.lineElementsBuffer, bucket_desc);
addBucketFeatures(bucket, layer, bucket_desc);
return obsolete() ? nullptr : std::move(bucket);
}
std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) {
std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
std::unique_ptr<LineBucket> bucket = std::make_unique<LineBucket>(
tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer, bucket_desc);
addBucketFeatures(bucket, layer, bucket_desc);
return obsolete() ? nullptr : std::move(bucket);
}
std::unique_ptr<Bucket> TileParser::createIconBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) {
std::unique_ptr<IconBucket> bucket = std::make_unique<IconBucket>(
tile.iconVertexBuffer, bucket_desc);
addBucketFeatures(bucket, layer, bucket_desc, spriteAtlas);
std::unique_ptr<Bucket> TileParser::createIconBucket(const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
std::unique_ptr<IconBucket> bucket =
std::make_unique<IconBucket>(tile.iconVertexBuffer, bucket_desc);
addBucketFeatures(bucket, layer, bucket_desc, *spriteAtlas);
return obsolete() ? nullptr : std::move(bucket);
}
typedef std::pair<uint16_t, uint16_t> GlyphRange;
std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& layer, const BucketDescription& bucket_desc) {
std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer &layer,
const BucketDescription &bucket_desc) {
std::unique_ptr<TextBucket> bucket = std::make_unique<TextBucket>(
tile.textVertexBuffer, tile.triangleElementsBuffer, bucket_desc, placement);
@@ -173,15 +188,18 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& laye
std::set<GlyphRange> ranges;
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
for (const pbf& feature_pbf : filtered_layer) {
if (obsolete()) return nullptr;
VectorTileFeature feature { feature_pbf, layer };
for (const pbf &feature_pbf : filtered_layer) {
if (obsolete())
return nullptr;
VectorTileFeature feature{feature_pbf, layer};
auto it_prop = feature.properties.find(bucket_desc.geometry.field);
if (it_prop == feature.properties.end()) {
// feature does not have the correct property
if (debug::labelTextMissingWarning) {
fprintf(stderr, "[WARNING] feature doesn't have property '%s' required for labelling\n", bucket_desc.geometry.field.c_str());
fprintf(stderr,
"[WARNING] feature doesn't have property '%s' required for labelling\n",
bucket_desc.geometry.field.c_str());
}
continue;
}
@@ -194,25 +212,28 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& laye
}
}
glyphStore.waitForGlyphRanges(bucket_desc.geometry.font, ranges);
glyphStore->waitForGlyphRanges(bucket_desc.geometry.font, ranges);
}
// Create a copy!
const FontStack &fontStack = glyphStore.getFontStack(bucket_desc.geometry.font);
const FontStack &fontStack = glyphStore->getFontStack(bucket_desc.geometry.font);
GlyphPositions face;
// Shape and place all labels.
{
FilteredVectorTileLayer filtered_layer(layer, bucket_desc);
for (const pbf& feature_pbf : filtered_layer) {
if (obsolete()) return nullptr;
VectorTileFeature feature { feature_pbf, layer };
for (const pbf &feature_pbf : filtered_layer) {
if (obsolete())
return nullptr;
VectorTileFeature feature{feature_pbf, layer};
auto it_prop = feature.properties.find(bucket_desc.geometry.field);
if (it_prop == feature.properties.end()) {
// feature does not have the correct property
if (debug::labelTextMissingWarning) {
fprintf(stderr, "[WARNING] feature doesn't have property '%s' required for labelling\n", bucket_desc.geometry.field.c_str());
fprintf(stderr,
"[WARNING] feature doesn't have property '%s' required for labelling\n",
bucket_desc.geometry.field.c_str());
}
continue;
}
@@ -224,7 +245,8 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& laye
const Shaping shaping = fontStack.getShaping(string);
// Place labels.
addGlyph(tile.id.to_uint64(), bucket_desc.geometry.font, string, fontStack, glyphAtlas, face);
addGlyph(tile.id.to_uint64(), bucket_desc.geometry.font, string, fontStack, *glyphAtlas,
face);
bucket->addFeature(feature.geometry, face, shaping);
}
@@ -232,4 +254,3 @@ std::unique_ptr<Bucket> TileParser::createTextBucket(const VectorTileLayer& laye
return std::move(bucket);
}

View File

@@ -1,7 +1,6 @@
#include <llmr/map/vector_tile_data.hpp>
#include <llmr/util/std.hpp>
#include <llmr/map/map.hpp>
#include <llmr/map/tile_parser.hpp>
using namespace llmr;
@@ -10,7 +9,11 @@ VectorTileData::VectorTileData(Tile::ID id, Map &map, const std::string url)
}
VectorTileData::~VectorTileData() {
map.getGlyphAtlas().removeGlyphs(id.to_uint64());
map.getGlyphAtlas()->removeGlyphs(id.to_uint64());
}
void VectorTileData::beforeParse() {
parser = std::make_unique<TileParser>(data, *this, map.getStyle(), map.getGlyphAtlas(), map.getGlyphStore(), map.getSpriteAtlas());
}
void VectorTileData::parse() {
@@ -22,7 +25,7 @@ void VectorTileData::parse() {
// Parsing creates state that is encapsulated in TileParser. While parsing,
// the TileParser object writes results into this objects. All other state
// is going to be discarded afterwards.
TileParser parser(data, *this, map.getStyle(), map.getGlyphAtlas(), map.getGlyphStore(), map.getSpriteAtlas());
parser->parse();
} catch (const std::exception& ex) {
#if defined(DEBUG)
fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what());
@@ -36,6 +39,10 @@ void VectorTileData::parse() {
}
}
void VectorTileData::afterParse() {
parser.reset();
}
void VectorTileData::render(Painter &painter, const LayerDescription& layer_desc) {
auto databucket_it = buckets.find(layer_desc.bucket_name);
if (databucket_it != buckets.end()) {

View File

@@ -15,11 +15,13 @@ void Painter::drawClippingMasks(const Sources &sources) {
glDepthRange(1.0f, 1.0f);
glStencilMask(0xFF);
Color background = map.getStyle().computed.background.color;
background[0] *= map.getStyle().computed.background.opacity;
background[1] *= map.getStyle().computed.background.opacity;
background[2] *= map.getStyle().computed.background.opacity;
background[3] *= map.getStyle().computed.background.opacity;
const BackgroundProperties &properties = map.getStyle()->computed.background;
Color background = properties.color;
const float opacity = properties.opacity;
background[0] *= opacity;
background[1] *= opacity;
background[2] *= opacity;
background[3] *= opacity;
plainShader->setColor(background);
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));

View File

@@ -65,9 +65,9 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c
}
if ((fill_color[3] >= 1.0f) == (pass == Opaque)) {
auto &sprite = map.getStyle().sprite;
const std::shared_ptr<Sprite> &sprite = map.getStyle()->sprite;
if (properties.image.size() && sprite) {
auto &spriteAtlas = map.getSpriteAtlas();
SpriteAtlas &spriteAtlas = *map.getSpriteAtlas();
Rect<uint16_t> imagePos = spriteAtlas.getImage(properties.image, *sprite);
@@ -144,7 +144,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
// Abort early.
if (!bucket.hasData()) return;
const std::unordered_map<std::string, FillProperties> &fill_properties = map.getStyle().computed.fills;
const std::unordered_map<std::string, FillProperties> &fill_properties = map.getStyle()->computed.fills;
const std::unordered_map<std::string, FillProperties>::const_iterator fill_properties_it = fill_properties.find(layer_name);
const FillProperties &properties = fill_properties_it != fill_properties.end()

View File

@@ -11,7 +11,7 @@ void Painter::renderIcon(IconBucket& bucket, const std::string& layer_name, cons
if (!bucket.hasData()) return;
if (pass == Opaque) return;
const std::unordered_map<std::string, IconProperties> &icon_properties = map.getStyle().computed.icons;
const std::unordered_map<std::string, IconProperties> &icon_properties = map.getStyle()->computed.icons;
const std::unordered_map<std::string, IconProperties>::const_iterator icon_properties_it = icon_properties.find(layer_name);
const IconProperties &properties = icon_properties_it != icon_properties.end()
@@ -27,7 +27,7 @@ void Painter::renderIcon(IconBucket& bucket, const std::string& layer_name, cons
const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor);
SpriteAtlas &spriteAtlas = map.getSpriteAtlas();
SpriteAtlas &spriteAtlas = *map.getSpriteAtlas();
useProgram(iconShader->program);
iconShader->setMatrix(vtxMatrix);

View File

@@ -9,7 +9,7 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
if (pass == Opaque) return;
if (!bucket.hasData()) return;
const std::unordered_map<std::string, LineProperties> &line_properties = map.getStyle().computed.lines;
const std::unordered_map<std::string, LineProperties> &line_properties = map.getStyle()->computed.lines;
const std::unordered_map<std::string, LineProperties>::const_iterator line_properties_it = line_properties.find(layer_name);
const LineProperties &properties = line_properties_it != line_properties.end()

View File

@@ -7,7 +7,7 @@ using namespace llmr;
void Painter::renderRaster(RasterBucket& bucket, const std::string& layer_name, const Tile::ID& /*id*/) {
if (pass == Translucent) return;
const std::unordered_map<std::string, RasterProperties> &raster_properties = map.getStyle().computed.rasters;
const std::unordered_map<std::string, RasterProperties> &raster_properties = map.getStyle()->computed.rasters;
const std::unordered_map<std::string, RasterProperties>::const_iterator raster_properties_it = raster_properties.find(layer_name);
const RasterProperties &properties = raster_properties_it != raster_properties.end()

View File

@@ -10,7 +10,7 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
if (pass == Opaque) return;
if (!bucket.hasData()) return;
const std::unordered_map<std::string, TextProperties> &text_properties = map.getStyle().computed.texts;
const std::unordered_map<std::string, TextProperties> &text_properties = map.getStyle()->computed.texts;
const std::unordered_map<std::string, TextProperties>::const_iterator text_properties_it = text_properties.find(layer_name);
const TextProperties &properties = text_properties_it != text_properties.end()
@@ -39,9 +39,10 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
textShader->setMatrix(vtxMatrix);
textShader->setExtrudeMatrix(exMatrix);
map.getGlyphAtlas().bind();
textShader->setTextureSize({{static_cast<float>(map.getGlyphAtlas().width),
static_cast<float>(map.getGlyphAtlas().height)}});
GlyphAtlas &glyphAtlas = *map.getGlyphAtlas();
glyphAtlas.bind();
textShader->setTextureSize({{static_cast<float>(glyphAtlas.width),
static_cast<float>(glyphAtlas.height)}});
// Convert the -pi..pi to an int8 range.
float angle = std::round((map.getState().getAngle() + rotate) / M_PI * 128);

View File

@@ -3,7 +3,7 @@
using namespace llmr;
RasterBucket::RasterBucket(Texturepool &texturepool)
RasterBucket::RasterBucket(const std::shared_ptr<Texturepool> &texturepool)
: raster(texturepool) {
}

View File

@@ -14,13 +14,13 @@
using namespace llmr;
Raster::Raster(Texturepool &texturepool)
Raster::Raster(const std::shared_ptr<Texturepool> &texturepool)
: texturepool(texturepool)
{}
Raster::~Raster() {
if (textured) {
texturepool.removeTextureID(texture);
texturepool->removeTextureID(texture);
}
}
@@ -49,7 +49,7 @@ void Raster::bind(bool linear) {
}
if (img && !textured) {
texture = texturepool.getTextureID();
texture = texturepool->getTextureID();
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);