[core] Synchronize render passes and render tiles
Before this change render passes were assigned for the whole layer at properties evaluation stage. This caused problems, as layer render data are bound to the tile and these data might differ from tile to tile, depending on which tile has been updated by the tile worker and which has not been yet updated. This change takes into consideration the actual render passes required for each tile and combines them for the layer render passes. Naturally, this change also introduces render pass check for each render layer in `RenderLayer::render()` implementations.
This commit is contained in:
@@ -16,6 +16,8 @@ public:
|
||||
// Returns constants mask for the data-driven properties.
|
||||
virtual unsigned long constantsMask() const { return 0u; }
|
||||
Immutable<Layer::Impl> baseImpl;
|
||||
// Contains render passes used by the renderer, see `mbgl::RenderPass`.
|
||||
uint8_t renderPasses = 0u;
|
||||
|
||||
protected:
|
||||
LayerProperties(Immutable<Layer::Impl> impl) : baseImpl(std::move(impl)) {}
|
||||
|
||||
@@ -39,6 +39,7 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters ¶met
|
||||
|
||||
passes = properties->evaluated.get<style::BackgroundOpacity>() > 0 ? RenderPass::Translucent
|
||||
: RenderPass::None;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -133,8 +134,8 @@ void RenderBackgroundLayer::render(PaintParameters& parameters) {
|
||||
}
|
||||
|
||||
optional<Color> RenderBackgroundLayer::getSolidBackground() const {
|
||||
const auto& evaluated = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
if (!evaluated.get<BackgroundPattern>().from.empty()) {
|
||||
const auto& evaluated = getEvaluated<BackgroundLayerProperties>(evaluatedProperties);
|
||||
if (!evaluated.get<BackgroundPattern>().from.empty() || evaluated.get<style::BackgroundOpacity>() <= 0.0f) {
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
@@ -152,7 +153,7 @@ void addPatternIfNeeded(const std::string& id, const LayerPrepareParameters& par
|
||||
} // namespace
|
||||
|
||||
void RenderBackgroundLayer::prepare(const LayerPrepareParameters& params) {
|
||||
const auto& evaluated = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
const auto& evaluated = getEvaluated<BackgroundLayerProperties>(evaluatedProperties);
|
||||
if (!evaluated.get<BackgroundPattern>().to.empty()) {
|
||||
// Ensures that the pattern bitmap gets copied to atlas bitmap.
|
||||
// Atlas bitmap is uploaded to atlas texture in upload.
|
||||
|
||||
@@ -41,6 +41,7 @@ void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters)
|
||||
&& (evaluated.get<style::CircleOpacity>().constantOr(1) > 0 ||
|
||||
evaluated.get<style::CircleStrokeOpacity>().constantOr(1) > 0))
|
||||
? RenderPass::Translucent : RenderPass::None;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -59,7 +60,7 @@ void RenderCircleLayer::render(PaintParameters& parameters) {
|
||||
}
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& para
|
||||
passes = (properties->evaluated.get<style::FillExtrusionOpacity>() > 0)
|
||||
? (RenderPass::Translucent | RenderPass::Pass3D)
|
||||
: RenderPass::None;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
|
||||
const auto& evaluated = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
const auto& crossfade = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).crossfade;
|
||||
if (evaluated.get<FillExtrusionOpacity>() == 0) {
|
||||
if (evaluatedProperties->renderPasses == mbgl::underlying_type(RenderPass::None)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -121,7 +122,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
// Draw solid color extrusions
|
||||
auto drawTiles = [&](const gfx::StencilMode& stencilMode_, const gfx::ColorMode& colorMode_, const std::string& name) {
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
@@ -168,7 +169,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(mbgl::Faded<std::basic_string<char> >{"", ""});
|
||||
auto drawTiles = [&](const gfx::StencilMode& stencilMode_, const gfx::ColorMode& colorMode_, const std::string& name) {
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
} else {
|
||||
passes |= RenderPass::Opaque;
|
||||
}
|
||||
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ void RenderFillLayer::render(PaintParameters& parameters) {
|
||||
if (unevaluated.get<FillPattern>().isUndefined()) {
|
||||
parameters.renderTileClippingMasks(renderTiles);
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ void RenderFillLayer::render(PaintParameters& parameters) {
|
||||
parameters.renderTileClippingMasks(renderTiles);
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters
|
||||
passes = (properties->evaluated.get<style::HeatmapOpacity>() > 0)
|
||||
? (RenderPass::Translucent | RenderPass::Pass3D)
|
||||
: RenderPass::None;
|
||||
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters) {
|
||||
"heatmap texture", { *renderTexture, Color{ 0.0f, 0.0f, 0.0f, 1.0f }, {}, {} });
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& paramete
|
||||
passes = (properties->evaluated.get<style::HillshadeExaggeration >() > 0)
|
||||
? (RenderPass::Translucent | RenderPass::Pass3D)
|
||||
: RenderPass::None;
|
||||
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ bool RenderHillshadeLayer::hasCrossfade() const {
|
||||
}
|
||||
|
||||
void RenderHillshadeLayer::prepare(const LayerPrepareParameters& params) {
|
||||
RenderLayer::prepare(params);
|
||||
renderTiles = params.source->getRenderTiles();
|
||||
maxzoom = params.source->getMaxZoom();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
&& evaluated.get<style::LineColor>().constantOr(Color::black()).a > 0
|
||||
&& evaluated.get<style::LineWidth>().constantOr(1.0) > 0)
|
||||
? RenderPass::Translucent : RenderPass::None;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ void RenderLineLayer::render(PaintParameters& parameters) {
|
||||
parameters.renderTileClippingMasks(renderTiles);
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters)
|
||||
staticImmutableCast<RasterLayer::Impl>(baseImpl),
|
||||
unevaluated.evaluate(parameters));
|
||||
passes = properties->evaluated.get<style::RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ void RenderSymbolLayer::evaluate(const PropertyEvaluationParameters& parameters)
|
||||
passes = ((evaluated.get<style::IconOpacity>().constantOr(1) > 0 && hasIconOpacity && iconSize > 0)
|
||||
|| (evaluated.get<style::TextOpacity>().constantOr(1) > 0 && hasTextOpacity && textSize > 0))
|
||||
? RenderPass::Translucent : RenderPass::None;
|
||||
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters) {
|
||||
};
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
@@ -495,7 +495,7 @@ style::TextPaintProperties::PossiblyEvaluated RenderSymbolLayer::textPaintProper
|
||||
|
||||
void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
|
||||
renderTiles = params.source->getRenderTilesSortedByYPosition();
|
||||
assert(renderTiles);
|
||||
addRenderPassesFromTiles();
|
||||
|
||||
placementData.clear();
|
||||
for (const RenderTile& renderTile : *renderTiles) {
|
||||
|
||||
@@ -48,7 +48,7 @@ bool RenderLayer::supportsZoom(float zoom) const {
|
||||
void RenderLayer::prepare(const LayerPrepareParameters& params) {
|
||||
assert(params.source);
|
||||
renderTiles = params.source->getRenderTiles();
|
||||
assert(renderTiles);
|
||||
addRenderPassesFromTiles();
|
||||
}
|
||||
|
||||
optional<Color> RenderLayer::getSolidBackground() const {
|
||||
@@ -86,5 +86,21 @@ void RenderLayer::checkRenderability(const PaintParameters& parameters,
|
||||
}
|
||||
}
|
||||
|
||||
void RenderLayer::addRenderPassesFromTiles() {
|
||||
assert(renderTiles);
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
if (const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl)) {
|
||||
passes |= RenderPass(renderData->layerProperties->renderPasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LayerRenderData* RenderLayer::getRenderDataForPass(const RenderTile& tile, RenderPass pass) const {
|
||||
if (const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl)) {
|
||||
return bool(RenderPass(renderData->layerProperties->renderPasses) & pass) ? renderData : nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} //namespace mbgl
|
||||
|
||||
|
||||
@@ -117,6 +117,10 @@ protected:
|
||||
// in the console to inform the developer.
|
||||
void checkRenderability(const PaintParameters&, uint32_t activeBindingCount);
|
||||
|
||||
void addRenderPassesFromTiles();
|
||||
|
||||
const LayerRenderData* getRenderDataForPass(const RenderTile&, RenderPass) const;
|
||||
|
||||
protected:
|
||||
// Stores current set of tiles to be rendered for this layer.
|
||||
RenderTiles renderTiles;
|
||||
|
||||
@@ -292,14 +292,14 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
|
||||
const Immutable<Layer::Impl>& layerImpl = *it;
|
||||
RenderLayer* layer = getRenderLayer(layerImpl->id);
|
||||
const auto* layerInfo = layerImpl->getTypeInfo();
|
||||
const bool layerNeedsRendering = layer->needsRendering();
|
||||
const bool layerIsVisible = layer->baseImpl->visibility != style::VisibilityType::None;
|
||||
const bool zoomFitsLayer = layer->supportsZoom(zoomHistory.lastZoom);
|
||||
renderTreeParameters->has3D |= (layerInfo->pass3d == LayerTypeInfo::Pass3D::Required);
|
||||
|
||||
if (layerInfo->source != LayerTypeInfo::Source::NotRequired) {
|
||||
if (layerImpl->source == sourceImpl->id) {
|
||||
sourceNeedsRelayout = (sourceNeedsRelayout || hasImageDiff || constantsMaskChanged.count(layerImpl->id) || hasLayoutDifference(layerDiff, layerImpl->id));
|
||||
if (layerNeedsRendering) {
|
||||
if (layerIsVisible) {
|
||||
filteredLayersForSource.push_back(layer->evaluatedProperties);
|
||||
if (zoomFitsLayer) {
|
||||
sourceNeedsRendering = true;
|
||||
@@ -311,7 +311,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
|
||||
}
|
||||
|
||||
// Handle layers without source.
|
||||
if (layerNeedsRendering && zoomFitsLayer && sourceImpl.get() == sourceImpls->at(0).get()) {
|
||||
if (layerIsVisible && zoomFitsLayer && sourceImpl.get() == sourceImpls->at(0).get()) {
|
||||
if (backgroundLayerAsColor && layerImpl.get() == layerImpls->at(0).get()) {
|
||||
const auto& solidBackground = layer->getSolidBackground();
|
||||
if (solidBackground) {
|
||||
|
||||
Reference in New Issue
Block a user