From f63fa491521dcee34b6ef90dcd6a57ae1342813d Mon Sep 17 00:00:00 2001 From: mwilsnd <53413200+mwilsnd@users.noreply.github.com> Date: Thu, 25 May 2023 15:32:21 -0500 Subject: [PATCH] Drawable LayerGroup sorting, depth buffer, split view (#1173) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- include/mbgl/renderer/change_request.hpp | 13 ++ include/mbgl/renderer/layer_group.hpp | 1 + src/mbgl/gl/layer_group_gl.cpp | 4 - src/mbgl/renderer/change_request.cpp | 12 ++ src/mbgl/renderer/layer_group.cpp | 7 + .../layers/render_background_layer.cpp | 20 +-- .../layers/render_background_layer.hpp | 4 +- .../renderer/layers/render_circle_layer.cpp | 14 +- .../renderer/layers/render_circle_layer.hpp | 4 +- .../renderer/layers/render_fill_layer.cpp | 17 +-- .../renderer/layers/render_fill_layer.hpp | 4 +- src/mbgl/renderer/render_layer.cpp | 33 +++++ src/mbgl/renderer/render_layer.hpp | 21 ++- src/mbgl/renderer/render_orchestrator.cpp | 49 +++++-- src/mbgl/renderer/render_orchestrator.hpp | 6 + src/mbgl/renderer/renderer_impl.cpp | 123 ++++++++++++++---- vendor/mapbox-gl-native-curl | 1 + 17 files changed, 244 insertions(+), 89 deletions(-) create mode 160000 vendor/mapbox-gl-native-curl diff --git a/include/mbgl/renderer/change_request.hpp b/include/mbgl/renderer/change_request.hpp index 8014f2d3d..918c014f6 100644 --- a/include/mbgl/renderer/change_request.hpp +++ b/include/mbgl/renderer/change_request.hpp @@ -9,6 +9,7 @@ namespace mbgl { class ChangeRequest; class LayerGroup; +class TileLayerGroup; class RenderOrchestrator; using ChangeRequestPtr = std::shared_ptr; @@ -76,4 +77,16 @@ protected: int32_t layerIndex; }; +class UpdateLayerGroupIndexRequest : public ChangeRequest { +public: + UpdateLayerGroupIndexRequest(std::shared_ptr tileLayerGroup_, int32_t newLayerIndex_); + UpdateLayerGroupIndexRequest(const UpdateLayerGroupIndexRequest &) = delete; + + void execute(RenderOrchestrator &) override; + +protected: + std::shared_ptr tileLayerGroup; + int32_t newLayerIndex; +}; + } // namespace mbgl diff --git a/include/mbgl/renderer/layer_group.hpp b/include/mbgl/renderer/layer_group.hpp index 7c579b019..7710bae5b 100644 --- a/include/mbgl/renderer/layer_group.hpp +++ b/include/mbgl/renderer/layer_group.hpp @@ -76,6 +76,7 @@ public: TileLayerGroup(int32_t layerIndex, std::size_t initialCapacity); ~TileLayerGroup() override; + void updateLayerIndex(int32_t newLayerIndex); std::size_t getDrawableCount() const; const gfx::UniqueDrawable& getDrawable(mbgl::RenderPass, const OverscaledTileID&) const; diff --git a/src/mbgl/gl/layer_group_gl.cpp b/src/mbgl/gl/layer_group_gl.cpp index 21c449cb7..a40593ba0 100644 --- a/src/mbgl/gl/layer_group_gl.cpp +++ b/src/mbgl/gl/layer_group_gl.cpp @@ -54,10 +54,6 @@ void TileLayerGroupGL::upload(gfx::Context& context, gfx::UploadPass& uploadPass void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters) { auto& context = parameters.context; - // TODO: figure out how to make drawables participate in the depth system - // Maybe make it a function mapping draw priority to the depth range (always (0,1)?) - parameters.depthRangeSize = 1 - (1 + 2) * parameters.numSublayers * parameters.depthEpsilon; - // TODO: Render tile masks // for (auto& layer : renderLayers) { // parameters.renderTileClippingMasks(renderTiles); diff --git a/src/mbgl/renderer/change_request.cpp b/src/mbgl/renderer/change_request.cpp index 13a971f18..fef923e72 100644 --- a/src/mbgl/renderer/change_request.cpp +++ b/src/mbgl/renderer/change_request.cpp @@ -18,4 +18,16 @@ void RemoveLayerGroupRequest::execute(RenderOrchestrator &orchestrator) { orchestrator.removeLayerGroup(layerIndex); } +UpdateLayerGroupIndexRequest::UpdateLayerGroupIndexRequest(std::shared_ptr tileLayerGroup_, + int32_t newLayerIndex_) + : tileLayerGroup(std::move(tileLayerGroup_)), + newLayerIndex(newLayerIndex_) {} + +void UpdateLayerGroupIndexRequest::execute(RenderOrchestrator &orchestrator) { + // Update the index of a tile layer group and indicate to the orchestator that it must rebuild the map of ordered + // layer groups + tileLayerGroup->updateLayerIndex(newLayerIndex); + orchestrator.markLayerGroupOrderDirty(); +} + } // namespace mbgl diff --git a/src/mbgl/renderer/layer_group.cpp b/src/mbgl/renderer/layer_group.cpp index fabd070a2..02f7e924f 100644 --- a/src/mbgl/renderer/layer_group.cpp +++ b/src/mbgl/renderer/layer_group.cpp @@ -38,6 +38,13 @@ TileLayerGroup::TileLayerGroup(int32_t layerIndex_, std::size_t initialCapacity) TileLayerGroup::~TileLayerGroup() {} +void TileLayerGroup::updateLayerIndex(int32_t newLayerIndex) { + layerIndex = newLayerIndex; + for (auto& it : impl->tileDrawables) { + it.second->setLayerIndex(newLayerIndex); + } +} + std::size_t TileLayerGroup::getDrawableCount() const { return impl->tileDrawables.size(); } diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index 4c575ff4a..ac031230b 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -75,16 +75,10 @@ bool RenderBackgroundLayer::hasCrossfade() const { return getCrossfade(evaluatedProperties).t != 1; } -static bool enableDefaultRender = false; - void RenderBackgroundLayer::render(PaintParameters& parameters) { // Note that for bottommost layers without a pattern, the background color // is drawn with glClear rather than this method. - if (!enableDefaultRender) { - return; - } - // Ensure programs are available if (!parameters.shaders.populate(backgroundProgram)) return; if (!parameters.shaders.populate(backgroundPatternProgram)) return; @@ -181,8 +175,7 @@ std::optional RenderBackgroundLayer::getSolidBackground() const { return std::nullopt; } - return std::nullopt; - // return { evaluated.get() * evaluated.get() }; + return {evaluated.get() * evaluated.get()}; } namespace { @@ -213,15 +206,11 @@ void RenderBackgroundLayer::layerRemoved(UniqueChangeRequestVec& changes) { } } -void RenderBackgroundLayer::update(const int32_t layerIndex, - gfx::ShaderRegistry& shaders, +void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& state, - UniqueChangeRequestVec& changes) { - if (enableDefaultRender) { - return; - } - + [[maybe_unused]] const RenderTree& renderTree, + [[maybe_unused]] UniqueChangeRequestVec& changes) { std::unique_lock guard(mutex); if (!shader) { @@ -271,7 +260,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex, return; } tileLayerGroup->setLayerTweaker(std::make_shared(evaluatedProperties)); - changes.emplace_back(std::make_unique(tileLayerGroup, /*canReplace=*/true)); } // Drawables per overscaled or canonical tile? diff --git a/src/mbgl/renderer/layers/render_background_layer.hpp b/src/mbgl/renderer/layers/render_background_layer.hpp index 7b6749c8f..d1ffc30d8 100644 --- a/src/mbgl/renderer/layers/render_background_layer.hpp +++ b/src/mbgl/renderer/layers/render_background_layer.hpp @@ -26,10 +26,10 @@ public: void layerRemoved(UniqueChangeRequestVec&) override; /// Generate any changes needed by the layer - void update(int32_t layerIndex, - gfx::ShaderRegistry&, + void update(gfx::ShaderRegistry&, gfx::Context&, const TransformState&, + const RenderTree&, UniqueChangeRequestVec&) override; private: diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index 3795e4bc9..6620eecf4 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -85,15 +85,9 @@ bool RenderCircleLayer::hasCrossfade() const { return false; } -static bool enableDefaultRender = false; - void RenderCircleLayer::render(PaintParameters& parameters) { assert(renderTiles); - if (!enableDefaultRender) { - return; - } - if (parameters.pass == RenderPass::Opaque) { return; } @@ -261,15 +255,11 @@ void RenderCircleLayer::removeTile(RenderPass renderPass, const OverscaledTileID stats.tileDrawablesRemoved += tileLayerGroup->removeDrawables(renderPass, tileID).size(); } -void RenderCircleLayer::update(const int32_t layerIndex, - gfx::ShaderRegistry& shaders, +void RenderCircleLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& /*state*/, + [[maybe_unused]] const RenderTree& renderTree, UniqueChangeRequestVec& changes) { - if (enableDefaultRender) { - return; - } - std::unique_lock guard(mutex); if (!renderTiles || renderTiles->empty()) { diff --git a/src/mbgl/renderer/layers/render_circle_layer.hpp b/src/mbgl/renderer/layers/render_circle_layer.hpp index a34ab1baa..c8786cb72 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.hpp +++ b/src/mbgl/renderer/layers/render_circle_layer.hpp @@ -16,10 +16,10 @@ public: void layerRemoved(UniqueChangeRequestVec&) override; /// Generate any changes needed by the layer - void update(int32_t layerIndex, - gfx::ShaderRegistry&, + void update(gfx::ShaderRegistry&, gfx::Context&, const TransformState&, + const RenderTree&, UniqueChangeRequestVec&) override; private: diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 977674e70..c2d0399a8 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -78,15 +78,9 @@ bool RenderFillLayer::hasCrossfade() const { return getCrossfade(evaluatedProperties).t != 1; } -static bool enableDefaultRender = false; - void RenderFillLayer::render(PaintParameters& parameters) { assert(renderTiles); - if (!enableDefaultRender) { - return; - } - if (!parameters.shaders.populate(fillProgram)) return; if (!parameters.shaders.populate(fillPatternProgram)) return; if (!parameters.shaders.populate(fillOutlineProgram)) return; @@ -284,15 +278,11 @@ void RenderFillLayer::removeTile(RenderPass renderPass, const OverscaledTileID& stats.tileDrawablesRemoved += tileLayerGroup->removeDrawables(renderPass, tileID).size(); } -void RenderFillLayer::update(const int32_t layerIndex, - gfx::ShaderRegistry& shaders, +void RenderFillLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, const TransformState& /*state*/, - UniqueChangeRequestVec& changes) { - if (enableDefaultRender) { - return; - } - + [[maybe_unused]] const RenderTree& renderTree, + [[maybe_unused]] UniqueChangeRequestVec& changes) { std::unique_lock guard(mutex); if (!renderTiles || renderTiles->empty()) { @@ -310,7 +300,6 @@ void RenderFillLayer::update(const int32_t layerIndex, return; } tileLayerGroup->setLayerTweaker(std::make_shared(evaluatedProperties)); - changes.emplace_back(std::make_unique(tileLayerGroup, /*canReplace=*/true)); } if (!fillShader) { diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp index c35812ac7..51c5a9a6b 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_layer.hpp @@ -25,10 +25,10 @@ public: void layerRemoved(UniqueChangeRequestVec&) override; /// Generate any changes needed by the layer - void update(int32_t layerIndex, - gfx::ShaderRegistry&, + void update(gfx::ShaderRegistry&, gfx::Context&, const TransformState&, + const RenderTree&, UniqueChangeRequestVec&) override; private: diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index fb3e2211e..c9d635461 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -31,6 +32,10 @@ const std::string& RenderLayer::getID() const { return baseImpl->id; } +int32_t RenderLayer::getLayerIndex() const noexcept { + return layerIndex; +} + bool RenderLayer::hasRenderPass(RenderPass pass) const { return passes & pass; } @@ -107,4 +112,32 @@ const LayerRenderData* RenderLayer::getRenderDataForPass(const RenderTile& tile, return nullptr; } +void RenderLayer::layerIndexChanged(int32_t newLayerIndex, UniqueChangeRequestVec& changes) { + layerIndex = newLayerIndex; + + // Submit a change request to update the layer index of our tile layer group + if (tileLayerGroup) { + changes.emplace_back(std::make_unique(tileLayerGroup, newLayerIndex)); + } +} + +void RenderLayer::markLayerRenderable(bool willRender, UniqueChangeRequestVec& changes) { + if (!tileLayerGroup) { + return; + } + if (isRenderable == willRender) { + return; + } + + // This layer is either being freshly included in the renderable set or excluded + isRenderable = willRender; + if (willRender) { + // The RenderTree has determined this layer should be included in the renderable set for a frame + changes.emplace_back(std::make_unique(tileLayerGroup, /*canReplace=*/true)); + } else { + // The RenderTree is informing us we should not render anything + changes.emplace_back(std::make_unique(tileLayerGroup->getLayerIndex())); + } +} + } // namespace mbgl diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 6d367da9d..5a7f32185 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -21,6 +21,7 @@ class PropertyEvaluationParameters; class PaintParameters; class PatternAtlas; class RenderTile; +class RenderTree; class SymbolBucket; class TileLayerGroup; class TransformState; @@ -101,6 +102,8 @@ public: const std::string& getID() const; + int32_t getLayerIndex() const noexcept; + // Checks whether this layer needs to be rendered in the given render pass. bool hasRenderPass(RenderPass) const; @@ -143,10 +146,22 @@ public: /// Generate any changes needed by the layer virtual void update( - int32_t /*layerIndex*/, gfx::ShaderRegistry&, gfx::Context&, const TransformState&, UniqueChangeRequestVec&) {} + gfx::ShaderRegistry&, gfx::Context&, const TransformState&, const RenderTree&, UniqueChangeRequestVec&) {} virtual void layerRemoved(UniqueChangeRequestVec&) {} + /// @brief Called by the RenderOrchestrator during RenderTree construction. + /// This event is run when a layer is added or removed from the style. + /// @param newLayerIndex The new layer index for this layer + /// @param changes The collection of current pending change requests + virtual void layerIndexChanged(int32_t newLayerIndex, UniqueChangeRequestVec& changes); + + /// @brief Called by the RenderOrchestrator during RenderTree construction. + /// This event is run to indicate if the layer should render or not for the current frame. + /// @param willRender Indicates if this layer should render or not + /// @param changes The collection of current pending change requests + virtual void markLayerRenderable(bool willRender, UniqueChangeRequestVec& changes); + protected: // Checks whether the current hardware can render this layer. If it can't, // we'll show a warning in the console to inform the developer. @@ -167,6 +182,10 @@ protected: LayerPlacementData placementData; TileLayerGroupPtr tileLayerGroup; + // Current layer index as specified by the layerIndexChanged event + int32_t layerIndex{0}; + // Current renderable status as specified by the markLayerRenderable event + bool isRenderable{false}; std::mutex mutex; diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index 305591cad..33f1a05fa 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -233,8 +233,6 @@ std::unique_ptr RenderOrchestrator::createRenderTree( } } - addChanges(changes); - // Create render layers for newly added layers. for (const auto& entry : layerDiff.added) { auto renderLayer = LayerManager::get()->createRenderLayer(entry.second); @@ -250,10 +248,14 @@ std::unique_ptr RenderOrchestrator::createRenderTree( if (layersAddedOrRemoved) { orderedLayers.clear(); orderedLayers.reserve(layerImpls->size()); + int32_t layerIndex = 0; for (const auto& layerImpl : *layerImpls) { RenderLayer* layer = renderLayers.at(layerImpl->id).get(); assert(layer); orderedLayers.emplace_back(*layer); + + // We're mutating the list of ordered layers and must notify them of their new assigned indices + layer->layerIndexChanged(layerIndex++, changes); } } assert(orderedLayers.size() == renderLayers.size()); @@ -336,6 +338,7 @@ std::unique_ptr RenderOrchestrator::createRenderTree( } } } + continue; } @@ -357,6 +360,18 @@ std::unique_ptr RenderOrchestrator::createRenderTree( filteredLayersForSource.clear(); } + // Mark layers included in the renderable set as renderable + // @TODO: Optimize this logic, combine with the above + for (size_t i = 0; i < orderedLayers.size(); ++i) { + RenderLayer& layer = orderedLayers[i]; + layer.markLayerRenderable( + layerRenderItems.find(LayerRenderItem(layer, nullptr, static_cast(i))) != layerRenderItems.end(), + changes); + } + + // Add all change requests up to this point + addChanges(changes); + renderTreeParameters->loaded = updateParameters->styleLoaded && isLoaded(); if (!isMapModeContinuous && !renderTreeParameters->loaded) { return nullptr; @@ -778,6 +793,16 @@ const gfx::DrawablePtr& RenderOrchestrator::getDrawable(const util::SimpleIdenti void RenderOrchestrator::onRemoveLayerGroup(LayerGroup&) {} +void RenderOrchestrator::updateLayerGroupOrder() { + // In the event layer indices change for layer groups, we must re-sort them + LayerGroupMap newMap; + for (auto& it : layerGroupsByLayerIndex) { + newMap.emplace(it.second->getLayerIndex(), it.second); + } + layerGroupsByLayerIndex = std::move(newMap); + layerGroupOrderDirty = false; +} + bool RenderOrchestrator::addLayerGroup(LayerGroupPtr layerGroup, const bool replace) { const auto index = layerGroup->getLayerIndex(); const auto result = layerGroupsByLayerIndex.insert(std::make_pair(index, LayerGroupPtr{})); @@ -808,6 +833,10 @@ bool RenderOrchestrator::removeLayerGroup(const int32_t layerIndex) { } } +size_t RenderOrchestrator::numLayerGroups() const noexcept { + return layerGroupsByLayerIndex.size(); +} + static const LayerGroupPtr no_group; const LayerGroupPtr& RenderOrchestrator::getLayerGroup(const int32_t layerIndex) const { @@ -847,15 +876,9 @@ void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders, }; std::vector> changes; - - // Layer index, similar but not identical to `layerRenderItems` index in render_impl - // int32_t i = static_cast(layerRenderItems.size()) - 1; - // for (auto it = layerRenderItems.begin(); it != layerRenderItems.end() && i >= 0; ++it, --i) { - auto index = static_cast(renderTree.getLayerRenderItems().size()) - 1; - for (const auto& item : renderTree.getLayerRenderItems()) { auto& renderLayer = static_cast(item.get()).layer.get(); - renderLayer.update(index--, shaders, context, state, changes); + renderLayer.update(shaders, context, state, renderTree, changes); } addChanges(changes); @@ -866,6 +889,14 @@ void RenderOrchestrator::processChanges() { for (auto& change : localChanges) { change->execute(*this); } + + if (layerGroupOrderDirty) { + updateLayerGroupOrder(); + } +} + +void RenderOrchestrator::markLayerGroupOrderDirty() { + layerGroupOrderDirty = true; } void RenderOrchestrator::onGlyphsError(const FontStack& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) { diff --git a/src/mbgl/renderer/render_orchestrator.hpp b/src/mbgl/renderer/render_orchestrator.hpp index e210539c6..16aabb426 100644 --- a/src/mbgl/renderer/render_orchestrator.hpp +++ b/src/mbgl/renderer/render_orchestrator.hpp @@ -105,6 +105,7 @@ public: bool addLayerGroup(LayerGroupPtr, bool replace); bool removeLayerGroup(const int32_t layerIndex); + size_t numLayerGroups() const noexcept; const LayerGroupPtr& getLayerGroup(const int32_t layerIndex) const; void observeLayerGroups(std::function); void observeLayerGroups(std::function) const; @@ -116,6 +117,8 @@ public: const RenderTree&); void processChanges(); + /// @brief Indicate that the orchestrator needs to re-sort layer groups when processing changes + void markLayerGroupOrderDirty(); const ZoomHistory& getZoomHistory() const { return zoomHistory; } @@ -153,6 +156,8 @@ private: void onRemoveLayerGroup(LayerGroup&); + void updateLayerGroupOrder(); + RendererObserver* observer; ZoomHistory zoomHistory; @@ -189,6 +194,7 @@ private: using LayerGroupMap = std::map; LayerGroupMap layerGroupsByLayerIndex; + bool layerGroupOrderDirty = false; }; } // namespace mbgl diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index a50a6853f..aad69f756 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -21,6 +21,16 @@ #include #include +// DEBUG: Enable a debugging split view to compare drawables and vanilla rendering pathways +// Drawables will be on the left, vanilla rendering on the right +// #define SPLIT_VIEW +// If using SPLIT_VIEW, QUAD_SPLIT_VIEW will split each half, showing just the opaque +// pass on top and then a composited opaque+translucent pass on the bottom +// #define QUAD_SPLIT_VIEW +#ifdef SPLIT_VIEW +#include +#endif + namespace mbgl { using namespace style; @@ -184,25 +194,45 @@ void Renderer::Impl::render(const RenderTree& renderTree) { "main buffer", {parameters.backend.getDefaultRenderable(), color, 1.0f, 0}); } - { + // Actually render the layers + + // Drawables + const auto drawableOpaquePass = [&] { + const auto debugGroup(parameters.renderPass->createDebugGroup("drawables-opaque")); parameters.pass = RenderPass::Opaque; parameters.currentLayer = 0; - parameters.opaquePassCutoff = 1; + parameters.depthRangeSize = 1 - (orchestrator.numLayerGroups() + 2) * parameters.numSublayers * + parameters.depthEpsilon; // draw layer groups, opaque pass - const auto debugGroup(parameters.renderPass->createDebugGroup("drawables-opaque")); + orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { + layerGroup.render(orchestrator, parameters); + parameters.currentLayer++; + }); + }; - orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.render(orchestrator, parameters); }); - } + const auto drawableTranslucentPass = [&] { + const auto debugGroup(parameters.renderPass->createDebugGroup("drawables-translucent")); + parameters.pass = RenderPass::Translucent; + parameters.currentLayer = static_cast(orchestrator.numLayerGroups()) - 1; + parameters.depthRangeSize = 1 - (orchestrator.numLayerGroups() + 2) * parameters.numSublayers * + parameters.depthEpsilon; - // Actually render the layers - parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff; - parameters.depthRangeSize = 1 - (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon; + // draw layer groups, translucent pass + orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { + layerGroup.render(orchestrator, parameters); + if (parameters.currentLayer != 0) { + parameters.currentLayer--; + } + }); + }; - // - OPAQUE PASS ------------------------------------------------------------------------------- // Render everything top-to-bottom by using reverse iterators. Render opaque objects first. - { + const auto renderLayerOpaquePass = [&] { const auto debugGroup(parameters.renderPass->createDebugGroup("opaque")); + parameters.pass = RenderPass::Opaque; + parameters.depthRangeSize = 1 - + (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon; uint32_t i = 0; for (auto it = layerRenderItems.rbegin(); it != layerRenderItems.rend(); ++it, ++i) { @@ -213,25 +243,14 @@ void Renderer::Impl::render(const RenderTree& renderTree) { renderItem.render(parameters); } } - } + }; - { - parameters.pass = RenderPass::Translucent; - parameters.currentLayer = 1; - parameters.opaquePassCutoff = 1; - - // draw layer groups, translucent pass - const auto debugGroup(parameters.renderPass->createDebugGroup("drawables-translucent")); - - orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.render(orchestrator, parameters); }); - - parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff; - } - - // - TRANSLUCENT PASS -------------------------------------------------------------------------- // Make a second pass, rendering translucent objects. This time, we render bottom-to-top. - { + const auto renderLayerTranslucentPass = [&] { const auto debugGroup(parameters.renderPass->createDebugGroup("translucent")); + parameters.pass = RenderPass::Translucent; + parameters.depthRangeSize = 1 - + (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon; int32_t i = static_cast(layerRenderItems.size()) - 1; for (auto it = layerRenderItems.begin(); it != layerRenderItems.end() && i >= 0; ++it, --i) { @@ -242,7 +261,57 @@ void Renderer::Impl::render(const RenderTree& renderTree) { renderItem.render(parameters); } } - } + }; + +#ifdef SPLIT_VIEW + [[maybe_unused]] const auto W = backend.getDefaultRenderable().getSize().width; + [[maybe_unused]] const auto H = backend.getDefaultRenderable().getSize().height; + [[maybe_unused]] const auto halfW = static_cast(backend.getDefaultRenderable().getSize().width * + 0.5f); + [[maybe_unused]] const auto halfH = static_cast(backend.getDefaultRenderable().getSize().height * + 0.5f); + platform::glEnable(GL_SCISSOR_TEST); +#ifdef QUAD_SPLIT_VIEW + // Drawable LayerGroups on the left + // Opaque only on top + platform::glScissor(0, 0, halfW, H); + drawableOpaquePass(); + + // Composite (Opaque+Translucent) on bottom + platform::glScissor(0, 0, halfW, halfH); + drawableTranslucentPass(); + + // RenderLayers on the right + // Opaque only on top + platform::glScissor(halfW, 0, halfW, H); + renderLayerOpaquePass(); + + // Composite (Opaque+Translucent) on bottom + platform::glScissor(halfW, 0, halfW, halfH); + renderLayerTranslucentPass(); +#else + // Drawable LayerGroups on the left + platform::glScissor(0, 0, halfW, H); + drawableOpaquePass(); + drawableTranslucentPass(); + + // RenderLayers on the right + platform::glScissor(halfW, 0, W, H); + renderLayerOpaquePass(); + renderLayerTranslucentPass(); +#endif + // Reset viewport + platform::glScissor(0, 0, W, H); + platform::glDisable(GL_SCISSOR_TEST); +#else // ifdef SPLIT_VIEW + + // Do RenderLayers first, drawables last + renderLayerOpaquePass(); + drawableOpaquePass(); + + renderLayerTranslucentPass(); + drawableTranslucentPass(); +#endif // - DEBUG PASS -------------------------------------------------------------------------------- // Renders debug overlays. diff --git a/vendor/mapbox-gl-native-curl b/vendor/mapbox-gl-native-curl new file mode 160000 index 000000000..674a741b1 --- /dev/null +++ b/vendor/mapbox-gl-native-curl @@ -0,0 +1 @@ +Subproject commit 674a741b1bfa6f7c6e8bb694ba0295365c8e2096