From dde59eaf769dc2d503e8bd4ca79d0923ad877e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 8 Mar 2016 17:18:57 +0100 Subject: [PATCH] [core] move Painter and dependents to new *TileID classes --- src/mbgl/algorithm/generate_clip_ids.cpp | 3 - src/mbgl/map/transform_state.cpp | 12 +- src/mbgl/map/transform_state.hpp | 4 +- src/mbgl/renderer/bucket.hpp | 4 +- src/mbgl/renderer/circle_bucket.cpp | 4 +- src/mbgl/renderer/circle_bucket.hpp | 2 +- src/mbgl/renderer/fill_bucket.cpp | 4 +- src/mbgl/renderer/fill_bucket.hpp | 2 +- src/mbgl/renderer/line_bucket.cpp | 4 +- src/mbgl/renderer/line_bucket.hpp | 2 +- src/mbgl/renderer/painter.cpp | 17 +- src/mbgl/renderer/painter.hpp | 21 +- src/mbgl/renderer/painter_background.cpp | 3 +- src/mbgl/renderer/painter_circle.cpp | 5 +- src/mbgl/renderer/painter_clipping.cpp | 7 +- src/mbgl/renderer/painter_fill.cpp | 37 +- src/mbgl/renderer/painter_line.cpp | 18 +- src/mbgl/renderer/painter_raster.cpp | 5 +- src/mbgl/renderer/painter_symbol.cpp | 25 +- src/mbgl/renderer/raster_bucket.cpp | 4 +- src/mbgl/renderer/raster_bucket.hpp | 2 +- src/mbgl/renderer/renderable.hpp | 14 + src/mbgl/renderer/symbol_bucket.cpp | 4 +- src/mbgl/renderer/symbol_bucket.hpp | 2 +- src/mbgl/source/source.cpp | 18 +- src/mbgl/source/source.hpp | 4 +- src/mbgl/util/clip_id.cpp | 147 -------- src/mbgl/util/clip_id.hpp | 22 -- test/test.gypi | 1 - test/util/clip_ids.cpp | 411 ----------------------- 30 files changed, 138 insertions(+), 670 deletions(-) create mode 100644 src/mbgl/renderer/renderable.hpp delete mode 100644 test/util/clip_ids.cpp diff --git a/src/mbgl/algorithm/generate_clip_ids.cpp b/src/mbgl/algorithm/generate_clip_ids.cpp index 369cb35de..208db797d 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&); - std::map ClipIDGenerator::getStencils() const { std::map stencils; diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index 4c96abcd1..2813d6334 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -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(tileID.canonical.x + tileID.wrap * tileScale) * s, + static_cast(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 37b52f960..b9acad66f 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 4212e7c30..0a4853ad9 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 4c94bfa0d..19ebf8e78 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(), id, matrix); + painter.renderCircle(*this, *layer.as(), tileID, matrix); } bool CircleBucket::hasData() const { diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp index defa7b069..abfca851e 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 48d9ae88a..b0f391323 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(), id, matrix); + painter.renderFill(*this, *layer.as(), tileID, matrix); } bool FillBucket::hasData() const { diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index bd6a9a9cf..aefb178c4 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 fdbb29145..5bbf1916b 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(), id, matrix); + painter.renderLine(*this, *layer.as(), tileID, matrix); } bool LineBucket::hasData() const { diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 9c7ec3d93..87d95586c 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 1fbce82c0..92ea94ba4 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -31,6 +31,9 @@ #include #include +#include +#include + #include #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 &translation, const TileID &id, TranslateAnchorType anchor) { +mat4 Painter::translatedMatrix(const mat4& matrix, + const std::array& 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 2fa5c0260..0fe623a91 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -3,6 +3,8 @@ #include +#include + #include #include @@ -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 spinWeights(float spin_value); - void drawClippingMasks(const std::map&); + void drawClippingMasks(const std::map&); bool needsAnimation() const; private: - mat4 translatedMatrix(const mat4& matrix, const std::array &translation, const TileID &id, TranslateAnchorType anchor); + mat4 translatedMatrix(const mat4& matrix, + const std::array& translation, + const UnwrappedTileID& id, + TranslateAnchorType anchor); std::vector 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 texsize, diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp index dddc75554..658d6535f 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 8e601ea7e..8711e2c48 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 aed4c4586..37e06922c 100644 --- a/src/mbgl/renderer/painter_clipping.cpp +++ b/src/mbgl/renderer/painter_clipping.cpp @@ -2,12 +2,13 @@ #include #include #include +#include #include using namespace mbgl; -void Painter::drawClippingMasks(const std::map& stencils) { +void Painter::drawClippingMasks(const std::map& stencils) { MBGL_DEBUG_GROUP("clipping masks"); mat4 matrix; @@ -27,8 +28,8 @@ void Painter::drawClippingMasks(const std::map& 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 0808cd2ac..6c23608c1 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()) - }}; + 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]) * id.x) / (float)imageSizeScaledA[0]; - float offsetAy = (std::fmod(util::tileSize, imageSizeScaledA[1]) * id.y) / (float)imageSizeScaledA[1]; + 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]) * id.x) / (float)imageSizeScaledB[0]; - float offsetBy = (std::fmod(util::tileSize, imageSizeScaledB[1]) * id.y) / (float)imageSizeScaledB[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{{offsetAx, offsetAy}}; patternShader->u_offset_b = std::array{{offsetBx, offsetBy}}; diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 80caf9a18..bc6c51c22 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 39e0b5f19..f00f2ebcb 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 1aecbcb50..6321d03a9 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 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 74f48e206..18c18923f 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(), id, matrix); + painter.renderRaster(*this, *layer.as(), tileID, matrix); } void RasterBucket::setImage(PremultipliedImage image) { diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp index 744cb4c29..6fe21f3e9 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 000000000..3d46fbd0b --- /dev/null +++ b/src/mbgl/renderer/renderable.hpp @@ -0,0 +1,14 @@ +#ifndef MBGL_RENDERER_RENDERABLE +#define MBGL_RENDERER_RENDERABLE + +#include + +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 b0930890d..a18303276 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(), id, matrix); + painter.renderSymbol(*this, *layer.as(), 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 e212f5616..8581a2357 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 b2729593c..1a961ac0c 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(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 Source::getLoadedTiles() const { - std::forward_list ptrs; - auto it = ptrs.before_begin(); +std::map Source::getRenderables() const { + std::map 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& Source::getTiles() const { diff --git a/src/mbgl/source/source.hpp b/src/mbgl/source/source.hpp index cc579e11e..5084f77ed 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 #include #include #include +#include #include #include @@ -70,7 +72,7 @@ public: void updateMatrices(const mat4 &projMatrix, const TransformState &transform); void finishRender(Painter &painter); - std::forward_list getLoadedTiles() const; + std::map getRenderables() const; const std::vector& getTiles() const; std::unordered_map> queryRenderedFeatures( diff --git a/src/mbgl/util/clip_id.cpp b/src/mbgl/util/clip_id.cpp index 634655296..a73692c45 100644 --- a/src/mbgl/util/clip_id.cpp +++ b/src/mbgl/util/clip_id.cpp @@ -1,17 +1,6 @@ #include -#include -#include -#include -#include - -#include -#include -#include -#include #include -#include -#include 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 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 -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 ClipIDGenerator::getStencils() const { - std::map 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::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 aa16f2d0d..bd14ea672 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 children; - ClipID& clip; - }; - - uint8_t bit_offset = 0; - std::vector pool; - -public: - void update(std::forward_list tiles); - - std::map getStencils() const; -}; - - } // namespace mbgl #endif diff --git a/test/test.gypi b/test/test.gypi index 3a4f96559..2cb98df65 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -20,7 +20,6 @@ 'sources': [ 'util/assert.cpp', 'util/async_task.cpp', - 'util/clip_ids.cpp', 'util/geo.cpp', 'util/image.cpp', 'util/mapbox.cpp', diff --git a/test/util/clip_ids.cpp b/test/util/clip_ids.cpp deleted file mode 100644 index 6bb0716a3..000000000 --- a/test/util/clip_ids.cpp +++ /dev/null @@ -1,411 +0,0 @@ -#include -#include - -#include - -#include -#include - -using namespace mbgl; - -using Stencil = std::pair; - -template void generate(ClipIDGenerator& generator, const T &sources) { - for (size_t j = 0; j < sources.size(); j++) { - std::forward_list tile_ptrs; - std::transform(sources[j].begin(), sources[j].end(), std::front_inserter(tile_ptrs), [](const std::shared_ptr &tile) { return tile.get(); }); - generator.update(tile_ptrs); - } -} - -void print(const std::vector>> &sources) { - for (size_t j = 0; j < sources.size(); j++) { - for (size_t i = 0; i < sources[j].size(); i++) { - std::cout << " ASSERT_EQ(ClipID(\"" << sources[j][i]->clip.mask << "\", \"" << sources[j][i]->clip.reference << "\"), sources[" << j << "][" << i << "]->clip);\n"; - } - } -} - -void print(const std::map& stencils) { - std::cout << " auto it = stencils.begin();\n"; - std::cout << " ASSERT_EQ(" << stencils.size() << ", stencils.size());\n"; - for (auto& stencil : stencils) { - std::cout << " ASSERT_EQ(Stencil(TileID{ " << (int)stencil.first.z << ", " - << stencil.first.x << ", " << stencil.first.y << ", " - << (int)stencil.first.sourceZ << " }, { \"" << stencil.second.mask.to_string() - << "\", \"" << stencil.second.reference.to_string() << "\"}), *it++);\n"; - } - std::cout << " ASSERT_EQ(stencils.end(), it);\n"; -} - -TEST(ClipIDs, ParentAndFourChildren) { - const std::vector>> sources = { - { - std::make_shared(TileID { 1, 0, 0, 1 }), - std::make_shared(TileID { 1, 0, 1, 1 }), - std::make_shared(TileID { 1, 1, 0, 1 }), - std::make_shared(TileID { 1, 1, 1, 1 }), - std::make_shared(TileID { 0, 0, 0, 0 }), - }, - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00000111", "00000010"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00000111", "00000011"), sources[0][1]->clip); - ASSERT_EQ(ClipID("00000111", "00000100"), sources[0][2]->clip); - ASSERT_EQ(ClipID("00000111", "00000101"), sources[0][3]->clip); - ASSERT_EQ(ClipID("00000111", "00000001"), sources[0][4]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(4, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 1, 0, 0, 1 }, { "00000111", "00000010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, 0, 1, 1 }, { "00000111", "00000011"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, 1, 0, 1 }, { "00000111", "00000100"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, 1, 1, 1 }, { "00000111", "00000101"}), *it++); - ASSERT_EQ(stencils.end(), it); - -} - -TEST(ClipIDs, ParentAndFourChildrenNegative) { - const std::vector>> sources = { - { - std::make_shared(TileID { 1, -2, 0, 1 }), - std::make_shared(TileID { 1, -2, 1, 1 }), - std::make_shared(TileID { 1, -1, 0, 1 }), - std::make_shared(TileID { 1, -1, 1, 1 }), - std::make_shared(TileID { 0, -1, 0, 0 }), - }, - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00000111", "00000010"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00000111", "00000011"), sources[0][1]->clip); - ASSERT_EQ(ClipID("00000111", "00000100"), sources[0][2]->clip); - ASSERT_EQ(ClipID("00000111", "00000101"), sources[0][3]->clip); - ASSERT_EQ(ClipID("00000111", "00000001"), sources[0][4]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(4, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 1, -2, 0, 1 }, { "00000111", "00000010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, -2, 1, 1 }, { "00000111", "00000011"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, -1, 0, 1 }, { "00000111", "00000100"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, -1, 1, 1 }, { "00000111", "00000101"}), *it++); - ASSERT_EQ(stencils.end(), it); -} - -TEST(ClipIDs, NegativeParentAndMissingLevel) { - const std::vector>> sources = { - { - std::make_shared(TileID { 1, -1, 0, 1 }), - std::make_shared(TileID { 2, -1, 0, 2 }), - std::make_shared(TileID { 2, -2, 1, 2 }), - std::make_shared(TileID { 2, -1, 1, 2 }), - std::make_shared(TileID { 2, -2, 0, 2 }), - }, - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00000111", "00000001"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00000111", "00000100"), sources[0][1]->clip); - ASSERT_EQ(ClipID("00000111", "00000011"), sources[0][2]->clip); - ASSERT_EQ(ClipID("00000111", "00000101"), sources[0][3]->clip); - ASSERT_EQ(ClipID("00000111", "00000010"), sources[0][4]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(4, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 2, -2, 0, 2 }, { "00000111", "00000010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, -2, 1, 2 }, { "00000111", "00000011"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, -1, 0, 2 }, { "00000111", "00000100"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, -1, 1, 2 }, { "00000111", "00000101"}), *it++); - ASSERT_EQ(stencils.end(), it); -} - - -TEST(ClipIDs, SevenOnSameLevel) { - const std::vector>> sources = { - { - std::make_shared(TileID { 2, 0, 0, 2 }), - std::make_shared(TileID { 2, 0, 1, 2 }), - std::make_shared(TileID { 2, 0, 2, 2 }), - std::make_shared(TileID { 2, 1, 0, 2 }), - std::make_shared(TileID { 2, 1, 1, 2 }), - std::make_shared(TileID { 2, 1, 2, 2 }), - std::make_shared(TileID { 2, 2, 0, 2 }), - }, - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00000111", "00000001"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00000111", "00000010"), sources[0][1]->clip); - ASSERT_EQ(ClipID("00000111", "00000011"), sources[0][2]->clip); - ASSERT_EQ(ClipID("00000111", "00000100"), sources[0][3]->clip); - ASSERT_EQ(ClipID("00000111", "00000101"), sources[0][4]->clip); - ASSERT_EQ(ClipID("00000111", "00000110"), sources[0][5]->clip); - ASSERT_EQ(ClipID("00000111", "00000111"), sources[0][6]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(7, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 2, 0, 0, 2 }, { "00000111", "00000001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 0, 1, 2 }, { "00000111", "00000010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 0, 2, 2 }, { "00000111", "00000011"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 1, 0, 2 }, { "00000111", "00000100"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 1, 1, 2 }, { "00000111", "00000101"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 1, 2, 2 }, { "00000111", "00000110"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 2, 0, 2 }, { "00000111", "00000111"}), *it++); - ASSERT_EQ(stencils.end(), it); -} - -TEST(ClipIDs, MultipleLevels) { - const std::vector>> sources = { - { - std::make_shared(TileID { 2, 0, 0, 2 }), - std::make_shared(TileID { 3, 0, 0, 3 }), - std::make_shared(TileID { 3, 0, 1, 3 }), - std::make_shared(TileID { 4, 0, 2, 4 }), - std::make_shared(TileID { 4, 1, 2, 4 }), - std::make_shared(TileID { 4, 0, 3, 4 }), - std::make_shared(TileID { 4, 1, 3, 4 }), - std::make_shared(TileID { 3, 1, 0, 3 }), - std::make_shared(TileID { 3, 1, 1, 3 }), - std::make_shared(TileID { 2, 1, 0, 2 }), - std::make_shared(TileID { 3, 2, 0, 3 }), - std::make_shared(TileID { 3, 2, 1, 3 }), - }, - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00001111", "00000001"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00001111", "00000011"), sources[0][1]->clip); - ASSERT_EQ(ClipID("00001111", "00000100"), sources[0][2]->clip); - ASSERT_EQ(ClipID("00001111", "00001001"), sources[0][3]->clip); - ASSERT_EQ(ClipID("00001111", "00001011"), sources[0][4]->clip); - ASSERT_EQ(ClipID("00001111", "00001010"), sources[0][5]->clip); - ASSERT_EQ(ClipID("00001111", "00001100"), sources[0][6]->clip); - ASSERT_EQ(ClipID("00001111", "00000101"), sources[0][7]->clip); - ASSERT_EQ(ClipID("00001111", "00000110"), sources[0][8]->clip); - ASSERT_EQ(ClipID("00001111", "00000010"), sources[0][9]->clip); - ASSERT_EQ(ClipID("00001111", "00000111"), sources[0][10]->clip); - ASSERT_EQ(ClipID("00001111", "00001000"), sources[0][11]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(10, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 2, 1, 0, 2 }, { "00001111", "00000010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 3, 0, 0, 3 }, { "00001111", "00000011"}), *it++); - ASSERT_EQ(Stencil(TileID{ 3, 1, 0, 3 }, { "00001111", "00000101"}), *it++); - ASSERT_EQ(Stencil(TileID{ 3, 1, 1, 3 }, { "00001111", "00000110"}), *it++); - ASSERT_EQ(Stencil(TileID{ 3, 2, 0, 3 }, { "00001111", "00000111"}), *it++); - ASSERT_EQ(Stencil(TileID{ 3, 2, 1, 3 }, { "00001111", "00001000"}), *it++); - ASSERT_EQ(Stencil(TileID{ 4, 0, 2, 4 }, { "00001111", "00001001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 4, 0, 3, 4 }, { "00001111", "00001010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 4, 1, 2, 4 }, { "00001111", "00001011"}), *it++); - ASSERT_EQ(Stencil(TileID{ 4, 1, 3, 4 }, { "00001111", "00001100"}), *it++); - ASSERT_EQ(stencils.end(), it); -} - - -TEST(ClipIDs, Bug206) { - const std::vector>> sources = { - { - std::make_shared(TileID { 10, 162, 395, 10 }), - std::make_shared(TileID { 10, 162, 396, 10 }), - std::make_shared(TileID { 10, 163, 395, 10 }), - std::make_shared(TileID { 11, 326, 791, 11 }), - std::make_shared(TileID { 12, 654, 1582, 12 }), - std::make_shared(TileID { 12, 654, 1583, 12 }), - std::make_shared(TileID { 12, 655, 1582, 12 }), - std::make_shared(TileID { 12, 655, 1583, 12 }), - std::make_shared(TileID { 10, 163, 396, 10 }), - std::make_shared(TileID { 10, 164, 395, 10 }), - std::make_shared(TileID { 10, 164, 396, 10 }), - }, - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00001111", "00000001"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00001111", "00000010"), sources[0][1]->clip); - ASSERT_EQ(ClipID("00001111", "00000011"), sources[0][2]->clip); - ASSERT_EQ(ClipID("00001111", "00000111"), sources[0][3]->clip); - ASSERT_EQ(ClipID("00001111", "00001000"), sources[0][4]->clip); - ASSERT_EQ(ClipID("00001111", "00001001"), sources[0][5]->clip); - ASSERT_EQ(ClipID("00001111", "00001010"), sources[0][6]->clip); - ASSERT_EQ(ClipID("00001111", "00001011"), sources[0][7]->clip); - ASSERT_EQ(ClipID("00001111", "00000100"), sources[0][8]->clip); - ASSERT_EQ(ClipID("00001111", "00000101"), sources[0][9]->clip); - ASSERT_EQ(ClipID("00001111", "00000110"), sources[0][10]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(11, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 10, 162, 395, 10 }, { "00001111", "00000001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 10, 162, 396, 10 }, { "00001111", "00000010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 10, 163, 395, 10 }, { "00001111", "00000011"}), *it++); - ASSERT_EQ(Stencil(TileID{ 10, 163, 396, 10 }, { "00001111", "00000100"}), *it++); - ASSERT_EQ(Stencil(TileID{ 10, 164, 395, 10 }, { "00001111", "00000101"}), *it++); - ASSERT_EQ(Stencil(TileID{ 10, 164, 396, 10 }, { "00001111", "00000110"}), *it++); - ASSERT_EQ(Stencil(TileID{ 11, 326, 791, 11 }, { "00001111", "00000111"}), *it++); - ASSERT_EQ(Stencil(TileID{ 12, 654, 1582, 12 }, { "00001111", "00001000"}), *it++); - ASSERT_EQ(Stencil(TileID{ 12, 654, 1583, 12 }, { "00001111", "00001001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 12, 655, 1582, 12 }, { "00001111", "00001010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 12, 655, 1583, 12 }, { "00001111", "00001011"}), *it++); - ASSERT_EQ(stencils.end(), it); -} - - -TEST(ClipIDs, MultipleSources) { - const std::vector>> sources = { - { - std::make_shared(TileID { 0, 0, 0, 0 }), - std::make_shared(TileID { 1, 1, 1, 1 }), - std::make_shared(TileID { 2, 2, 1, 2 }), - std::make_shared(TileID { 2, 2, 2, 2 }), - }, - { - std::make_shared(TileID { 0, 0, 0, 0 }), - std::make_shared(TileID { 1, 1, 1, 1 }), - std::make_shared(TileID { 2, 1, 1, 2 }), - std::make_shared(TileID { 2, 2, 2, 2 }), - }, - { - std::make_shared(TileID { 1, 0, 0, 1 }), - std::make_shared(TileID { 1, 0, 1, 1 }), - std::make_shared(TileID { 1, 1, 0, 1 }), - std::make_shared(TileID { 1, 1, 1, 1 }), - std::make_shared(TileID { 2, 1, 1, 2 }), - }, - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00000111", "00000001"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00000111", "00000010"), sources[0][1]->clip); - ASSERT_EQ(ClipID("00000111", "00000011"), sources[0][2]->clip); - ASSERT_EQ(ClipID("00000111", "00000100"), sources[0][3]->clip); - - ASSERT_EQ(ClipID("00011000", "00001000"), sources[1][0]->clip); - ASSERT_EQ(ClipID("00011111", "00000010"), sources[1][1]->clip); - ASSERT_EQ(ClipID("00011000", "00010000"), sources[1][2]->clip); - ASSERT_EQ(ClipID("00011111", "00000100"), sources[1][3]->clip); - - ASSERT_EQ(ClipID("11100000", "00100000"), sources[2][0]->clip); - ASSERT_EQ(ClipID("11100000", "01000000"), sources[2][1]->clip); - ASSERT_EQ(ClipID("11100000", "01100000"), sources[2][2]->clip); - ASSERT_EQ(ClipID("11100000", "10000000"), sources[2][3]->clip); - ASSERT_EQ(ClipID("11111000", "00010000"), sources[2][4]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(7, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 1, 0, 0, 1 }, { "11111111", "00101001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, 0, 1, 1 }, { "11111111", "01001001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, 1, 0, 1 }, { "11111111", "01101001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, 1, 1, 1 }, { "11111111", "10000010"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 1, 1, 2 }, { "11111111", "00010001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 2, 1, 2 }, { "11111111", "01101011"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 2, 2, 2 }, { "11111111", "10000100"}), *it++); - ASSERT_EQ(stencils.end(), it); -} - - -TEST(ClipIDs, DuplicateIDs) { - const std::vector>> sources = { - { - std::make_shared(TileID { 2, 0, 0, 2 }), - std::make_shared(TileID { 2, 0, 1, 2 }), - }, - { - std::make_shared(TileID { 2, 0, 0, 2 }), - std::make_shared(TileID { 2, 0, 1, 2 }), - std::make_shared(TileID { 2, 0, 1, 2 }), - } - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00000011", "00000001"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00000011", "00000010"), sources[0][1]->clip); - ASSERT_EQ(ClipID("00000011", "00000001"), sources[1][0]->clip); - ASSERT_EQ(ClipID("00000011", "00000010"), sources[1][1]->clip); - ASSERT_EQ(ClipID("00000011", "00000010"), sources[1][2]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(2, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 2, 0, 0, 2 }, { "00000011", "00000001"}), *it++); - ASSERT_EQ(Stencil(TileID{ 2, 0, 1, 2 }, { "00000011", "00000010"}), *it++); - ASSERT_EQ(stencils.end(), it); -} - -TEST(ClipIDs, SecondSourceHasParentOfFirstSource) { - const std::vector>> sources = { - { - std::make_shared(TileID { 1, 0, 0, 1 }), - }, - { - std::make_shared(TileID { 0, 0, 0, 0 }), - std::make_shared(TileID { 1, 0, 0, 1 }), - }, - { - std::make_shared(TileID { 0, 0, 0, 0 }), - } - }; - - ClipIDGenerator generator; - generate(generator, sources); - // print(sources); - - ASSERT_EQ(ClipID("00000001", "00000001"), sources[0][0]->clip); - ASSERT_EQ(ClipID("00000010", "00000010"), sources[1][0]->clip); - ASSERT_EQ(ClipID("00000011", "00000001"), sources[1][1]->clip); - - const auto stencils = generator.getStencils(); - // print(stencils); - - auto it = stencils.begin(); - ASSERT_EQ(2, stencils.size()); - ASSERT_EQ(Stencil(TileID{ 0, 0, 0, 0 }, { "00000110", "00000110"}), *it++); - ASSERT_EQ(Stencil(TileID{ 1, 0, 0, 1 }, { "00000111", "00000101"}), *it++); - ASSERT_EQ(stencils.end(), it); -}