Drawable LayerGroup sorting, depth buffer, split view (#1173)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
namespace mbgl {
|
||||
class ChangeRequest;
|
||||
class LayerGroup;
|
||||
class TileLayerGroup;
|
||||
class RenderOrchestrator;
|
||||
|
||||
using ChangeRequestPtr = std::shared_ptr<ChangeRequest>;
|
||||
@@ -76,4 +77,16 @@ protected:
|
||||
int32_t layerIndex;
|
||||
};
|
||||
|
||||
class UpdateLayerGroupIndexRequest : public ChangeRequest {
|
||||
public:
|
||||
UpdateLayerGroupIndexRequest(std::shared_ptr<TileLayerGroup> tileLayerGroup_, int32_t newLayerIndex_);
|
||||
UpdateLayerGroupIndexRequest(const UpdateLayerGroupIndexRequest &) = delete;
|
||||
|
||||
void execute(RenderOrchestrator &) override;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<TileLayerGroup> tileLayerGroup;
|
||||
int32_t newLayerIndex;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -18,4 +18,16 @@ void RemoveLayerGroupRequest::execute(RenderOrchestrator &orchestrator) {
|
||||
orchestrator.removeLayerGroup(layerIndex);
|
||||
}
|
||||
|
||||
UpdateLayerGroupIndexRequest::UpdateLayerGroupIndexRequest(std::shared_ptr<TileLayerGroup> 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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -75,16 +75,10 @@ bool RenderBackgroundLayer::hasCrossfade() const {
|
||||
return getCrossfade<BackgroundLayerProperties>(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<Color> RenderBackgroundLayer::getSolidBackground() const {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
// return { evaluated.get<BackgroundColor>() * evaluated.get<BackgroundOpacity>() };
|
||||
return {evaluated.get<BackgroundColor>() * evaluated.get<BackgroundOpacity>()};
|
||||
}
|
||||
|
||||
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<std::mutex> guard(mutex);
|
||||
|
||||
if (!shader) {
|
||||
@@ -271,7 +260,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
return;
|
||||
}
|
||||
tileLayerGroup->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(evaluatedProperties));
|
||||
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
||||
}
|
||||
|
||||
// Drawables per overscaled or canonical tile?
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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<std::mutex> guard(mutex);
|
||||
|
||||
if (!renderTiles || renderTiles->empty()) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -78,15 +78,9 @@ bool RenderFillLayer::hasCrossfade() const {
|
||||
return getCrossfade<FillLayerProperties>(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<std::mutex> guard(mutex);
|
||||
|
||||
if (!renderTiles || renderTiles->empty()) {
|
||||
@@ -310,7 +300,6 @@ void RenderFillLayer::update(const int32_t layerIndex,
|
||||
return;
|
||||
}
|
||||
tileLayerGroup->setLayerTweaker(std::make_shared<FillLayerTweaker>(evaluatedProperties));
|
||||
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
||||
}
|
||||
|
||||
if (!fillShader) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/renderer/change_request.hpp>
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
#include <mbgl/renderer/layer_group.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
@@ -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<UpdateLayerGroupIndexRequest>(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<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
||||
} else {
|
||||
// The RenderTree is informing us we should not render anything
|
||||
changes.emplace_back(std::make_unique<RemoveLayerGroupRequest>(tileLayerGroup->getLayerIndex()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -233,8 +233,6 @@ std::unique_ptr<RenderTree> 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<RenderTree> 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<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -357,6 +360,18 @@ std::unique_ptr<RenderTree> 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<uint32_t>(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<std::unique_ptr<ChangeRequest>> changes;
|
||||
|
||||
// Layer index, similar but not identical to `layerRenderItems` index in render_impl
|
||||
// int32_t i = static_cast<int32_t>(layerRenderItems.size()) - 1;
|
||||
// for (auto it = layerRenderItems.begin(); it != layerRenderItems.end() && i >= 0; ++it, --i) {
|
||||
auto index = static_cast<int32_t>(renderTree.getLayerRenderItems().size()) - 1;
|
||||
|
||||
for (const auto& item : renderTree.getLayerRenderItems()) {
|
||||
auto& renderLayer = static_cast<const LayerRenderItem&>(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) {
|
||||
|
||||
@@ -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(LayerGroup&)>);
|
||||
void observeLayerGroups(std::function<void(const LayerGroup&)>) 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<int32_t, LayerGroupPtr>;
|
||||
LayerGroupMap layerGroupsByLayerIndex;
|
||||
bool layerGroupOrderDirty = false;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -21,6 +21,16 @@
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
// 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 <mbgl/gl/context.hpp>
|
||||
#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<int32_t>(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<int32_t>(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<platform::GLsizei>(backend.getDefaultRenderable().getSize().width *
|
||||
0.5f);
|
||||
[[maybe_unused]] const auto halfH = static_cast<platform::GLsizei>(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.
|
||||
|
||||
1
vendor/mapbox-gl-native-curl
vendored
Submodule
1
vendor/mapbox-gl-native-curl
vendored
Submodule
Submodule vendor/mapbox-gl-native-curl added at 674a741b1b
Reference in New Issue
Block a user