diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-03-08 17:18:57 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2016-05-10 14:50:56 +0200 |
commit | dde59eaf769dc2d503e8bd4ca79d0923ad877e13 (patch) | |
tree | 1743d0a0d7c50fbc2c686c6e02de838aa69dbb96 /src | |
parent | 5b640fb446693c42086489cdaa3066eb172609e6 (diff) | |
download | qtlocation-mapboxgl-dde59eaf769dc2d503e8bd4ca79d0923ad877e13.tar.gz |
[core] move Painter and dependents to new *TileID classes
Diffstat (limited to 'src')
28 files changed, 140 insertions, 260 deletions
diff --git a/src/mbgl/algorithm/generate_clip_ids.cpp b/src/mbgl/algorithm/generate_clip_ids.cpp index 369cb35de1..208db797d0 100644 --- a/src/mbgl/algorithm/generate_clip_ids.cpp +++ b/src/mbgl/algorithm/generate_clip_ids.cpp @@ -32,9 +32,6 @@ bool ClipIDGenerator::Leaf::operator==(const Leaf& other) const { return children == other.children; } -// Instantiate the function for Tile& refs. -template void ClipIDGenerator::update(std::map<UnwrappedTileID, Tile&>&); - std::map<UnwrappedTileID, ClipID> ClipIDGenerator::getStencils() const { std::map<UnwrappedTileID, ClipID> stencils; diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index 4c96abcd13..2813d6334e 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -1,5 +1,5 @@ #include <mbgl/map/transform_state.hpp> -#include <mbgl/map/tile_id.hpp> +#include <mbgl/tile/tile_id.hpp> #include <mbgl/util/constants.hpp> #include <mbgl/util/interpolate.hpp> #include <mbgl/util/math.hpp> @@ -14,12 +14,14 @@ TransformState::TransformState(ConstrainMode constrainMode_) #pragma mark - Matrix -void TransformState::matrixFor(mat4& matrix, const TileID& id, const int8_t z) const { - const double tile_scale = std::pow(2, z); - double s = worldSize() / tile_scale; +void TransformState::matrixFor(mat4& matrix, const UnwrappedTileID& tileID) const { + const uint64_t tileScale = 1ull << tileID.canonical.z; + const double s = worldSize() / tileScale; matrix::identity(matrix); - matrix::translate(matrix, matrix, id.x * s, id.y * s, 0); + matrix::translate(matrix, matrix, + static_cast<int64_t>(tileID.canonical.x + tileID.wrap * tileScale) * s, + static_cast<int64_t>(tileID.canonical.y) * s, 0); matrix::scale(matrix, matrix, s / util::EXTENT, s / util::EXTENT, 1); } diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp index 37b52f9606..b9acad66f1 100644 --- a/src/mbgl/map/transform_state.hpp +++ b/src/mbgl/map/transform_state.hpp @@ -12,7 +12,7 @@ namespace mbgl { -class TileID; +class UnwrappedTileID; class TransformState { friend class Transform; @@ -21,7 +21,7 @@ public: TransformState(ConstrainMode = ConstrainMode::HeightOnly); // Matrix - void matrixFor(mat4& matrix, const TileID& id, const int8_t z) const; + void matrixFor(mat4&, const UnwrappedTileID&) const; void getProjMatrix(mat4& matrix) const; // Dimensions diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp index 4212e7c30e..0a4853ad9e 100644 --- a/src/mbgl/renderer/bucket.hpp +++ b/src/mbgl/renderer/bucket.hpp @@ -15,7 +15,7 @@ namespace mbgl { class Painter; class StyleLayer; -class TileID; +class UnwrappedTileID; class CollisionTile; namespace gl { @@ -32,7 +32,7 @@ public: // Every time this bucket is getting rendered, this function is called. This happens either // once or twice (for Opaque and Transparent render passes). - virtual void render(Painter&, const StyleLayer&, const TileID&, const mat4&) = 0; + virtual void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) = 0; virtual ~Bucket() = default; diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp index 4c94bfa0d0..19ebf8e78b 100644 --- a/src/mbgl/renderer/circle_bucket.cpp +++ b/src/mbgl/renderer/circle_bucket.cpp @@ -22,9 +22,9 @@ void CircleBucket::upload(gl::GLObjectStore& glObjectStore) { void CircleBucket::render(Painter& painter, const StyleLayer& layer, - const TileID& id, + const UnwrappedTileID& tileID, const mat4& matrix) { - painter.renderCircle(*this, *layer.as<CircleLayer>(), id, matrix); + painter.renderCircle(*this, *layer.as<CircleLayer>(), tileID, matrix); } bool CircleBucket::hasData() const { diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index defa7b069f..abfca851ef 100644 --- a/src/mbgl/renderer/circle_bucket.hpp +++ b/src/mbgl/renderer/circle_bucket.hpp @@ -20,7 +20,7 @@ public: ~CircleBucket() override; void upload(gl::GLObjectStore&) override; - void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; + void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool needsClipping() const override; diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index 48d9ae88aa..b0f391323c 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -198,9 +198,9 @@ void FillBucket::upload(gl::GLObjectStore& glObjectStore) { void FillBucket::render(Painter& painter, const StyleLayer& layer, - const TileID& id, + const UnwrappedTileID& tileID, const mat4& matrix) { - painter.renderFill(*this, *layer.as<FillLayer>(), id, matrix); + painter.renderFill(*this, *layer.as<FillLayer>(), tileID, matrix); } bool FillBucket::hasData() const { diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index bd6a9a9cf4..aefb178c47 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -34,7 +34,7 @@ public: ~FillBucket() override; void upload(gl::GLObjectStore&) override; - void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; + void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool needsClipping() const override; diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index fdbb291457..5bbf1916bb 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -445,9 +445,9 @@ void LineBucket::upload(gl::GLObjectStore& glObjectStore) { void LineBucket::render(Painter& painter, const StyleLayer& layer, - const TileID& id, + const UnwrappedTileID& tileID, const mat4& matrix) { - painter.renderLine(*this, *layer.as<LineLayer>(), id, matrix); + painter.renderLine(*this, *layer.as<LineLayer>(), tileID, matrix); } bool LineBucket::hasData() const { diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 9c7ec3d93e..87d95586ca 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -27,7 +27,7 @@ public: ~LineBucket() override; void upload(gl::GLObjectStore&) override; - void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; + void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool needsClipping() const override; diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 1fbce82c03..92ea94ba4b 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -31,6 +31,9 @@ #include <mbgl/shader/box_shader.hpp> #include <mbgl/shader/circle_shader.hpp> +#include <mbgl/algorithm/generate_clip_ids.hpp> +#include <mbgl/algorithm/generate_clip_ids_impl.hpp> + #include <mbgl/util/constants.hpp> #if defined(DEBUG) @@ -144,11 +147,12 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a MBGL_DEBUG_GROUP("clip"); // Update all clipping IDs. - ClipIDGenerator generator; + algorithm::ClipIDGenerator generator; for (const auto& source : sources) { if (source->type == SourceType::Vector || source->type == SourceType::GeoJSON || source->type == SourceType::Annotations) { - generator.update(source->getLoadedTiles()); + auto renderables = source->getRenderables(); + generator.update(renderables); } source->updateMatrices(projMatrix, state); } @@ -251,7 +255,8 @@ void Painter::renderPass(RenderPass pass_, if (item.bucket->needsClipping()) { setClipping(item.tile->clip); } - item.bucket->render(*this, layer, item.tile->id, item.tile->matrix); + const UnwrappedTileID tileID{ item.tile->id.sourceZ, item.tile->id.x, item.tile->id.y }; + item.bucket->render(*this, layer, tileID, item.tile->matrix); } } @@ -260,11 +265,13 @@ void Painter::renderPass(RenderPass pass_, } } -mat4 Painter::translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const TileID &id, TranslateAnchorType anchor) { +mat4 Painter::translatedMatrix(const mat4& matrix, + const std::array<float, 2>& translation, + const UnwrappedTileID& id, + TranslateAnchorType anchor) { if (translation[0] == 0 && translation[1] == 0) { return matrix; } else { - mat4 vtxMatrix; if (anchor == TranslateAnchorType::Viewport) { const double sin_a = std::sin(-state.getAngle()); diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 2fa5c02604..0fe623a91d 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -3,6 +3,8 @@ #include <mbgl/map/transform_state.hpp> +#include <mbgl/tile/tile_id.hpp> + #include <mbgl/renderer/frame_history.hpp> #include <mbgl/renderer/bucket.hpp> @@ -98,23 +100,26 @@ public: void renderDebugFrame(const mat4 &matrix); void renderDebugText(TileData&, const mat4&); - void renderFill(FillBucket&, const FillLayer&, const TileID&, const mat4&); - void renderLine(LineBucket&, const LineLayer&, const TileID&, const mat4&); - void renderCircle(CircleBucket&, const CircleLayer&, const TileID&, const mat4&); - void renderSymbol(SymbolBucket&, const SymbolLayer&, const TileID&, const mat4&); - void renderRaster(RasterBucket&, const RasterLayer&, const TileID&, const mat4&); + void renderFill(FillBucket&, const FillLayer&, const UnwrappedTileID&, const mat4&); + void renderLine(LineBucket&, const LineLayer&, const UnwrappedTileID&, const mat4&); + void renderCircle(CircleBucket&, const CircleLayer&, const UnwrappedTileID&, const mat4&); + void renderSymbol(SymbolBucket&, const SymbolLayer&, const UnwrappedTileID&, const mat4&); + void renderRaster(RasterBucket&, const RasterLayer&, const UnwrappedTileID&, const mat4&); void renderBackground(const BackgroundLayer&); float saturationFactor(float saturation); float contrastFactor(float contrast); std::array<float, 3> spinWeights(float spin_value); - void drawClippingMasks(const std::map<TileID, ClipID>&); + void drawClippingMasks(const std::map<UnwrappedTileID, ClipID>&); bool needsAnimation() const; private: - mat4 translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const TileID &id, TranslateAnchorType anchor); + mat4 translatedMatrix(const mat4& matrix, + const std::array<float, 2>& translation, + const UnwrappedTileID& id, + TranslateAnchorType anchor); std::vector<RenderItem> determineRenderOrder(const Style& style); @@ -126,7 +131,7 @@ private: void setClipping(const ClipID&); void renderSDF(SymbolBucket &bucket, - const TileID &id, + const UnwrappedTileID &tileID, const mat4 &matrixSymbol, float scaleDivisor, std::array<float, 2> texsize, diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index dddc755542..658d6535f6 100644 --- a/src/mbgl/renderer/painter_background.cpp +++ b/src/mbgl/renderer/painter_background.cpp @@ -59,7 +59,8 @@ void Painter::renderBackground(const BackgroundLayer& layer) { for (auto &id: tileIDs) { mat4 vtxMatrix; - state.matrixFor(vtxMatrix, id, id.z); + const UnwrappedTileID tileID(id.z, id.x, id.y); + state.matrixFor(vtxMatrix, tileID); matrix::multiply(vtxMatrix, projMatrix, vtxMatrix); if (isPatterned) { diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp index 8e601ea7ee..8711e2c48b 100644 --- a/src/mbgl/renderer/painter_circle.cpp +++ b/src/mbgl/renderer/painter_circle.cpp @@ -11,7 +11,7 @@ using namespace mbgl; void Painter::renderCircle(CircleBucket& bucket, const CircleLayer& layer, - const TileID& id, + const UnwrappedTileID& tileID, const mat4& matrix) { // Abort early. if (pass == RenderPass::Opaque) return; @@ -23,7 +23,8 @@ void Painter::renderCircle(CircleBucket& bucket, setDepthSublayer(0); const CirclePaintProperties& properties = layer.paint; - mat4 vtxMatrix = translatedMatrix(matrix, properties.circleTranslate, id, properties.circleTranslateAnchor); + mat4 vtxMatrix = translatedMatrix(matrix, properties.circleTranslate, tileID, + properties.circleTranslateAnchor); Color color = properties.circleColor; color[0] *= properties.circleOpacity; diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp index aed4c45869..37e06922c1 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -2,12 +2,13 @@ #include <mbgl/source/source.hpp> #include <mbgl/shader/plain_shader.hpp> #include <mbgl/util/clip_id.hpp> +#include <mbgl/util/string.hpp> #include <mbgl/gl/debugging.hpp> using namespace mbgl; -void Painter::drawClippingMasks(const std::map<TileID, ClipID>& stencils) { +void Painter::drawClippingMasks(const std::map<UnwrappedTileID, ClipID>& stencils) { MBGL_DEBUG_GROUP("clipping masks"); mat4 matrix; @@ -27,8 +28,8 @@ void Painter::drawClippingMasks(const std::map<TileID, ClipID>& stencils) { const auto& id = stencil.first; const auto& clip = stencil.second; - MBGL_DEBUG_GROUP(std::string{ "mask: " } + std::string(id)); - state.matrixFor(matrix, id, id.z); + MBGL_DEBUG_GROUP(std::string{ "mask: " } + util::toString(id)); + state.matrixFor(matrix, id); matrix::multiply(matrix, projMatrix, matrix); plainShader->u_matrix = matrix; diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp index 0808cd2ac1..6c23608c18 100644 --- a/src/mbgl/renderer/painter_fill.cpp +++ b/src/mbgl/renderer/painter_fill.cpp @@ -10,9 +10,13 @@ using namespace mbgl; -void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileID& id, const mat4& matrix) { +void Painter::renderFill(FillBucket& bucket, + const FillLayer& layer, + const UnwrappedTileID& tileID, + const mat4& matrix) { const FillPaintProperties& properties = layer.paint; - mat4 vtxMatrix = translatedMatrix(matrix, properties.fillTranslate, id, properties.fillTranslateAnchor); + mat4 vtxMatrix = + translatedMatrix(matrix, properties.fillTranslate, tileID, properties.fillTranslateAnchor); Color fill_color = properties.fillColor; fill_color[0] *= properties.fillOpacity; @@ -65,7 +69,6 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI // Image fill. if (pass == RenderPass::Translucent && posA && posB) { - config.program = patternShader->getID(); patternShader->u_matrix = vtxMatrix; patternShader->u_pattern_tl_a = (*posA).tl; @@ -85,20 +88,24 @@ void Painter::renderFill(FillBucket& bucket, const FillLayer& layer, const TileI (int)((*posB).size[1] * properties.fillPattern.value.toScale) }}; - patternShader->u_patternscale_a = {{ - 1.0f / id.pixelsToTileUnits(imageSizeScaledA[0], state.getIntegerZoom()), - 1.0f / id.pixelsToTileUnits(imageSizeScaledB[1], state.getIntegerZoom()) - }}; - patternShader->u_patternscale_b = {{ - 1.0f / id.pixelsToTileUnits(imageSizeScaledB[0], state.getIntegerZoom()), - 1.0f / id.pixelsToTileUnits(imageSizeScaledB[1], state.getIntegerZoom()) - }}; - - float offsetAx = (std::fmod(util::tileSize, imageSizeScaledA[0]) * id.x) / (float)imageSizeScaledA[0]; - float offsetAy = (std::fmod(util::tileSize, imageSizeScaledA[1]) * id.y) / (float)imageSizeScaledA[1]; - - float offsetBx = (std::fmod(util::tileSize, imageSizeScaledB[0]) * id.x) / (float)imageSizeScaledB[0]; - float offsetBy = (std::fmod(util::tileSize, imageSizeScaledB[1]) * id.y) / (float)imageSizeScaledB[1]; + patternShader->u_patternscale_a = { + { 1.0f / tileID.pixelsToTileUnits(imageSizeScaledA[0], state.getIntegerZoom()), + 1.0f / tileID.pixelsToTileUnits(imageSizeScaledB[1], state.getIntegerZoom()) } + }; + patternShader->u_patternscale_b = { + { 1.0f / tileID.pixelsToTileUnits(imageSizeScaledB[0], state.getIntegerZoom()), + 1.0f / tileID.pixelsToTileUnits(imageSizeScaledB[1], state.getIntegerZoom()) } + }; + + float offsetAx = (std::fmod(util::tileSize, imageSizeScaledA[0]) * tileID.canonical.x) / + (float)imageSizeScaledA[0]; + float offsetAy = (std::fmod(util::tileSize, imageSizeScaledA[1]) * tileID.canonical.y) / + (float)imageSizeScaledA[1]; + + float offsetBx = (std::fmod(util::tileSize, imageSizeScaledB[0]) * tileID.canonical.x) / + (float)imageSizeScaledB[0]; + float offsetBy = (std::fmod(util::tileSize, imageSizeScaledB[1]) * tileID.canonical.y) / + (float)imageSizeScaledB[1]; patternShader->u_offset_a = std::array<float, 2>{{offsetAx, offsetAy}}; patternShader->u_offset_b = std::array<float, 2>{{offsetBx, offsetBy}}; diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 80caf9a18c..bc6c51c226 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -11,7 +11,10 @@ using namespace mbgl; -void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileID& id, const mat4& matrix) { +void Painter::renderLine(LineBucket& bucket, + const LineLayer& layer, + const UnwrappedTileID& tileID, + const mat4& matrix) { // Abort early. if (pass == RenderPass::Opaque) return; @@ -50,7 +53,7 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI color[2] *= properties.lineOpacity; color[3] *= properties.lineOpacity; - const float ratio = 1.0 / id.pixelsToTileUnits(1.0, state.getZoom()); + const float ratio = 1.0 / tileID.pixelsToTileUnits(1.0, state.getZoom()); mat2 antialiasingMatrix; matrix::identity(antialiasingMatrix); @@ -63,7 +66,8 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI float x = state.getHeight() / 2.0f * std::tan(state.getPitch()); float extra = (topedgelength + x) / topedgelength - 1; - mat4 vtxMatrix = translatedMatrix(matrix, properties.lineTranslate, id, properties.lineTranslateAnchor); + mat4 vtxMatrix = + translatedMatrix(matrix, properties.lineTranslate, tileID, properties.lineTranslateAnchor); setDepthSublayer(0); @@ -84,9 +88,9 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI const float widthA = posA.width * properties.lineDasharray.value.fromScale * layer.dashLineWidth; const float widthB = posB.width * properties.lineDasharray.value.toScale * layer.dashLineWidth; - float scaleXA = 1.0 / id.pixelsToTileUnits(widthA, state.getIntegerZoom()); + float scaleXA = 1.0 / tileID.pixelsToTileUnits(widthA, state.getIntegerZoom()); float scaleYA = -posA.height / 2.0; - float scaleXB = 1.0 / id.pixelsToTileUnits(widthB, state.getIntegerZoom()); + float scaleXB = 1.0 / tileID.pixelsToTileUnits(widthB, state.getIntegerZoom()); float scaleYB = -posB.height / 2.0; linesdfShader->u_patternscale_a = {{ scaleXA, scaleYA }}; @@ -121,14 +125,14 @@ void Painter::renderLine(LineBucket& bucket, const LineLayer& layer, const TileI linepatternShader->u_blur = blur; linepatternShader->u_pattern_size_a = {{ - id.pixelsToTileUnits((*imagePosA).size[0] * properties.linePattern.value.fromScale, state.getIntegerZoom()), + tileID.pixelsToTileUnits((*imagePosA).size[0] * properties.linePattern.value.fromScale, state.getIntegerZoom()), (*imagePosA).size[1] }}; linepatternShader->u_pattern_tl_a = (*imagePosA).tl; linepatternShader->u_pattern_br_a = (*imagePosA).br; linepatternShader->u_pattern_size_b = {{ - id.pixelsToTileUnits((*imagePosB).size[0] * properties.linePattern.value.toScale, state.getIntegerZoom()), + tileID.pixelsToTileUnits((*imagePosB).size[0] * properties.linePattern.value.toScale, state.getIntegerZoom()), (*imagePosB).size[1] }}; linepatternShader->u_pattern_tl_b = (*imagePosB).tl; diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp index 39e0b5f195..f00f2ebcbd 100644 --- a/src/mbgl/renderer/painter_raster.cpp +++ b/src/mbgl/renderer/painter_raster.cpp @@ -6,7 +6,10 @@ using namespace mbgl; -void Painter::renderRaster(RasterBucket& bucket, const RasterLayer& layer, const TileID&, const mat4& matrix) { +void Painter::renderRaster(RasterBucket& bucket, + const RasterLayer& layer, + const UnwrappedTileID&, + const mat4& matrix) { if (pass != RenderPass::Translucent) return; const RasterPaintProperties& properties = layer.paint; diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 1aecbcb50b..6321d03a9a 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -14,7 +14,7 @@ using namespace mbgl; void Painter::renderSDF(SymbolBucket &bucket, - const TileID &id, + const UnwrappedTileID &tileID, const mat4 &matrix, float sdfFontSize, std::array<float, 2> texsize, @@ -35,7 +35,7 @@ void Painter::renderSDF(SymbolBucket &bucket, TranslateAnchorType translateAnchor, float paintSize) { - mat4 vtxMatrix = translatedMatrix(matrix, translate, id, translateAnchor); + mat4 vtxMatrix = translatedMatrix(matrix, translate, tileID, translateAnchor); bool skewed = rotationAlignment == RotationAlignmentType::Map; mat4 exMatrix; @@ -44,7 +44,7 @@ void Painter::renderSDF(SymbolBucket &bucket, if (skewed) { matrix::identity(exMatrix); - s = id.pixelsToTileUnits(1, state.getZoom()); + s = tileID.pixelsToTileUnits(1, state.getZoom()); gammaScale = 1.0f / std::cos(state.getPitch()); } else { exMatrix = extrudeMatrix; @@ -130,7 +130,10 @@ void Painter::renderSDF(SymbolBucket &bucket, } } -void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const TileID& id, const mat4& matrix) { +void Painter::renderSymbol(SymbolBucket& bucket, + const SymbolLayer& layer, + const UnwrappedTileID& tileID, + const mat4& matrix) { // Abort early. if (pass == RenderPass::Opaque) { return; @@ -183,7 +186,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const if (sdf) { renderSDF(bucket, - id, + tileID, matrix, 1.0f, {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }}, @@ -200,7 +203,8 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const paint.iconTranslateAnchor, layer.iconSize); } else { - mat4 vtxMatrix = translatedMatrix(matrix, paint.iconTranslate, id, paint.iconTranslateAnchor); + mat4 vtxMatrix = + translatedMatrix(matrix, paint.iconTranslate, tileID, paint.iconTranslateAnchor); bool skewed = layout.iconRotationAlignment == RotationAlignmentType::Map; mat4 exMatrix; @@ -208,7 +212,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const if (skewed) { matrix::identity(exMatrix); - s = id.pixelsToTileUnits(1, state.getZoom()); + s = tileID.pixelsToTileUnits(1, state.getZoom()); } else { exMatrix = extrudeMatrix; matrix::rotate_z(exMatrix, exMatrix, state.getNorthOrientationAngle()); @@ -259,7 +263,7 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const glyphAtlas->bind(glObjectStore); renderSDF(bucket, - id, + tileID, matrix, 24.0f, {{ float(glyphAtlas->width) / 4, float(glyphAtlas->height) / 4 }}, @@ -283,9 +287,10 @@ void Painter::renderSymbol(SymbolBucket& bucket, const SymbolLayer& layer, const config.program = collisionBoxShader->getID(); collisionBoxShader->u_matrix = matrix; - collisionBoxShader->u_scale = std::pow(2, state.getZoom() - id.z); + // TODO: This was the overscaled z instead of the canonical z. + collisionBoxShader->u_scale = std::pow(2, state.getZoom() - tileID.canonical.z); collisionBoxShader->u_zoom = state.getZoom() * 10; - collisionBoxShader->u_maxzoom = (id.z + 1) * 10; + collisionBoxShader->u_maxzoom = (tileID.canonical.z + 1) * 10; config.lineWidth = 1.0f; setDepthSublayer(0); diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp index 74f48e2069..18c18923f6 100644 --- a/src/mbgl/renderer/raster_bucket.cpp +++ b/src/mbgl/renderer/raster_bucket.cpp @@ -18,9 +18,9 @@ void RasterBucket::upload(gl::GLObjectStore& glObjectStore) { void RasterBucket::render(Painter& painter, const StyleLayer& layer, - const TileID& id, + const UnwrappedTileID& tileID, const mat4& matrix) { - painter.renderRaster(*this, *layer.as<RasterLayer>(), id, matrix); + painter.renderRaster(*this, *layer.as<RasterLayer>(), tileID, matrix); } void RasterBucket::setImage(PremultipliedImage image) { diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp index 744cb4c297..6fe21f3e91 100644 --- a/src/mbgl/renderer/raster_bucket.hpp +++ b/src/mbgl/renderer/raster_bucket.hpp @@ -15,7 +15,7 @@ public: RasterBucket(gl::TexturePool&); void upload(gl::GLObjectStore&) override; - void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; + void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool needsClipping() const override; diff --git a/src/mbgl/renderer/renderable.hpp b/src/mbgl/renderer/renderable.hpp new file mode 100644 index 0000000000..3d46fbd0bf --- /dev/null +++ b/src/mbgl/renderer/renderable.hpp @@ -0,0 +1,14 @@ +#ifndef MBGL_RENDERER_RENDERABLE +#define MBGL_RENDERER_RENDERABLE + +#include <mbgl/util/clip_id.hpp> + +namespace mbgl { + +struct Renderable { + ClipID& clip; +}; + +} // namespace mbgl + +#endif diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index b0930890d4..a183032761 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -87,9 +87,9 @@ void SymbolBucket::upload(gl::GLObjectStore& glObjectStore) { void SymbolBucket::render(Painter& painter, const StyleLayer& layer, - const TileID& id, + const UnwrappedTileID& tileID, const mat4& matrix) { - painter.renderSymbol(*this, *layer.as<SymbolLayer>(), id, matrix); + painter.renderSymbol(*this, *layer.as<SymbolLayer>(), tileID, matrix); } bool SymbolBucket::hasData() const { return hasTextData() || hasIconData() || !symbolInstances.empty(); } diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index e212f56162..8581a23574 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -72,7 +72,7 @@ public: ~SymbolBucket() override; void upload(gl::GLObjectStore&) override; - void render(Painter&, const StyleLayer&, const TileID&, const mat4&) override; + void render(Painter&, const StyleLayer&, const UnwrappedTileID&, const mat4&) override; bool hasData() const override; bool hasTextData() const; bool hasIconData() const; diff --git a/src/mbgl/source/source.cpp b/src/mbgl/source/source.cpp index b2729593c6..1a961ac0c4 100644 --- a/src/mbgl/source/source.cpp +++ b/src/mbgl/source/source.cpp @@ -162,8 +162,8 @@ void Source::load(FileSource& fileSource) { void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transform) { for (const auto& pair : tiles) { - Tile &tile = *pair.second; - transform.matrixFor(tile.matrix, tile.id, std::min(static_cast<uint8_t>(info->maxZoom), tile.id.z)); + auto& tile = *pair.second; + transform.matrixFor(tile.matrix, UnwrappedTileID{ tile.id.sourceZ, tile.id.x, tile.id.y }); matrix::multiply(tile.matrix, projMatrix, tile.matrix); } } @@ -175,16 +175,16 @@ void Source::finishRender(Painter &painter) { } } -std::forward_list<Tile*> Source::getLoadedTiles() const { - std::forward_list<Tile*> ptrs; - auto it = ptrs.before_begin(); +std::map<UnwrappedTileID, Renderable> Source::getRenderables() const { + std::map<UnwrappedTileID, Renderable> renderables; for (const auto& pair : tiles) { - auto tile = pair.second.get(); - if (tile->data->isReady() && tile->data->hasData()) { - it = ptrs.insert_after(it, tile); + auto& tile = *pair.second; + if (tile.data->isReady() && tile.data->hasData()) { + renderables.emplace(UnwrappedTileID{ tile.id.sourceZ, tile.id.x, tile.id.y }, + Renderable{ tile.clip }); } } - return ptrs; + return renderables; } const std::vector<Tile*>& Source::getTiles() const { diff --git a/src/mbgl/source/source.hpp b/src/mbgl/source/source.hpp index cc579e11e7..5084f77edf 100644 --- a/src/mbgl/source/source.hpp +++ b/src/mbgl/source/source.hpp @@ -1,9 +1,11 @@ #ifndef MBGL_MAP_SOURCE #define MBGL_MAP_SOURCE +#include <mbgl/tile/tile_id.hpp> #include <mbgl/tile/tile_data.hpp> #include <mbgl/tile/tile_cache.hpp> #include <mbgl/source/source_info.hpp> +#include <mbgl/renderer/renderable.hpp> #include <mbgl/util/mat4.hpp> #include <mbgl/util/rapidjson.hpp> @@ -70,7 +72,7 @@ public: void updateMatrices(const mat4 &projMatrix, const TransformState &transform); void finishRender(Painter &painter); - std::forward_list<Tile *> getLoadedTiles() const; + std::map<UnwrappedTileID, Renderable> getRenderables() const; const std::vector<Tile*>& getTiles() const; std::unordered_map<std::string, std::vector<Feature>> queryRenderedFeatures( diff --git a/src/mbgl/util/clip_id.cpp b/src/mbgl/util/clip_id.cpp index 6346552962..a73692c451 100644 --- a/src/mbgl/util/clip_id.cpp +++ b/src/mbgl/util/clip_id.cpp @@ -1,17 +1,6 @@ #include <mbgl/util/clip_id.hpp> -#include <mbgl/platform/log.hpp> -#include <mbgl/util/math.hpp> -#include <mbgl/util/std.hpp> -#include <mbgl/tile/tile.hpp> - -#include <list> -#include <vector> -#include <bitset> -#include <cassert> #include <iostream> -#include <algorithm> -#include <iterator> namespace mbgl { @@ -19,140 +8,4 @@ namespace mbgl { return os << "mask=" << rhs.mask << ",ref=" << rhs.reference; } -ClipIDGenerator::Leaf::Leaf(TileID id_, ClipID& clip_) : id(id_), clip(clip_) {} - -void ClipIDGenerator::Leaf::add(const TileID &p) { - if (p.isChildOf(id)) { - // Ensure that no already present child is a parent of the new p. - for (const auto& child : children) { - if (p.isChildOf(child)) - return; - } - children.push_front(p); - } -} - -bool ClipIDGenerator::Leaf::operator==(const Leaf &other) const { - return id == other.id && children == other.children; -} - -void ClipIDGenerator::update(std::forward_list<Tile *> tiles) { - tiles.sort([](const Tile *a, const Tile *b) { - return a->id < b->id; - }); - - std::size_t size = 0; - - const auto end = tiles.end(); - for (auto it = tiles.begin(); it != end; it++) { - if (!*it) { - // Handle null pointers. - continue; - } - - Tile &tile = **it; - // Use the actual zoom level for computing the clipping mask. - Leaf leaf{ TileID{ tile.id.sourceZ, tile.id.x, tile.id.y, tile.id.sourceZ }, tile.clip }; - - // Try to add all remaining ids as children. We sorted the tile list - // by z earlier, so all preceding items cannot be children of the current - // tile. - for (auto child_it = std::next(it); child_it != end; child_it++) { - // Use the actual zoom level for computing the clipping mask. - const auto& childID = (*child_it)->id; - leaf.add(TileID { childID.sourceZ, childID.x, childID.y, childID.sourceZ }); - } - leaf.children.sort(); - - // Loop through all existing pools and try to find a matching ClipID. - auto existing = std::find(pool.begin(), pool.end(), leaf); - if (existing != pool.end()) { - leaf.clip = existing->clip; - } else { - // We haven't found an existing clip ID - leaf.clip = {}; - size++; - } - - pool.emplace_back(std::move(leaf)); - } - - if (size > 0) { - const uint32_t bit_count = util::ceil_log2(size + 1); - const std::bitset<8> mask = uint64_t(((1ul << bit_count) - 1) << bit_offset); - - // We are starting our count with 1 since we need at least 1 bit set to distinguish between - // areas without any tiles whatsoever and the current area. - uint8_t count = 1; - for (auto& tile : tiles) { - tile->clip.mask |= mask; - - // Assign only to clip IDs that have no value yet. - if (tile->clip.reference.none()) { - tile->clip.reference = uint32_t(count++) << bit_offset; - } - } - - bit_offset += bit_count; - } - - if (bit_offset > 8) { - Log::Error(Event::OpenGL, "stencil mask overflow"); - } -} - -template <typename Container> -bool coveredByChildren(const TileID& id, const Container& container) { - for (const auto& child : id.children()) { - const auto lower = container.lower_bound(child); - if (lower == container.end() || lower->first.w != child.w || - (lower->first != child && !coveredByChildren(child, container))) { - return false; - } - } - - // We looked at all four immediate children and verified that they're covered. - return true; -} - -std::map<TileID, ClipID> ClipIDGenerator::getStencils() const { - std::map<TileID, ClipID> stencils; - - // Merge everything. - for (auto& leaf : pool) { - auto res = stencils.emplace(leaf.id, leaf.clip); - if (!res.second) { - // Merge with the existing ClipID when there was already an element with the - // same tile ID. - res.first->second |= leaf.clip; - } - } - - for (auto it = stencils.begin(); it != stencils.end(); ++it) { - auto& childId = it->first; - auto& childClip = it->second; - - // Loop through all preceding stencils, and find all parents. - - for (auto parentIt = std::reverse_iterator<std::map<TileID, ClipID>::iterator>(it); - parentIt != stencils.rend(); ++parentIt) { - auto& parentId = parentIt->first; - if (childId.isChildOf(parentId)) { - // Once we have a parent, we add the bits that this ID hasn't set yet. - const auto& parentClip = parentIt->second; - const auto mask = ~(childClip.mask & parentClip.mask); - childClip.reference |= mask & parentClip.reference; - childClip.mask |= parentClip.mask; - } - } - } - - // Remove tiles that are entirely covered by children. - util::erase_if(stencils, [&] (const auto& stencil) { - return coveredByChildren(stencil.first, stencils); - }); - - return stencils; -} - } // namespace mbgl diff --git a/src/mbgl/util/clip_id.hpp b/src/mbgl/util/clip_id.hpp index aa16f2d0d6..bd14ea6720 100644 --- a/src/mbgl/util/clip_id.hpp +++ b/src/mbgl/util/clip_id.hpp @@ -36,28 +36,6 @@ struct ClipID { ::std::ostream& operator<<(::std::ostream& os, const ClipID& rhs); -class ClipIDGenerator { -private: - struct Leaf { - Leaf(TileID, ClipID&); - void add(const TileID &p); - bool operator==(const Leaf &other) const; - - const TileID id; - std::forward_list<TileID> children; - ClipID& clip; - }; - - uint8_t bit_offset = 0; - std::vector<Leaf> pool; - -public: - void update(std::forward_list<Tile *> tiles); - - std::map<TileID, ClipID> getStencils() const; -}; - - } // namespace mbgl #endif |