From de2d75379d2b0f135fd0afbe16411cfd28fa401e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 16 Apr 2019 17:44:34 +0200 Subject: [core] change approach to stencil clipping to (almost) match JS --- src/core-files.json | 6 - src/mbgl/algorithm/covered_by_children.hpp | 39 -- src/mbgl/algorithm/generate_clip_ids.cpp | 76 ---- src/mbgl/algorithm/generate_clip_ids.hpp | 36 -- src/mbgl/algorithm/generate_clip_ids_impl.hpp | 91 ---- src/mbgl/annotation/render_annotation_source.cpp | 4 - src/mbgl/gfx/context.hpp | 2 + src/mbgl/gl/context.cpp | 5 + src/mbgl/gl/context.hpp | 2 + src/mbgl/renderer/layers/render_circle_layer.cpp | 4 +- src/mbgl/renderer/layers/render_fill_layer.cpp | 8 +- src/mbgl/renderer/layers/render_heatmap_layer.cpp | 6 +- src/mbgl/renderer/layers/render_line_layer.cpp | 5 +- src/mbgl/renderer/paint_parameters.cpp | 100 ++++- src/mbgl/renderer/paint_parameters.hpp | 21 +- src/mbgl/renderer/render_layer.cpp | 1 + src/mbgl/renderer/render_tile.cpp | 6 +- src/mbgl/renderer/render_tile.hpp | 2 - src/mbgl/renderer/renderer_impl.cpp | 62 +-- .../sources/render_custom_geometry_source.cpp | 4 - .../renderer/sources/render_geojson_source.cpp | 4 - src/mbgl/renderer/sources/render_vector_source.cpp | 4 - src/mbgl/util/clip_id.cpp | 11 - src/mbgl/util/clip_id.hpp | 34 -- test/algorithm/covered_by_children.test.cpp | 103 ----- test/algorithm/generate_clip_ids.test.cpp | 459 --------------------- test/test-files.json | 2 - 27 files changed, 139 insertions(+), 958 deletions(-) delete mode 100644 src/mbgl/algorithm/covered_by_children.hpp delete mode 100644 src/mbgl/algorithm/generate_clip_ids.cpp delete mode 100644 src/mbgl/algorithm/generate_clip_ids.hpp delete mode 100644 src/mbgl/algorithm/generate_clip_ids_impl.hpp delete mode 100644 src/mbgl/util/clip_id.cpp delete mode 100644 src/mbgl/util/clip_id.hpp delete mode 100644 test/algorithm/covered_by_children.test.cpp delete mode 100644 test/algorithm/generate_clip_ids.test.cpp diff --git a/src/core-files.json b/src/core-files.json index e224f55cad..e22e061ef0 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -4,7 +4,6 @@ "src/csscolorparser/csscolorparser.cpp", "src/mbgl/actor/mailbox.cpp", "src/mbgl/actor/scheduler.cpp", - "src/mbgl/algorithm/generate_clip_ids.cpp", "src/mbgl/annotation/annotation_manager.cpp", "src/mbgl/annotation/annotation_source.cpp", "src/mbgl/annotation/annotation_tile.cpp", @@ -280,7 +279,6 @@ "src/mbgl/tile/vector_tile.cpp", "src/mbgl/tile/vector_tile_data.cpp", "src/mbgl/util/chrono.cpp", - "src/mbgl/util/clip_id.cpp", "src/mbgl/util/color.cpp", "src/mbgl/util/compression.cpp", "src/mbgl/util/constants.cpp", @@ -495,9 +493,6 @@ }, "private_headers": { "csscolorparser/csscolorparser.hpp": "src/csscolorparser/csscolorparser.hpp", - "mbgl/algorithm/covered_by_children.hpp": "src/mbgl/algorithm/covered_by_children.hpp", - "mbgl/algorithm/generate_clip_ids.hpp": "src/mbgl/algorithm/generate_clip_ids.hpp", - "mbgl/algorithm/generate_clip_ids_impl.hpp": "src/mbgl/algorithm/generate_clip_ids_impl.hpp", "mbgl/algorithm/update_renderables.hpp": "src/mbgl/algorithm/update_renderables.hpp", "mbgl/algorithm/update_tile_masks.hpp": "src/mbgl/algorithm/update_tile_masks.hpp", "mbgl/annotation/annotation_manager.hpp": "src/mbgl/annotation/annotation_manager.hpp", @@ -750,7 +745,6 @@ "mbgl/tile/tile_observer.hpp": "src/mbgl/tile/tile_observer.hpp", "mbgl/tile/vector_tile.hpp": "src/mbgl/tile/vector_tile.hpp", "mbgl/tile/vector_tile_data.hpp": "src/mbgl/tile/vector_tile_data.hpp", - "mbgl/util/clip_id.hpp": "src/mbgl/util/clip_id.hpp", "mbgl/util/dtoa.hpp": "src/mbgl/util/dtoa.hpp", "mbgl/util/grid_index.hpp": "src/mbgl/util/grid_index.hpp", "mbgl/util/hash.hpp": "src/mbgl/util/hash.hpp", diff --git a/src/mbgl/algorithm/covered_by_children.hpp b/src/mbgl/algorithm/covered_by_children.hpp deleted file mode 100644 index fe5af3f3db..0000000000 --- a/src/mbgl/algorithm/covered_by_children.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include - -namespace mbgl { -namespace algorithm { - -template -bool coveredByChildren(const UnwrappedTileID& id, Iterator it, const Iterator& end) { - for (const auto& child : id.children()) { - it = std::lower_bound(it, end, child, [](const auto& a, const auto& b) { return std::get<0>(a) < b; }); - - // Child is not present, neither its grandchildren. - if (it == end) { - return false; - } - - // Child is not present, but its grandchildren are. - if (std::get<0>(*it) != child) { - // This child is not covered by its grandchildren. - if (!coveredByChildren(child, it, end)) { - return false; - } - } - } - - // We looked at all four children (recursively) and verified that they're covered. - return true; -} - -template -bool coveredByChildren(const UnwrappedTileID& id, const Container& container) { - return coveredByChildren( - id, container.upper_bound(id), - container.lower_bound(UnwrappedTileID{ static_cast(id.wrap + 1), { 0, 0, 0 } })); -} - -} // namespace algorithm -} // namespace mbgl diff --git a/src/mbgl/algorithm/generate_clip_ids.cpp b/src/mbgl/algorithm/generate_clip_ids.cpp deleted file mode 100644 index aefa55b929..0000000000 --- a/src/mbgl/algorithm/generate_clip_ids.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace mbgl { -namespace algorithm { - -ClipIDGenerator::Leaf::Leaf(ClipID& clip_) : clip(clip_) { -} - -void ClipIDGenerator::Leaf::add(const CanonicalTileID& p) { - // Ensure that no already present child is a parent of the new p. - for (const auto& child : children) { - if (p.isChildOf(child)) { - return; - } - } - children.emplace(p); -} - -bool ClipIDGenerator::Leaf::operator==(const Leaf& other) const { - return children == other.children; -} - -std::map ClipIDGenerator::getClipIDs() const { - std::map clipIDs; - - // Merge everything. - for (auto& pair : pool) { - auto& id = pair.first; - auto& leaf = pair.second; - auto res = clipIDs.emplace(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 = clipIDs.begin(); it != clipIDs.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(it); - parentIt != clipIDs.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(clipIDs, [&](const auto& stencil) { - return algorithm::coveredByChildren(stencil.first, clipIDs); - }); - - return clipIDs; -} - -} // namespace algorithm -} // namespace mbgl diff --git a/src/mbgl/algorithm/generate_clip_ids.hpp b/src/mbgl/algorithm/generate_clip_ids.hpp deleted file mode 100644 index 6950433578..0000000000 --- a/src/mbgl/algorithm/generate_clip_ids.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include - -namespace mbgl { -namespace algorithm { - -class ClipIDGenerator { -private: - struct Leaf { - Leaf(ClipID&); - void add(const CanonicalTileID &p); - bool operator==(const Leaf &other) const; - - std::set children; - ClipID& clip; - }; - - uint8_t bit_offset = 0; - std::multimap pool; - -public: - // The given vector must be sorted by id. - template - void update(std::vector> sortedRenderables); - - std::map getClipIDs() const; -}; - -} // namespace algorithm -} // namespace mbgl diff --git a/src/mbgl/algorithm/generate_clip_ids_impl.hpp b/src/mbgl/algorithm/generate_clip_ids_impl.hpp deleted file mode 100644 index a4af9c8cbb..0000000000 --- a/src/mbgl/algorithm/generate_clip_ids_impl.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace mbgl { -namespace algorithm { - -template -void ClipIDGenerator::update(std::vector> renderables) { - std::size_t size = 0; - assert(std::is_sorted(renderables.begin(), renderables.end(), - [](const Renderable& a, const Renderable& b) { return a.id < b.id; })); - - const auto end = renderables.end(); - for (auto it = renderables.begin(); it != end; ++it) { - auto& renderable = it->get(); - if (!renderable.used || !renderable.needsClipping) { - continue; - } - - renderable.clip = {}; - Leaf leaf{ renderable.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. We also compute the lower bound of the next wrap, because items of the next wrap - // can never be children of the current wrap. - auto child_it = std::next(it); - const auto children_end = std::lower_bound( - child_it, end, UnwrappedTileID{ static_cast(renderable.id.wrap + 1), { 0, 0, 0 } }, - [](auto& a, auto& b) { return a.get().id < b; }); - for (; child_it != children_end; ++child_it) { - auto& childTileID = child_it->get().id; - if (childTileID.isChildOf(it->get().id)) { - leaf.add(childTileID.canonical); - } - } - - // Find a leaf with matching children. - for (auto its = pool.equal_range(renderable.id); its.first != its.second; ++its.first) { - auto& existing = its.first->second; - if (existing == leaf) { - leaf.clip = existing.clip; - break; - } - } - if (leaf.clip.reference.none()) { - // We haven't found an existing clip ID - size++; - } - - pool.emplace(renderable.id, 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& it : renderables) { - auto& renderable = it.get(); - if (!renderable.used || !renderable.needsClipping) { - continue; - } - renderable.clip.mask |= mask; - - // Assign only to clip IDs that have no value yet. - if (renderable.clip.reference.none()) { - renderable.clip.reference = uint32_t(count++) << bit_offset; - } - } - - bit_offset += bit_count; - } - - // Prevent this warning from firing on every frame, - // which can be expensive in some platforms. - static bool warned = false; - - if (!warned && bit_offset > 8) { - Log::Error(Event::OpenGL, "stencil mask overflow"); - warned = true; - } -} - -} // namespace algorithm -} // namespace mbgl diff --git a/src/mbgl/annotation/render_annotation_source.cpp b/src/mbgl/annotation/render_annotation_source.cpp index ff6e6e34b7..740ad32244 100644 --- a/src/mbgl/annotation/render_annotation_source.cpp +++ b/src/mbgl/annotation/render_annotation_source.cpp @@ -3,9 +3,6 @@ #include #include -#include -#include - #include namespace mbgl { @@ -51,7 +48,6 @@ void RenderAnnotationSource::update(Immutable baseImpl_, } void RenderAnnotationSource::startRender(PaintParameters& parameters) { - parameters.clipIDGenerator.update(tilePyramid.getRenderTiles()); tilePyramid.startRender(parameters); } diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp index 140d3b2356..c56ace2252 100644 --- a/src/mbgl/gfx/context.hpp +++ b/src/mbgl/gfx/context.hpp @@ -168,6 +168,8 @@ public: virtual void visualizeStencilBuffer() = 0; virtual void visualizeDepthBuffer(float depthRangeSize) = 0; #endif + + virtual void clearStencilBuffer(int32_t) = 0; }; } // namespace gfx diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 394f2cd0d7..b6a7bcc44c 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -870,5 +870,10 @@ void Context::visualizeDepthBuffer(const float depthRangeSize) { #endif +void Context::clearStencilBuffer(const int32_t bits) { + MBGL_CHECK_ERROR(glClearStencil(bits)); + MBGL_CHECK_ERROR(glClear(GL_STENCIL_BUFFER_BIT)); +} + } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index ae935e32cb..aa8d2c4c84 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -247,6 +247,8 @@ public: void visualizeStencilBuffer() override; void visualizeDepthBuffer(float depthRangeSize) override; #endif + + void clearStencilBuffer(int32_t) override; }; } // namespace gl diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index a0531afaed..e96dee0cf5 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -103,9 +103,7 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { *parameters.renderPass, gfx::Triangles(), parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), - parameters.mapMode != MapMode::Continuous - ? parameters.stencilModeForClipping(tile.clip) - : gfx::StencilMode::disabled(), + gfx::StencilMode::disabled(), parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), *bucket.indexBuffer, diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 85ae12b9d9..ec446136dc 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ bool RenderFillLayer::hasCrossfade() const { void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { if (unevaluated.get().isUndefined()) { + parameters.renderTileClippingMasks(renderTiles); for (const RenderTile& tile : renderTiles) { const LayerRenderData* renderData = tile.tile.getLayerRenderData(*baseImpl); if (!renderData) { @@ -115,7 +117,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { *parameters.renderPass, drawMode, depthMode, - parameters.stencilModeForClipping(tile.clip), + parameters.stencilModeForClipping(tile.id), parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), indexBuffer, @@ -157,6 +159,8 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { return; } + parameters.renderTileClippingMasks(renderTiles); + for (const RenderTile& tile : renderTiles) { const LayerRenderData* renderData = tile.tile.getLayerRenderData(*baseImpl); if (!renderData) { @@ -209,7 +213,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { *parameters.renderPass, drawMode, depthMode, - parameters.stencilModeForClipping(tile.clip), + parameters.stencilModeForClipping(tile.id), parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), indexBuffer, diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index 1f3c179acc..48249002ea 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -98,10 +98,6 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto extrudeScale = tile.id.pixelsToTileUnits(1, parameters.state.getZoom()); - const auto stencilMode = parameters.mapMode != MapMode::Continuous - ? parameters.stencilModeForClipping(tile.clip) - : gfx::StencilMode::disabled(); - const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); auto& programInstance = parameters.programs.getHeatmapLayerPrograms().heatmap; @@ -129,7 +125,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { *renderPass, gfx::Triangles(), parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), - stencilMode, + gfx::StencilMode::disabled(), gfx::ColorMode::additive(), gfx::CullFaceMode::disabled(), *bucket.indexBuffer, diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 8fbe799f17..596a121249 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,8 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { return; } + parameters.renderTileClippingMasks(renderTiles); + for (const RenderTile& tile : renderTiles) { const LayerRenderData* renderData = tile.tile.getLayerRenderData(*baseImpl); if (!renderData) { @@ -98,7 +101,7 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { *parameters.renderPass, gfx::Triangles(), parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), - parameters.stencilModeForClipping(tile.clip), + parameters.stencilModeForClipping(tile.id), parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), *bucket.indexBuffer, diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp index 624deeec0a..e9f42d2579 100644 --- a/src/mbgl/renderer/paint_parameters.cpp +++ b/src/mbgl/renderer/paint_parameters.cpp @@ -1,8 +1,11 @@ #include #include #include +#include +#include #include #include +#include #include namespace mbgl { @@ -73,15 +76,94 @@ gfx::DepthMode PaintParameters::depthModeFor3D(gfx::DepthMaskType mask) const { return gfx::DepthMode { gfx::DepthFunctionType::LessEqual, mask, { 0.0, 1.0 } }; } -gfx::StencilMode PaintParameters::stencilModeForClipping(const ClipID& id) const { - return gfx::StencilMode { - gfx::StencilMode::Equal { static_cast(id.mask.to_ulong()) }, - static_cast(id.reference.to_ulong()), - 0, - gfx::StencilOpType::Keep, - gfx::StencilOpType::Keep, - gfx::StencilOpType::Replace - }; +void PaintParameters::clearStencil() { + nextStencilID = 1; + context.clearStencilBuffer(0b00000000); +} + +namespace { + +// Detects a difference in keys of renderTiles and tileClippingMaskIDs +bool tileIDsIdentical(const std::vector>& renderTiles, + const std::map& tileClippingMaskIDs) { + assert(std::is_sorted(renderTiles.begin(), renderTiles.end(), + [](const RenderTile& a, const RenderTile& b) { return a.id < b.id; })); + if (renderTiles.size() != tileClippingMaskIDs.size()) { + return false; + } + return std::equal(renderTiles.begin(), renderTiles.end(), tileClippingMaskIDs.begin(), + [](const RenderTile& a, const auto& b) { return a.id == b.first; }); +} + +} // namespace + +void PaintParameters::renderTileClippingMasks(const std::vector>& renderTiles) { + if (renderTiles.empty() || tileIDsIdentical(renderTiles, tileClippingMaskIDs)) { + // The current stencil mask is for this source already; no need to draw another one. + return; + } + + if (nextStencilID + renderTiles.size() > 256) { + // we'll run out of fresh IDs so we need to clear and start from scratch + clearStencil(); + } + + tileClippingMaskIDs.clear(); + + auto& program = staticData.programs.clippingMask; + const style::Properties<>::PossiblyEvaluated properties {}; + const ClippingMaskProgram::Binders paintAttributeData(properties, 0); + + for (const RenderTile& renderTile : renderTiles) { + const int32_t stencilID = nextStencilID++; + tileClippingMaskIDs.emplace(renderTile.id, stencilID); + + program.draw( + context, + *renderPass, + gfx::Triangles(), + gfx::DepthMode::disabled(), + gfx::StencilMode { + gfx::StencilMode::Always{}, + stencilID, + 0b11111111, + gfx::StencilOpType::Keep, + gfx::StencilOpType::Keep, + gfx::StencilOpType::Replace + }, + gfx::ColorMode::disabled(), + gfx::CullFaceMode::disabled(), + staticData.quadTriangleIndexBuffer, + staticData.tileTriangleSegments, + program.computeAllUniformValues( + ClippingMaskProgram::LayoutUniformValues { + uniforms::matrix::Value( matrixForTile(renderTile.id) ), + }, + paintAttributeData, + properties, + state.getZoom() + ), + program.computeAllAttributeBindings( + staticData.tileVertexBuffer, + paintAttributeData, + properties + ), + ClippingMaskProgram::TextureBindings{}, + "clipping" + ); + } +} + +gfx::StencilMode PaintParameters::stencilModeForClipping(const UnwrappedTileID& tileID) const { + auto it = tileClippingMaskIDs.find(tileID); + assert(it != tileClippingMaskIDs.end()); + const int32_t id = it != tileClippingMaskIDs.end() ? it->second : 0b00000000; + return gfx::StencilMode{ gfx::StencilMode::Equal{ 0b11111111 }, + id, + 0b00000000, + gfx::StencilOpType::Keep, + gfx::StencilOpType::Keep, + gfx::StencilOpType::Replace }; } gfx::ColorMode PaintParameters::colorModeForRenderPass() const { diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp index 523975c78c..1a576b6c9c 100644 --- a/src/mbgl/renderer/paint_parameters.hpp +++ b/src/mbgl/renderer/paint_parameters.hpp @@ -7,10 +7,11 @@ #include #include #include -#include #include #include +#include +#include namespace mbgl { @@ -21,6 +22,8 @@ class TransformState; class ImageManager; class LineAtlas; class UnwrappedTileID; +class RenderSource; +class RenderTile; namespace gfx { class Context; @@ -62,13 +65,11 @@ public: float pixelRatio; Placement::VariableOffsets variableOffsets; std::array pixelsToGLUnits; - algorithm::ClipIDGenerator clipIDGenerator; Programs& programs; gfx::DepthMode depthModeForSublayer(uint8_t n, gfx::DepthMaskType) const; gfx::DepthMode depthModeFor3D(gfx::DepthMaskType) const; - gfx::StencilMode stencilModeForClipping(const ClipID&) const; gfx::ColorMode colorModeForRenderPass() const; mat4 matrixForTile(const UnwrappedTileID&, bool aligned = false) const; @@ -77,10 +78,24 @@ public: mat4 alignedProjMatrix; mat4 nearClippedProjMatrix; + // Stencil handling +public: + void renderTileClippingMasks(const std::vector>&); + gfx::StencilMode stencilModeForClipping(const UnwrappedTileID&) const; + +private: + void clearStencil(); + + // This needs to be an ordered map so that we have the same order as the renderTiles. + std::map tileClippingMaskIDs; + int32_t nextStencilID = 1; + +public: int numSublayers = 3; uint32_t currentLayer; float depthRangeSize; const float depthEpsilon = 1.0f / (1 << 16); + float symbolFadeChange; }; diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index 5868c38fbc..b7639f83fe 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index 5429536c3f..e175b761fe 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -101,7 +101,7 @@ void RenderTile::finishRender(PaintParameters& parameters) { *parameters.renderPass, gfx::Lines { 4.0f * parameters.pixelRatio }, gfx::DepthMode::disabled(), - parameters.stencilModeForClipping(clip), + gfx::StencilMode::disabled(), gfx::ColorMode::unblended(), gfx::CullFaceMode::disabled(), *tile.debugBucket->indexBuffer, @@ -125,7 +125,7 @@ void RenderTile::finishRender(PaintParameters& parameters) { *parameters.renderPass, gfx::Lines { 2.0f * parameters.pixelRatio }, gfx::DepthMode::disabled(), - parameters.stencilModeForClipping(clip), + gfx::StencilMode::disabled(), gfx::ColorMode::unblended(), gfx::CullFaceMode::disabled(), *tile.debugBucket->indexBuffer, @@ -152,7 +152,7 @@ void RenderTile::finishRender(PaintParameters& parameters) { *parameters.renderPass, gfx::LineStrip { 4.0f * parameters.pixelRatio }, gfx::DepthMode::disabled(), - parameters.stencilModeForClipping(clip), + gfx::StencilMode::disabled(), gfx::ColorMode::unblended(), gfx::CullFaceMode::disabled(), parameters.staticData.tileBorderIndexBuffer, diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp index bfa695586c..ddfcaa8d4d 100644 --- a/src/mbgl/renderer/render_tile.hpp +++ b/src/mbgl/renderer/render_tile.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -24,7 +23,6 @@ public: UnwrappedTileID id; Tile& tile; - ClipID clip; mat4 matrix; mat4 nearClippedMatrix; bool used = false; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 1b17324ccf..ecb26fa330 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -420,61 +420,6 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { parameters.renderPass = parameters.encoder->createRenderPass("main buffer", { parameters.backend.getDefaultRenderable(), color, 1, 0 }); } - // - CLIPPING MASKS ---------------------------------------------------------------------------- - // Draws the clipping masks to the stencil buffer. - { - const auto debugGroup(parameters.renderPass->createDebugGroup("clipping masks")); - - static const Properties<>::PossiblyEvaluated properties {}; - static const ClippingMaskProgram::Binders paintAttributeData(properties, 0); - - for (const auto& clipID : parameters.clipIDGenerator.getClipIDs()) { - auto& program = parameters.staticData.programs.clippingMask; - - program.draw( - parameters.context, - *parameters.renderPass, - gfx::Triangles(), - gfx::DepthMode::disabled(), - gfx::StencilMode { - gfx::StencilMode::Always(), - static_cast(clipID.second.reference.to_ulong()), - 0b11111111, - gfx::StencilOpType::Keep, - gfx::StencilOpType::Keep, - gfx::StencilOpType::Replace - }, - gfx::ColorMode::disabled(), - gfx::CullFaceMode::disabled(), - parameters.staticData.quadTriangleIndexBuffer, - parameters.staticData.tileTriangleSegments, - program.computeAllUniformValues( - ClippingMaskProgram::LayoutUniformValues { - uniforms::matrix::Value( parameters.matrixForTile(clipID.first) ), - }, - paintAttributeData, - properties, - parameters.state.getZoom() - ), - program.computeAllAttributeBindings( - parameters.staticData.tileVertexBuffer, - paintAttributeData, - properties - ), - ClippingMaskProgram::TextureBindings{}, - "clipping" - ); - } - } - -#if not defined(NDEBUG) - // Render tile clip boundaries, using stencil buffer to calculate fill color. - if (parameters.debugOptions & MapDebugOptions::StencilClip) { - parameters.context.visualizeStencilBuffer(); - return; - } -#endif - // Actually render the layers parameters.depthRangeSize = 1 - (renderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon; @@ -530,8 +475,11 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { } #if not defined(NDEBUG) - // Render the depth buffer. - if (parameters.debugOptions & MapDebugOptions::DepthBuffer) { + if (parameters.debugOptions & MapDebugOptions::StencilClip) { + // Render tile clip boundaries, using stencil buffer to calculate fill color. + parameters.context.visualizeStencilBuffer(); + } else if (parameters.debugOptions & MapDebugOptions::DepthBuffer) { + // Render the depth buffer. parameters.context.visualizeDepthBuffer(parameters.depthRangeSize); } #endif diff --git a/src/mbgl/renderer/sources/render_custom_geometry_source.cpp b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp index 30b6e65f24..8de79d8016 100644 --- a/src/mbgl/renderer/sources/render_custom_geometry_source.cpp +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp @@ -3,9 +3,6 @@ #include #include -#include -#include - namespace mbgl { using namespace style; @@ -51,7 +48,6 @@ void RenderCustomGeometrySource::update(Immutable baseImpl_ } void RenderCustomGeometrySource::startRender(PaintParameters& parameters) { - parameters.clipIDGenerator.update(tilePyramid.getRenderTiles()); tilePyramid.startRender(parameters); } diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp index 332ea4d170..0234b97eca 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -4,9 +4,6 @@ #include #include -#include -#include - #include namespace mbgl { @@ -127,7 +124,6 @@ void RenderGeoJSONSource::update(Immutable baseImpl_, } void RenderGeoJSONSource::startRender(PaintParameters& parameters) { - parameters.clipIDGenerator.update(tilePyramid.getRenderTiles()); tilePyramid.startRender(parameters); } diff --git a/src/mbgl/renderer/sources/render_vector_source.cpp b/src/mbgl/renderer/sources/render_vector_source.cpp index efcd11094c..518692fc77 100644 --- a/src/mbgl/renderer/sources/render_vector_source.cpp +++ b/src/mbgl/renderer/sources/render_vector_source.cpp @@ -3,9 +3,6 @@ #include #include -#include -#include - namespace mbgl { using namespace style; @@ -61,7 +58,6 @@ void RenderVectorSource::update(Immutable baseImpl_, } void RenderVectorSource::startRender(PaintParameters& parameters) { - parameters.clipIDGenerator.update(tilePyramid.getRenderTiles()); tilePyramid.startRender(parameters); } diff --git a/src/mbgl/util/clip_id.cpp b/src/mbgl/util/clip_id.cpp deleted file mode 100644 index a73692c451..0000000000 --- a/src/mbgl/util/clip_id.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -#include - -namespace mbgl { - -::std::ostream& operator<<(::std::ostream& os, const ClipID& rhs) { - return os << "mask=" << rhs.mask << ",ref=" << rhs.reference; -} - -} // namespace mbgl diff --git a/src/mbgl/util/clip_id.hpp b/src/mbgl/util/clip_id.hpp deleted file mode 100644 index de2dc51919..0000000000 --- a/src/mbgl/util/clip_id.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mbgl { - -struct ClipID { - ClipID() {} - ClipID(const std::string &mask_, const std::string &reference_) : mask(mask_), reference(reference_) {} - - std::bitset<8> mask; - std::bitset<8> reference; - - bool operator==(const ClipID &other) const { - return mask == other.mask && reference == other.reference; - } - - ClipID& operator|=(const ClipID &other) { - mask |= other.mask; - reference |= other.reference; - return *this; - } -}; - -::std::ostream& operator<<(::std::ostream& os, const ClipID& rhs); - -} // namespace mbgl diff --git a/test/algorithm/covered_by_children.test.cpp b/test/algorithm/covered_by_children.test.cpp deleted file mode 100644 index 84f5aa6a21..0000000000 --- a/test/algorithm/covered_by_children.test.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include - -#include - -#include - -using namespace mbgl; - -using List = std::map; - -TEST(CoveredByChildren, GrandChildren) { - const List list { - { UnwrappedTileID{ 0, 0, 0 }, true }, - // These grandchildren covers 1/0/0, but 1/0/0 only covers a quarter of - // 0/0/0. - { UnwrappedTileID{ 2, 0, 0 }, true }, - { UnwrappedTileID{ 2, 0, 1 }, true }, - { UnwrappedTileID{ 2, 1, 0 }, true }, - { UnwrappedTileID{ 2, 1, 1 }, true }, - }; - EXPECT_FALSE(algorithm::coveredByChildren(UnwrappedTileID{ 0, 0, 0 }, list)); - - const List list2 { - { UnwrappedTileID{ 0, 0, 0 }, true }, - - // Children of 1/0/0 - { UnwrappedTileID{ 2, 0, 0 }, true }, - { UnwrappedTileID{ 2, 0, 1 }, true }, - { UnwrappedTileID{ 2, 1, 0 }, true }, - { UnwrappedTileID{ 2, 1, 1 }, true }, - - // Children of 1/0/1 - { UnwrappedTileID{ 2, 0, 2 }, true }, - { UnwrappedTileID{ 2, 0, 3 }, true }, - { UnwrappedTileID{ 2, 1, 2 }, true }, - { UnwrappedTileID{ 2, 1, 3 }, true }, - - // Children of 1/1/0 - { UnwrappedTileID{ 2, 2, 0 }, true }, - { UnwrappedTileID{ 2, 2, 1 }, true }, - { UnwrappedTileID{ 2, 3, 0 }, true }, - { UnwrappedTileID{ 2, 3, 1 }, true }, - - // Children of 1/0/1 - { UnwrappedTileID{ 2, 2, 2 }, true }, - { UnwrappedTileID{ 2, 2, 3 }, true }, - { UnwrappedTileID{ 2, 3, 2 }, true }, - { UnwrappedTileID{ 2, 3, 3 }, true }, - }; - EXPECT_TRUE(algorithm::coveredByChildren(UnwrappedTileID{ 0, 0, 0 }, list2)); -} - -TEST(CoveredByChildren, NotCovered) { - const List list1; - EXPECT_FALSE(algorithm::coveredByChildren(UnwrappedTileID{ 0, 0, 0 }, list1)); - - const List list2{ - { UnwrappedTileID{ 0, 0, 0 }, true }, - // 3 out of 4 child tiles - { UnwrappedTileID{ 1, 0, 0 }, true }, - { UnwrappedTileID{ 1, 0, 1 }, true }, - // missing 1/1/0 - { UnwrappedTileID{ 1, 1, 1 }, true }, - }; - EXPECT_FALSE(algorithm::coveredByChildren(UnwrappedTileID{ 0, 0, 0 }, list2)); - - const List list3{ - { UnwrappedTileID{ 0, 0, 0 }, true }, - // all four child tiles, with a different wrap index - { UnwrappedTileID{ 1, { 1, 0, 0 } }, true }, - { UnwrappedTileID{ 1, { 1, 0, 1 } }, true }, - { UnwrappedTileID{ 1, { 1, 1, 0 } }, true }, - { UnwrappedTileID{ 1, { 1, 1, 1 } }, true }, - }; - EXPECT_FALSE(algorithm::coveredByChildren(UnwrappedTileID{ 0, 0, 0 }, list3)); -} - -TEST(CoveredByChildren, Covered) { - const List list1{ - { UnwrappedTileID{ 0, 0, 0 }, true }, - // all four child tiles - { UnwrappedTileID{ 1, 0, 0 }, true }, - { UnwrappedTileID{ 1, 0, 1 }, true }, - { UnwrappedTileID{ 1, 1, 0 }, true }, - { UnwrappedTileID{ 1, 1, 1 }, true }, - }; - EXPECT_TRUE(algorithm::coveredByChildren(UnwrappedTileID{ 0, 0, 0 }, list1)); - - const List list2{ - { UnwrappedTileID{ 0, 0, 0 }, true }, - // missing 1/0/0 - { UnwrappedTileID{ 1, 0, 1 }, true }, - { UnwrappedTileID{ 1, 1, 0 }, true }, - { UnwrappedTileID{ 1, 1, 1 }, true }, - { UnwrappedTileID{ 2, 0, 0 }, true }, - { UnwrappedTileID{ 2, 0, 1 }, true }, - { UnwrappedTileID{ 2, 1, 0 }, true }, - { UnwrappedTileID{ 2, 1, 1 }, true }, - }; - EXPECT_TRUE(algorithm::coveredByChildren(UnwrappedTileID{ 0, 0, 0 }, list2)); - EXPECT_TRUE(algorithm::coveredByChildren(UnwrappedTileID{ 1, 0, 0 }, list2)); - EXPECT_FALSE(algorithm::coveredByChildren(UnwrappedTileID{ 2, 0, 0 }, list2)); -} diff --git a/test/algorithm/generate_clip_ids.test.cpp b/test/algorithm/generate_clip_ids.test.cpp deleted file mode 100644 index d918514e51..0000000000 --- a/test/algorithm/generate_clip_ids.test.cpp +++ /dev/null @@ -1,459 +0,0 @@ -#include - -#include - -using namespace mbgl; - -struct Renderable { - UnwrappedTileID id; - ClipID clip; - bool used; - bool needsClipping; - - Renderable(UnwrappedTileID id_, - ClipID clip_, - bool used_ = true, - bool needsClipping_ = true) - : id(std::move(id_)), - clip(std::move(clip_)), - used(used_), - needsClipping(needsClipping_) {} - - bool operator==(const Renderable& rhs) const { - return id == rhs.id && clip == rhs.clip; - } -}; - -namespace { -auto makeSorted(std::vector& renderables) { - std::vector> sorted(renderables.begin(), renderables.end()); - std::sort(sorted.begin(), sorted.end(), - [](const Renderable& a, const Renderable& b){ return a.id < b.id; }); - return sorted; -} -} // namespace - -::std::ostream& operator<<(::std::ostream& os, const Renderable& rhs) { - return os << "Renderable{ " << rhs.id << ", " << rhs.clip << " }"; -} - -TEST(GenerateClipIDs, ParentAndFourChildren) { - std::vector renderables{ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, - // All four covering children - Renderable{ UnwrappedTileID{ 1, 0, 0 }, {} }, - Renderable{ UnwrappedTileID{ 1, 0, 1 }, {} }, - Renderable{ UnwrappedTileID{ 1, 1, 0 }, {} }, - Renderable{ UnwrappedTileID{ 1, 1, 1 }, {} }, - }; - - algorithm::ClipIDGenerator generator; - generator.update({ renderables.begin(), renderables.end() }); - - EXPECT_EQ(decltype(renderables)({ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000111", "00000001" } }, - Renderable{ UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000111", "00000010" } }, - Renderable{ UnwrappedTileID{ 1, 0, 1 }, ClipID{ "00000111", "00000011" } }, - Renderable{ UnwrappedTileID{ 1, 1, 0 }, ClipID{ "00000111", "00000100" } }, - Renderable{ UnwrappedTileID{ 1, 1, 1 }, ClipID{ "00000111", "00000101" } }, - }), - renderables); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - // 0/0/0 is missing because it is covered by children. - { UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000111", "00000010" } }, - { UnwrappedTileID{ 1, 0, 1 }, ClipID{ "00000111", "00000011" } }, - { UnwrappedTileID{ 1, 1, 0 }, ClipID{ "00000111", "00000100" } }, - { UnwrappedTileID{ 1, 1, 1 }, ClipID{ "00000111", "00000101" } }, - }), - clipIDs); -} - -TEST(GenerateClipIDs, ParentAndFourChildrenNegative) { - std::vector renderables{ - Renderable{ UnwrappedTileID{ 1, -2, 0 }, {} }, - Renderable{ UnwrappedTileID{ 1, -2, 1 }, {} }, - Renderable{ UnwrappedTileID{ 1, -1, 0 }, {} }, - Renderable{ UnwrappedTileID{ 1, -1, 1 }, {} }, - Renderable{ UnwrappedTileID{ 0, -1, 0 }, {} }, - }; - - algorithm::ClipIDGenerator generator; - generator.update(makeSorted(renderables)); - - EXPECT_EQ(decltype(renderables)({ - Renderable{ UnwrappedTileID{ 1, -2, 0 }, ClipID{ "00000111", "00000010" } }, - Renderable{ UnwrappedTileID{ 1, -2, 1 }, ClipID{ "00000111", "00000011" } }, - Renderable{ UnwrappedTileID{ 1, -1, 0 }, ClipID{ "00000111", "00000100" } }, - Renderable{ UnwrappedTileID{ 1, -1, 1 }, ClipID{ "00000111", "00000101" } }, - Renderable{ UnwrappedTileID{ 0, -1, 0 }, ClipID{ "00000111", "00000001" } }, - }), - renderables); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID{ 1, -2, 0 }, ClipID{ "00000111", "00000010" } }, - { UnwrappedTileID{ 1, -2, 1 }, ClipID{ "00000111", "00000011" } }, - { UnwrappedTileID{ 1, -1, 0 }, ClipID{ "00000111", "00000100" } }, - { UnwrappedTileID{ 1, -1, 1 }, ClipID{ "00000111", "00000101" } }, - }), - clipIDs); -} - -TEST(GenerateClipIDs, NegativeParentAndMissingLevel) { - std::vector renderables{ - Renderable{ UnwrappedTileID{ 1, -1, 0 }, {} }, - Renderable{ UnwrappedTileID{ 2, -1, 0 }, {} }, - Renderable{ UnwrappedTileID{ 2, -2, 1 }, {} }, - Renderable{ UnwrappedTileID{ 2, -1, 1 }, {} }, - Renderable{ UnwrappedTileID{ 2, -2, 0 }, {} }, - }; - - algorithm::ClipIDGenerator generator; - generator.update(makeSorted(renderables)); - - EXPECT_EQ(decltype(renderables)({ - Renderable{ UnwrappedTileID{ 1, -1, 0 }, ClipID{ "00000111", "00000001" } }, - Renderable{ UnwrappedTileID{ 2, -1, 0 }, ClipID{ "00000111", "00000100" } }, - Renderable{ UnwrappedTileID{ 2, -2, 1 }, ClipID{ "00000111", "00000011" } }, - Renderable{ UnwrappedTileID{ 2, -1, 1 }, ClipID{ "00000111", "00000101" } }, - Renderable{ UnwrappedTileID{ 2, -2, 0 }, ClipID{ "00000111", "00000010" } }, - }), - renderables); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID{ 2, -2, 0 }, ClipID{ "00000111", "00000010" } }, - { UnwrappedTileID{ 2, -2, 1 }, ClipID{ "00000111", "00000011" } }, - { UnwrappedTileID{ 2, -1, 0 }, ClipID{ "00000111", "00000100" } }, - { UnwrappedTileID{ 2, -1, 1 }, ClipID{ "00000111", "00000101" } }, - }), - clipIDs); -} - -TEST(GenerateClipIDs, SevenOnSameLevel) { - std::vector renderables{ - // first column - Renderable{ UnwrappedTileID{ 2, 0, 0 }, {} }, - Renderable{ UnwrappedTileID{ 2, 0, 1 }, {} }, - Renderable{ UnwrappedTileID{ 2, 0, 2 }, {} }, - // second column - Renderable{ UnwrappedTileID{ 2, 1, 0 }, {} }, - Renderable{ UnwrappedTileID{ 2, 1, 1 }, {} }, - Renderable{ UnwrappedTileID{ 2, 1, 2 }, {} }, - // third column - Renderable{ UnwrappedTileID{ 2, 2, 0 }, {} }, - }; - - algorithm::ClipIDGenerator generator; - generator.update({ renderables.begin(), renderables.end() }); - EXPECT_EQ(decltype(renderables)({ - Renderable{ UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000111", "00000001" } }, - Renderable{ UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000111", "00000010" } }, - Renderable{ UnwrappedTileID{ 2, 0, 2 }, ClipID{ "00000111", "00000011" } }, - Renderable{ UnwrappedTileID{ 2, 1, 0 }, ClipID{ "00000111", "00000100" } }, - Renderable{ UnwrappedTileID{ 2, 1, 1 }, ClipID{ "00000111", "00000101" } }, - Renderable{ UnwrappedTileID{ 2, 1, 2 }, ClipID{ "00000111", "00000110" } }, - Renderable{ UnwrappedTileID{ 2, 2, 0 }, ClipID{ "00000111", "00000111" } }, - }), - renderables); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000111", "00000001" } }, - { UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000111", "00000010" } }, - { UnwrappedTileID{ 2, 0, 2 }, ClipID{ "00000111", "00000011" } }, - { UnwrappedTileID{ 2, 1, 0 }, ClipID{ "00000111", "00000100" } }, - { UnwrappedTileID{ 2, 1, 1 }, ClipID{ "00000111", "00000101" } }, - { UnwrappedTileID{ 2, 1, 2 }, ClipID{ "00000111", "00000110" } }, - { UnwrappedTileID{ 2, 2, 0 }, ClipID{ "00000111", "00000111" } }, - }), - clipIDs); -} - -TEST(GenerateClipIDs, MultipleLevels) { - std::vector renderables{ - Renderable{ UnwrappedTileID{ 2, 0, 0 }, {} }, - // begin subtiles of (2/0/0) - Renderable{ UnwrappedTileID{ 3, 0, 0 }, {} }, - Renderable{ UnwrappedTileID{ 3, 0, 1 }, {} }, - // begin subtiles of (3/0/1) - Renderable{ UnwrappedTileID{ 4, 0, 2 }, {} }, - Renderable{ UnwrappedTileID{ 4, 1, 2 }, {} }, - Renderable{ UnwrappedTileID{ 4, 0, 3 }, {} }, - Renderable{ UnwrappedTileID{ 4, 1, 3 }, {} }, - // end subtiles of (3/0/1) - Renderable{ UnwrappedTileID{ 3, 1, 0 }, {} }, - Renderable{ UnwrappedTileID{ 3, 1, 1 }, {} }, - // end subtiles of (2/0/0) - Renderable{ UnwrappedTileID{ 2, 1, 0 }, {} }, - // begin subtiles of (2/1/0) - Renderable{ UnwrappedTileID{ 3, 2, 0 }, {} }, - Renderable{ UnwrappedTileID{ 3, 2, 1 }, {} }, - // end subtiles of (2/1/0) - }; - - algorithm::ClipIDGenerator generator; - generator.update(makeSorted(renderables)); - ASSERT_EQ(decltype(renderables)({ - Renderable{ UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00001111", "00000001" } }, - Renderable{ UnwrappedTileID{ 3, 0, 0 }, ClipID{ "00001111", "00000011" } }, - Renderable{ UnwrappedTileID{ 3, 0, 1 }, ClipID{ "00001111", "00000100" } }, - Renderable{ UnwrappedTileID{ 4, 0, 2 }, ClipID{ "00001111", "00001001" } }, - Renderable{ UnwrappedTileID{ 4, 1, 2 }, ClipID{ "00001111", "00001011" } }, - Renderable{ UnwrappedTileID{ 4, 0, 3 }, ClipID{ "00001111", "00001010" } }, - Renderable{ UnwrappedTileID{ 4, 1, 3 }, ClipID{ "00001111", "00001100" } }, - Renderable{ UnwrappedTileID{ 3, 1, 0 }, ClipID{ "00001111", "00000101" } }, - Renderable{ UnwrappedTileID{ 3, 1, 1 }, ClipID{ "00001111", "00000110" } }, - Renderable{ UnwrappedTileID{ 2, 1, 0 }, ClipID{ "00001111", "00000010" } }, - Renderable{ UnwrappedTileID{ 3, 2, 0 }, ClipID{ "00001111", "00000111" } }, - Renderable{ UnwrappedTileID{ 3, 2, 1 }, ClipID{ "00001111", "00001000" } }, - }), - renderables); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID{ 2, 1, 0 }, ClipID{ "00001111", "00000010" } }, - { UnwrappedTileID{ 3, 0, 0 }, ClipID{ "00001111", "00000011" } }, - { UnwrappedTileID{ 3, 1, 0 }, ClipID{ "00001111", "00000101" } }, - { UnwrappedTileID{ 3, 1, 1 }, ClipID{ "00001111", "00000110" } }, - { UnwrappedTileID{ 3, 2, 0 }, ClipID{ "00001111", "00000111" } }, - { UnwrappedTileID{ 3, 2, 1 }, ClipID{ "00001111", "00001000" } }, - { UnwrappedTileID{ 4, 0, 2 }, ClipID{ "00001111", "00001001" } }, - { UnwrappedTileID{ 4, 0, 3 }, ClipID{ "00001111", "00001010" } }, - { UnwrappedTileID{ 4, 1, 2 }, ClipID{ "00001111", "00001011" } }, - { UnwrappedTileID{ 4, 1, 3 }, ClipID{ "00001111", "00001100" } }, - }), - clipIDs); -} - -TEST(GenerateClipIDs, Bug206) { - std::vector renderables{ - Renderable{ UnwrappedTileID{ 10, 162, 395 }, {} }, - Renderable{ UnwrappedTileID{ 10, 162, 396 }, {} }, - Renderable{ UnwrappedTileID{ 10, 163, 395 }, {} }, - // begin subtiles of (10/163/395) - Renderable{ UnwrappedTileID{ 11, 326, 791 }, {} }, - Renderable{ UnwrappedTileID{ 12, 654, 1582 }, {} }, - Renderable{ UnwrappedTileID{ 12, 654, 1583 }, {} }, - Renderable{ UnwrappedTileID{ 12, 655, 1582 }, {} }, - Renderable{ UnwrappedTileID{ 12, 655, 1583 }, {} }, - // end subtiles of (10/163/395) - Renderable{ UnwrappedTileID{ 10, 163, 396 }, {} }, - Renderable{ UnwrappedTileID{ 10, 164, 395 }, {} }, - Renderable{ UnwrappedTileID{ 10, 164, 396 }, {} }, - }; - - algorithm::ClipIDGenerator generator; - generator.update(makeSorted(renderables)); - EXPECT_EQ( - decltype(renderables)({ - Renderable{ UnwrappedTileID{ 10, 162, 395 }, ClipID{ "00001111", "00000001" } }, - Renderable{ UnwrappedTileID{ 10, 162, 396 }, ClipID{ "00001111", "00000010" } }, - Renderable{ UnwrappedTileID{ 10, 163, 395 }, ClipID{ "00001111", "00000011" } }, - Renderable{ UnwrappedTileID{ 11, 326, 791 }, ClipID{ "00001111", "00000111" } }, - Renderable{ UnwrappedTileID{ 12, 654, 1582 }, ClipID{ "00001111", "00001000" } }, - Renderable{ UnwrappedTileID{ 12, 654, 1583 }, ClipID{ "00001111", "00001001" } }, - Renderable{ UnwrappedTileID{ 12, 655, 1582 }, ClipID{ "00001111", "00001010" } }, - Renderable{ UnwrappedTileID{ 12, 655, 1583 }, ClipID{ "00001111", "00001011" } }, - Renderable{ UnwrappedTileID{ 10, 163, 396 }, ClipID{ "00001111", "00000100" } }, - Renderable{ UnwrappedTileID{ 10, 164, 395 }, ClipID{ "00001111", "00000101" } }, - Renderable{ UnwrappedTileID{ 10, 164, 396 }, ClipID{ "00001111", "00000110" } }, - }), - renderables); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID{ 10, 162, 395 }, ClipID{ "00001111", "00000001" } }, - { UnwrappedTileID{ 10, 162, 396 }, ClipID{ "00001111", "00000010" } }, - { UnwrappedTileID{ 10, 163, 395 }, ClipID{ "00001111", "00000011" } }, - { UnwrappedTileID{ 10, 163, 396 }, ClipID{ "00001111", "00000100" } }, - { UnwrappedTileID{ 10, 164, 395 }, ClipID{ "00001111", "00000101" } }, - { UnwrappedTileID{ 10, 164, 396 }, ClipID{ "00001111", "00000110" } }, - { UnwrappedTileID{ 11, 326, 791 }, ClipID{ "00001111", "00000111" } }, - { UnwrappedTileID{ 12, 654, 1582 }, ClipID{ "00001111", "00001000" } }, - { UnwrappedTileID{ 12, 654, 1583 }, ClipID{ "00001111", "00001001" } }, - { UnwrappedTileID{ 12, 655, 1582 }, ClipID{ "00001111", "00001010" } }, - { UnwrappedTileID{ 12, 655, 1583 }, ClipID{ "00001111", "00001011" } }, - }), - clipIDs); -} - -TEST(GenerateClipIDs, MultipleSources) { - std::vector renderables1{ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, - Renderable{ UnwrappedTileID{ 1, 1, 1 }, {} }, - // Differing children - Renderable{ UnwrappedTileID{ 2, 2, 1 }, {} }, - Renderable{ UnwrappedTileID{ 2, 2, 2 }, {} }, - }; - std::vector renderables2{ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, - Renderable{ UnwrappedTileID{ 1, 1, 1 }, {} }, - // Differing children - Renderable{ UnwrappedTileID{ 2, 1, 1 }, {} }, - Renderable{ UnwrappedTileID{ 2, 2, 2 }, {} }, - }; - std::vector renderables3{ - Renderable{ UnwrappedTileID{ 1, 0, 0 }, {} }, - Renderable{ UnwrappedTileID{ 1, 0, 1 }, {} }, - Renderable{ UnwrappedTileID{ 1, 1, 0 }, {} }, - Renderable{ UnwrappedTileID{ 1, 1, 1 }, {} }, - // Differing children - Renderable{ UnwrappedTileID{ 2, 1, 1 }, {} }, - }; - - algorithm::ClipIDGenerator generator; - generator.update({ renderables1.begin(), renderables1.end() }); - generator.update({ renderables2.begin(), renderables2.end() }); - generator.update({ renderables3.begin(), renderables3.end() }); - EXPECT_EQ(decltype(renderables1)({ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000111", "00000001" } }, - Renderable{ UnwrappedTileID{ 1, 1, 1 }, ClipID{ "00000111", "00000010" } }, - Renderable{ UnwrappedTileID{ 2, 2, 1 }, ClipID{ "00000111", "00000011" } }, - Renderable{ UnwrappedTileID{ 2, 2, 2 }, ClipID{ "00000111", "00000100" } }, - }), - renderables1); - EXPECT_EQ(decltype(renderables2)({ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00011000", "00001000" } }, - Renderable{ UnwrappedTileID{ 1, 1, 1 }, ClipID{ "00011111", "00000010" } }, - Renderable{ UnwrappedTileID{ 2, 1, 1 }, ClipID{ "00011000", "00010000" } }, - Renderable{ UnwrappedTileID{ 2, 2, 2 }, ClipID{ "00011111", "00000100" } }, - }), - renderables2); - EXPECT_EQ(decltype(renderables3)({ - Renderable{ UnwrappedTileID{ 1, 0, 0 }, ClipID{ "11100000", "00100000" } }, - Renderable{ UnwrappedTileID{ 1, 0, 1 }, ClipID{ "11100000", "01000000" } }, - Renderable{ UnwrappedTileID{ 1, 1, 0 }, ClipID{ "11100000", "01100000" } }, - Renderable{ UnwrappedTileID{ 1, 1, 1 }, ClipID{ "11100000", "10000000" } }, - Renderable{ UnwrappedTileID{ 2, 1, 1 }, ClipID{ "11111000", "00010000" } }, - }), - renderables3); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID{ 1, 0, 0 }, ClipID{ "11111111", "00101001" } }, - { UnwrappedTileID{ 1, 0, 1 }, ClipID{ "11111111", "01001001" } }, - { UnwrappedTileID{ 1, 1, 0 }, ClipID{ "11111111", "01101001" } }, - { UnwrappedTileID{ 1, 1, 1 }, ClipID{ "11111111", "10000010" } }, - { UnwrappedTileID{ 2, 1, 1 }, ClipID{ "11111111", "00010001" } }, - { UnwrappedTileID{ 2, 2, 1 }, ClipID{ "11111111", "01101011" } }, - { UnwrappedTileID{ 2, 2, 2 }, ClipID{ "11111111", "10000100" } }, - }), - clipIDs); -} - -TEST(GenerateClipIDs, SomeUnclippedTiles) { - std::vector renderables1{ - Renderable { UnwrappedTileID { 7, 36, 49 }, {}, true, true }, - Renderable { UnwrappedTileID { 7, 36, 48 }, {}, true, true }, - Renderable { UnwrappedTileID { 7, 35, 48 }, {}, true, false }, - Renderable { UnwrappedTileID { 7, 35, 49 }, {}, true, false }, - Renderable { UnwrappedTileID { 7, 37, 48 }, {}, true, false }, - Renderable { UnwrappedTileID { 7, 37, 49 }, {}, true, false } - }; - std::vector renderables2{ - Renderable { UnwrappedTileID { 7, 36, 49 }, {}, true, true }, - Renderable { UnwrappedTileID { 7, 36, 48 }, {}, true, true } - }; - - algorithm::ClipIDGenerator generator; - generator.update(makeSorted(renderables1)); - generator.update(makeSorted(renderables2)); - EXPECT_EQ(decltype(renderables1)({ - Renderable { UnwrappedTileID { 7, 36, 49 }, ClipID {"00000011","00000010"} }, - Renderable { UnwrappedTileID { 7, 36, 48 }, ClipID {"00000011","00000001"} }, - Renderable { UnwrappedTileID { 7, 35, 48 }, ClipID {"00000000","00000000"} }, - Renderable { UnwrappedTileID { 7, 35, 49 }, ClipID {"00000000","00000000"} }, - Renderable { UnwrappedTileID { 7, 37, 48 }, ClipID {"00000000","00000000"} }, - Renderable { UnwrappedTileID { 7, 37, 49 }, ClipID {"00000000","00000000"} } - }), - renderables1); - EXPECT_EQ(decltype(renderables2)({ - Renderable { UnwrappedTileID { 7, 36, 49 }, ClipID {"00000011","00000010"} }, - Renderable { UnwrappedTileID { 7, 36, 48 }, ClipID {"00000011","00000001"} } - }), - renderables2); - - const auto clipIDs = generator.getClipIDs(); - - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID { 7, 36, 48 }, ClipID {"00000011","00000001"} }, - { UnwrappedTileID { 7, 36, 49 }, ClipID {"00000011","00000010"} } - }), - clipIDs); -} - -TEST(GenerateClipIDs, DuplicateIDs) { - std::vector renderables1{ - Renderable{ UnwrappedTileID{ 2, 0, 0 }, {} }, - Renderable{ UnwrappedTileID{ 2, 0, 1 }, {} }, - }; - std::vector renderables2{ - Renderable{ UnwrappedTileID{ 2, 0, 0 }, {} }, - Renderable{ UnwrappedTileID{ 2, 0, 1 }, {} }, - Renderable{ UnwrappedTileID{ 2, 0, 1 }, {} }, - }; - - algorithm::ClipIDGenerator generator; - generator.update({ renderables1.begin(), renderables1.end() }); - generator.update({ renderables2.begin(), renderables2.end() }); - EXPECT_EQ(decltype(renderables1)({ - Renderable{ UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000011", "00000001" } }, - Renderable{ UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000011", "00000010" } }, - }), - renderables1); - EXPECT_EQ(decltype(renderables2)({ - Renderable{ UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000011", "00000001" } }, - Renderable{ UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000011", "00000010" } }, - Renderable{ UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000011", "00000010" } }, - }), - renderables2); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID{ 2, 0, 0 }, ClipID{ "00000011", "00000001" } }, - { UnwrappedTileID{ 2, 0, 1 }, ClipID{ "00000011", "00000010" } }, - }), - clipIDs); -} - -TEST(GenerateClipIDs, SecondSourceHasParentOfFirstSource) { - std::vector renderables1{ - Renderable{ UnwrappedTileID{ 1, 0, 0 }, {} }, - }; - std::vector renderables2{ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, - // Same as in renderables1, but has a parent that it knocks out. - Renderable{ UnwrappedTileID{ 1, 0, 0 }, {} }, - }; - std::vector renderables3{ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, {} }, - }; - - algorithm::ClipIDGenerator generator; - generator.update({ renderables1.begin(), renderables1.end() }); - generator.update({ renderables2.begin(), renderables2.end() }); - generator.update({ renderables3.begin(), renderables3.end() }); - EXPECT_EQ(decltype(renderables1)({ - Renderable{ UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000001", "00000001" } }, - }), - renderables1); - EXPECT_EQ(decltype(renderables2)({ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000010", "00000010" } }, - Renderable{ UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000011", "00000001" } }, - }), - renderables2); - EXPECT_EQ(decltype(renderables3)({ - Renderable{ UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000100", "00000100" } }, - }), - renderables3); - - const auto clipIDs = generator.getClipIDs(); - EXPECT_EQ(decltype(clipIDs)({ - { UnwrappedTileID{ 0, 0, 0 }, ClipID{ "00000110", "00000110" } }, - { UnwrappedTileID{ 1, 0, 0 }, ClipID{ "00000111", "00000101" } }, - }), - clipIDs); -} diff --git a/test/test-files.json b/test/test-files.json index df46689d50..948cccfa4a 100644 --- a/test/test-files.json +++ b/test/test-files.json @@ -3,8 +3,6 @@ "sources": [ "test/actor/actor.test.cpp", "test/actor/actor_ref.test.cpp", - "test/algorithm/covered_by_children.test.cpp", - "test/algorithm/generate_clip_ids.test.cpp", "test/algorithm/update_renderables.test.cpp", "test/algorithm/update_tile_masks.test.cpp", "test/api/annotations.test.cpp", -- cgit v1.2.1