summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-08 12:31:42 +0300
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-08 12:31:42 +0300
commitc1e4bf91f8c3e490336e9722f8e3d8bd63979c6f (patch)
tree7281b8b96b64318b5a1d59b7845a1dfa4ea7adb8
parentb481469394a7c55ec43aeaec5a19622a2fae7df5 (diff)
downloadqtlocation-mapboxgl-c1e4bf91f8c3e490336e9722f8e3d8bd63979c6f.tar.gz
[core] Renderer for RenderFillLayer and RenderFillExtrusionLayer
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp321
-rw-r--r--src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp6
-rw-r--r--src/mbgl/renderer/layers/render_fill_layer.cpp362
-rw-r--r--src/mbgl/renderer/layers/render_fill_layer.hpp3
4 files changed, 352 insertions, 340 deletions
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
index 29002d8bdf..cdaefb6b0e 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp
@@ -31,6 +31,169 @@ RenderFillExtrusionLayer::RenderFillExtrusionLayer(Immutable<style::FillExtrusio
RenderFillExtrusionLayer::~RenderFillExtrusionLayer() = default;
+LayerRenderer RenderFillExtrusionLayer::createRenderer() {
+ const bool drawPattern = !unevaluated.get<FillExtrusionPattern>().isUndefined();
+ return [drawPattern](PaintParameters& parameters, const LayerRenderItem& renderItem) {
+ if (parameters.pass != RenderPass::Translucent) {
+ return;
+ }
+ const auto& renderTiles = renderItem.renderTiles;
+ const auto& baseImpl = *renderItem.evaluatedProperties->baseImpl;
+ const auto& evaluated = getEvaluated<FillExtrusionLayerProperties>(renderItem.evaluatedProperties);
+ const auto& crossfade = getCrossfade<FillExtrusionLayerProperties>(renderItem.evaluatedProperties);
+
+ if (evaluated.get<FillExtrusionOpacity>() == 0) {
+ return;
+ }
+
+ const auto depthMode = parameters.depthModeFor3D();
+
+ auto draw = [&](auto& programInstance,
+ const auto& evaluated_,
+ const auto& crossfade_,
+ const gfx::StencilMode& stencilMode,
+ const gfx::ColorMode& colorMode,
+ const auto& tileBucket,
+ const auto& uniformValues,
+ const optional<ImagePosition>& patternPositionA,
+ const optional<ImagePosition>& patternPositionB,
+ const auto& textureBindings,
+ const std::string& uniqueName) {
+ const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(baseImpl.id);
+ paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade_);
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ uniformValues,
+ paintPropertyBinders,
+ evaluated_,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *tileBucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated_
+ );
+
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ *parameters.renderPass,
+ gfx::Triangles(),
+ depthMode,
+ stencilMode,
+ colorMode,
+ gfx::CullFaceMode::backCCW(),
+ *tileBucket.indexBuffer,
+ tileBucket.triangleSegments,
+ allUniformValues,
+ allAttributeBindings,
+ textureBindings,
+ baseImpl.id + "/" + uniqueName);
+ };
+
+ if (!drawPattern) {
+ // 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);
+ if (!renderData) {
+ continue;
+ }
+ auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
+ draw(
+ parameters.programs.getFillExtrusionLayerPrograms().fillExtrusion,
+ evaluated,
+ crossfade,
+ stencilMode_,
+ colorMode_,
+ bucket,
+ FillExtrusionProgram::layoutUniformValues(
+ tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
+ evaluated.get<FillExtrusionTranslateAnchor>(),
+ parameters.state),
+ parameters.state,
+ evaluated.get<FillExtrusionOpacity>(),
+ parameters.evaluatedLight,
+ evaluated.get<FillExtrusionVerticalGradient>()
+ ),
+ {},
+ {},
+ FillExtrusionProgram::TextureBindings{},
+ name
+ );
+ }
+ };
+
+ if (evaluated.get<FillExtrusionOpacity>() == 1) {
+ // Draw opaque extrusions
+ drawTiles(gfx::StencilMode::disabled(), parameters.colorModeForRenderPass(), "color");
+ } else {
+ // Draw transparent buildings in two passes so that only the closest surface is drawn.
+ // First draw all the extrusions into only the depth buffer. No colors are drawn.
+ drawTiles(gfx::StencilMode::disabled(), gfx::ColorMode::disabled(), "depth");
+
+ // Then draw all the extrusions a second time, only coloring fragments if they have the
+ // same depth value as the closest fragment in the previous pass. Use the stencil buffer
+ // to prevent the second draw in cases where we have coincident polygons.
+ drawTiles(parameters.stencilModeFor3D(), parameters.colorModeForRenderPass(), "color");
+ }
+ } else {
+ // Draw textured extrusions
+ 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);
+ if (!renderData) {
+ continue;
+ }
+ auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
+ optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from);
+ optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to);
+
+ draw(
+ parameters.programs.getFillExtrusionLayerPrograms().fillExtrusionPattern,
+ evaluated,
+ crossfade,
+ stencilMode_,
+ colorMode_,
+ bucket,
+ FillExtrusionPatternProgram::layoutUniformValues(
+ tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
+ evaluated.get<FillExtrusionTranslateAnchor>(),
+ parameters.state),
+ tile.getIconAtlasTexture().size,
+ crossfade,
+ tile.id,
+ parameters.state,
+ evaluated.get<FillExtrusionOpacity>(),
+ -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f,
+ parameters.pixelRatio,
+ parameters.evaluatedLight,
+ evaluated.get<FillExtrusionVerticalGradient>()
+ ),
+ patternPosA,
+ patternPosB,
+ FillExtrusionPatternProgram::TextureBindings{
+ textures::image::Value{ tile.getIconAtlasTexture().getResource(), gfx::TextureFilterType::Linear },
+ },
+ name
+ );
+ }
+ };
+
+ // Draw transparent buildings in two passes so that only the closest surface is drawn.
+ // First draw all the extrusions into only the depth buffer. No colors are drawn.
+ drawTiles(gfx::StencilMode::disabled(), gfx::ColorMode::disabled(), "depth");
+
+ // Then draw all the extrusions a second time, only coloring fragments if they have the
+ // same depth value as the closest fragment in the previous pass. Use the stencil buffer
+ // to prevent the second draw in cases where we have coincident polygons.
+ drawTiles(parameters.stencilModeFor3D(), parameters.colorModeForRenderPass(), "color");
+ }
+ };
+}
+
void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters) {
unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
}
@@ -55,164 +218,6 @@ bool RenderFillExtrusionLayer::hasCrossfade() const {
return getCrossfade<FillExtrusionLayerProperties>(evaluatedProperties).t != 1;
}
-void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
- if (parameters.pass != RenderPass::Translucent) {
- return;
- }
-
- const auto& evaluated = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).evaluated;
- const auto& crossfade = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).crossfade;
- if (evaluated.get<FillExtrusionOpacity>() == 0) {
- return;
- }
-
- const auto depthMode = parameters.depthModeFor3D();
-
- auto draw = [&](auto& programInstance,
- const auto& evaluated_,
- const auto& crossfade_,
- const gfx::StencilMode& stencilMode,
- const gfx::ColorMode& colorMode,
- const auto& tileBucket,
- const auto& uniformValues,
- const optional<ImagePosition>& patternPositionA,
- const optional<ImagePosition>& patternPositionB,
- const auto& textureBindings,
- const std::string& uniqueName) {
- const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID());
- paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade_);
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- uniformValues,
- paintPropertyBinders,
- evaluated_,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *tileBucket.vertexBuffer,
- paintPropertyBinders,
- evaluated_
- );
-
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- depthMode,
- stencilMode,
- colorMode,
- gfx::CullFaceMode::backCCW(),
- *tileBucket.indexBuffer,
- tileBucket.triangleSegments,
- allUniformValues,
- allAttributeBindings,
- textureBindings,
- getID() + "/" + uniqueName);
- };
-
- if (unevaluated.get<FillExtrusionPattern>().isUndefined()) {
- // 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);
- if (!renderData) {
- continue;
- }
- auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
- draw(
- parameters.programs.getFillExtrusionLayerPrograms().fillExtrusion,
- evaluated,
- crossfade,
- stencilMode_,
- colorMode_,
- bucket,
- FillExtrusionProgram::layoutUniformValues(
- tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
- evaluated.get<FillExtrusionTranslateAnchor>(),
- parameters.state),
- parameters.state,
- evaluated.get<FillExtrusionOpacity>(),
- parameters.evaluatedLight,
- evaluated.get<FillExtrusionVerticalGradient>()
- ),
- {},
- {},
- FillExtrusionProgram::TextureBindings{},
- name
- );
- }
- };
-
- if (evaluated.get<FillExtrusionOpacity>() == 1) {
- // Draw opaque extrusions
- drawTiles(gfx::StencilMode::disabled(), parameters.colorModeForRenderPass(), "color");
- } else {
- // Draw transparent buildings in two passes so that only the closest surface is drawn.
- // First draw all the extrusions into only the depth buffer. No colors are drawn.
- drawTiles(gfx::StencilMode::disabled(), gfx::ColorMode::disabled(), "depth");
-
- // Then draw all the extrusions a second time, only coloring fragments if they have the
- // same depth value as the closest fragment in the previous pass. Use the stencil buffer
- // to prevent the second draw in cases where we have coincident polygons.
- drawTiles(parameters.stencilModeFor3D(), parameters.colorModeForRenderPass(), "color");
- }
- } else {
- // Draw textured extrusions
- 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);
- if (!renderData) {
- continue;
- }
- auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
- optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from);
- optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to);
-
- draw(
- parameters.programs.getFillExtrusionLayerPrograms().fillExtrusionPattern,
- evaluated,
- crossfade,
- stencilMode_,
- colorMode_,
- bucket,
- FillExtrusionPatternProgram::layoutUniformValues(
- tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(),
- evaluated.get<FillExtrusionTranslateAnchor>(),
- parameters.state),
- tile.getIconAtlasTexture().size,
- crossfade,
- tile.id,
- parameters.state,
- evaluated.get<FillExtrusionOpacity>(),
- -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f,
- parameters.pixelRatio,
- parameters.evaluatedLight,
- evaluated.get<FillExtrusionVerticalGradient>()
- ),
- patternPosA,
- patternPosB,
- FillExtrusionPatternProgram::TextureBindings{
- textures::image::Value{ tile.getIconAtlasTexture().getResource(), gfx::TextureFilterType::Linear },
- },
- name
- );
- }
- };
-
- // Draw transparent buildings in two passes so that only the closest surface is drawn.
- // First draw all the extrusions into only the depth buffer. No colors are drawn.
- drawTiles(gfx::StencilMode::disabled(), gfx::ColorMode::disabled(), "depth");
-
- // Then draw all the extrusions a second time, only coloring fragments if they have the
- // same depth value as the closest fragment in the previous pass. Use the stencil buffer
- // to prevent the second draw in cases where we have coincident polygons.
- drawTiles(parameters.stencilModeFor3D(), parameters.colorModeForRenderPass(), "color");
- }
-}
-
bool RenderFillExtrusionLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature,
diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
index 9118601581..3410814444 100644
--- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
+++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp
@@ -3,7 +3,6 @@
#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
#include <mbgl/style/layers/fill_extrusion_layer_properties.hpp>
-#include <mbgl/gfx/offscreen_texture.hpp>
namespace mbgl {
@@ -13,11 +12,12 @@ public:
~RenderFillExtrusionLayer() override;
private:
+ LayerRenderer createRenderer() override;
void transition(const TransitionParameters&) override;
void evaluate(const PropertyEvaluationParameters&) override;
bool hasTransition() const override;
bool hasCrossfade() const override;
- void render(PaintParameters&) override;
+ void render(PaintParameters&) override {}
bool queryIntersectsFeature(
const GeometryCoordinates&,
@@ -29,8 +29,6 @@ private:
// Paint properties
style::FillExtrusionPaintProperties::Unevaluated unevaluated;
-
- std::unique_ptr<gfx::OffscreenTexture> renderTexture;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp
index c549b338df..2d36a71812 100644
--- a/src/mbgl/renderer/layers/render_fill_layer.cpp
+++ b/src/mbgl/renderer/layers/render_fill_layer.cpp
@@ -32,6 +32,191 @@ RenderFillLayer::RenderFillLayer(Immutable<style::FillLayer::Impl> _impl)
RenderFillLayer::~RenderFillLayer() = default;
+LayerRenderer RenderFillLayer::createRenderer() {
+ bool drawPattern = !unevaluated.get<FillPattern>().isUndefined();
+ bool hasOutlineColor = !unevaluated.get<FillOutlineColor>().isUndefined();
+
+ return [hasOutlineColor, drawPattern](PaintParameters& parameters, const LayerRenderItem& renderItem) {
+ const auto& renderTiles = renderItem.renderTiles;
+ const auto& baseImpl = *renderItem.evaluatedProperties->baseImpl;
+
+ if (!drawPattern) {
+ parameters.renderTileClippingMasks(renderTiles);
+ for (const RenderTile& tile : renderTiles) {
+ const LayerRenderData* renderData = tile.getLayerRenderData(baseImpl);
+ if (!renderData) {
+ continue;
+ }
+ auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
+ const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
+
+ auto draw = [&] (auto& programInstance,
+ const auto& drawMode,
+ const auto& depthMode,
+ const auto& indexBuffer,
+ const auto& segments,
+ auto&& textureBindings) {
+ const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(baseImpl.id);
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ FillProgram::LayoutUniformValues {
+ uniforms::matrix::Value(
+ tile.translatedMatrix(evaluated.get<FillTranslate>(),
+ evaluated.get<FillTranslateAnchor>(),
+ parameters.state)
+ ),
+ uniforms::world::Value( parameters.backend.getDefaultRenderable().getSize() ),
+ },
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *bucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ *parameters.renderPass,
+ drawMode,
+ depthMode,
+ parameters.stencilModeForClipping(tile.id),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ indexBuffer,
+ segments,
+ allUniformValues,
+ allAttributeBindings,
+ std::move(textureBindings),
+ baseImpl.id
+ );
+ };
+
+ // Only draw the fill when it's opaque and we're drawing opaque fragments,
+ // or when it's translucent and we're drawing translucent fragments.
+ if (bucket.triangleIndexBuffer &&
+ (evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f &&
+ evaluated.get<FillOpacity>().constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) {
+ draw(parameters.programs.getFillLayerPrograms().fill,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(1, parameters.pass == RenderPass::Opaque
+ ? gfx::DepthMaskType::ReadWrite
+ : gfx::DepthMaskType::ReadOnly),
+ *bucket.triangleIndexBuffer,
+ bucket.triangleSegments,
+ FillProgram::TextureBindings{});
+ }
+
+ if (evaluated.get<FillAntialias>() && parameters.pass == RenderPass::Translucent) {
+ draw(parameters.programs.getFillLayerPrograms().fillOutline,
+ gfx::Lines{ 2.0f },
+ parameters.depthModeForSublayer(
+ hasOutlineColor ? 0u : 2u,
+ gfx::DepthMaskType::ReadOnly),
+ *bucket.lineIndexBuffer,
+ bucket.lineSegments,
+ FillOutlineProgram::TextureBindings{});
+ }
+ }
+ } else {
+ if (parameters.pass != RenderPass::Translucent) {
+ return;
+ }
+
+ parameters.renderTileClippingMasks(renderTiles);
+
+ for (const RenderTile& tile : renderTiles) {
+ const LayerRenderData* renderData = tile.getLayerRenderData(baseImpl);
+ if (!renderData) {
+ continue;
+ }
+ auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
+ const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
+ const auto& crossfade = getCrossfade<FillLayerProperties>(renderData->layerProperties);
+
+ const auto& fillPatternValue = evaluated.get<FillPattern>().constantOr(Faded<std::basic_string<char>>{"", ""});
+ optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from);
+ optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to);
+
+ auto draw = [&] (auto& programInstance,
+ const auto& drawMode,
+ const auto& depthMode,
+ const auto& indexBuffer,
+ const auto& segments,
+ auto&& textureBindings) {
+ const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(baseImpl.id);
+ paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ FillPatternProgram::layoutUniformValues(
+ tile.translatedMatrix(evaluated.get<FillTranslate>(),
+ evaluated.get<FillTranslateAnchor>(),
+ parameters.state),
+ parameters.backend.getDefaultRenderable().getSize(),
+ tile.getIconAtlasTexture().size,
+ crossfade,
+ tile.id,
+ parameters.state,
+ parameters.pixelRatio
+ ),
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *bucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ *parameters.renderPass,
+ drawMode,
+ depthMode,
+ parameters.stencilModeForClipping(tile.id),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ indexBuffer,
+ segments,
+ allUniformValues,
+ allAttributeBindings,
+ std::move(textureBindings),
+ baseImpl.id
+ );
+ };
+
+ if (bucket.triangleIndexBuffer) {
+ draw(parameters.programs.getFillLayerPrograms().fillPattern,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(1, gfx::DepthMaskType::ReadWrite),
+ *bucket.triangleIndexBuffer,
+ bucket.triangleSegments,
+ FillPatternProgram::TextureBindings{
+ textures::image::Value{ tile.getIconAtlasTexture().getResource(), gfx::TextureFilterType::Linear },
+ });
+ }
+ if (evaluated.get<FillAntialias>() && !hasOutlineColor) {
+ draw(parameters.programs.getFillLayerPrograms().fillOutlinePattern,
+ gfx::Lines { 2.0f },
+ parameters.depthModeForSublayer(2, gfx::DepthMaskType::ReadOnly),
+ *bucket.lineIndexBuffer,
+ bucket.lineSegments,
+ FillOutlinePatternProgram::TextureBindings{
+ textures::image::Value{ tile.getIconAtlasTexture().getResource(), gfx::TextureFilterType::Linear },
+ });
+ }
+ }
+ }
+ };
+}
+
void RenderFillLayer::transition(const TransitionParameters& parameters) {
unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
}
@@ -72,183 +257,6 @@ bool RenderFillLayer::hasCrossfade() const {
return getCrossfade<FillLayerProperties>(evaluatedProperties).t != 1;
}
-void RenderFillLayer::render(PaintParameters& parameters) {
- if (unevaluated.get<FillPattern>().isUndefined()) {
- parameters.renderTileClippingMasks(renderTiles);
- for (const RenderTile& tile : renderTiles) {
- const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
- if (!renderData) {
- continue;
- }
- auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
- const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
-
- auto draw = [&] (auto& programInstance,
- const auto& drawMode,
- const auto& depthMode,
- const auto& indexBuffer,
- const auto& segments,
- auto&& textureBindings) {
- const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- FillProgram::LayoutUniformValues {
- uniforms::matrix::Value(
- tile.translatedMatrix(evaluated.get<FillTranslate>(),
- evaluated.get<FillTranslateAnchor>(),
- parameters.state)
- ),
- uniforms::world::Value( parameters.backend.getDefaultRenderable().getSize() ),
- },
- paintPropertyBinders,
- evaluated,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *bucket.vertexBuffer,
- paintPropertyBinders,
- evaluated
- );
-
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- drawMode,
- depthMode,
- parameters.stencilModeForClipping(tile.id),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- indexBuffer,
- segments,
- allUniformValues,
- allAttributeBindings,
- std::move(textureBindings),
- getID()
- );
- };
-
- // Only draw the fill when it's opaque and we're drawing opaque fragments,
- // or when it's translucent and we're drawing translucent fragments.
- if (bucket.triangleIndexBuffer &&
- (evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f &&
- evaluated.get<FillOpacity>().constantOr(0) >= 1.0f) == (parameters.pass == RenderPass::Opaque)) {
- draw(parameters.programs.getFillLayerPrograms().fill,
- gfx::Triangles(),
- parameters.depthModeForSublayer(1, parameters.pass == RenderPass::Opaque
- ? gfx::DepthMaskType::ReadWrite
- : gfx::DepthMaskType::ReadOnly),
- *bucket.triangleIndexBuffer,
- bucket.triangleSegments,
- FillProgram::TextureBindings{});
- }
-
- if (evaluated.get<FillAntialias>() && parameters.pass == RenderPass::Translucent) {
- draw(parameters.programs.getFillLayerPrograms().fillOutline,
- gfx::Lines{ 2.0f },
- parameters.depthModeForSublayer(
- unevaluated.get<FillOutlineColor>().isUndefined() ? 2 : 0,
- gfx::DepthMaskType::ReadOnly),
- *bucket.lineIndexBuffer,
- bucket.lineSegments,
- FillOutlineProgram::TextureBindings{});
- }
- }
- } else {
- if (parameters.pass != RenderPass::Translucent) {
- return;
- }
-
- parameters.renderTileClippingMasks(renderTiles);
-
- for (const RenderTile& tile : renderTiles) {
- const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
- if (!renderData) {
- continue;
- }
- auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
- const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
- const auto& crossfade = getCrossfade<FillLayerProperties>(renderData->layerProperties);
-
- const auto& fillPatternValue = evaluated.get<FillPattern>().constantOr(Faded<std::basic_string<char>>{"", ""});
- optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from);
- optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to);
-
- auto draw = [&] (auto& programInstance,
- const auto& drawMode,
- const auto& depthMode,
- const auto& indexBuffer,
- const auto& segments,
- auto&& textureBindings) {
- const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
- paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- FillPatternProgram::layoutUniformValues(
- tile.translatedMatrix(evaluated.get<FillTranslate>(),
- evaluated.get<FillTranslateAnchor>(),
- parameters.state),
- parameters.backend.getDefaultRenderable().getSize(),
- tile.getIconAtlasTexture().size,
- crossfade,
- tile.id,
- parameters.state,
- parameters.pixelRatio
- ),
- paintPropertyBinders,
- evaluated,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *bucket.vertexBuffer,
- paintPropertyBinders,
- evaluated
- );
-
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- drawMode,
- depthMode,
- parameters.stencilModeForClipping(tile.id),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- indexBuffer,
- segments,
- allUniformValues,
- allAttributeBindings,
- std::move(textureBindings),
- getID()
- );
- };
-
- if (bucket.triangleIndexBuffer) {
- draw(parameters.programs.getFillLayerPrograms().fillPattern,
- gfx::Triangles(),
- parameters.depthModeForSublayer(1, gfx::DepthMaskType::ReadWrite),
- *bucket.triangleIndexBuffer,
- bucket.triangleSegments,
- FillPatternProgram::TextureBindings{
- textures::image::Value{ tile.getIconAtlasTexture().getResource(), gfx::TextureFilterType::Linear },
- });
- }
- if (evaluated.get<FillAntialias>() && unevaluated.get<FillOutlineColor>().isUndefined()) {
- draw(parameters.programs.getFillLayerPrograms().fillOutlinePattern,
- gfx::Lines { 2.0f },
- parameters.depthModeForSublayer(2, gfx::DepthMaskType::ReadOnly),
- *bucket.lineIndexBuffer,
- bucket.lineSegments,
- FillOutlinePatternProgram::TextureBindings{
- textures::image::Value{ tile.getIconAtlasTexture().getResource(), gfx::TextureFilterType::Linear },
- });
- }
- }
- }
-}
-
bool RenderFillLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature,
diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp
index 79adc9dab4..dda4bdd372 100644
--- a/src/mbgl/renderer/layers/render_fill_layer.hpp
+++ b/src/mbgl/renderer/layers/render_fill_layer.hpp
@@ -15,11 +15,12 @@ public:
~RenderFillLayer() override;
private:
+ LayerRenderer createRenderer() override;
void transition(const TransitionParameters&) override;
void evaluate(const PropertyEvaluationParameters&) override;
bool hasTransition() const override;
bool hasCrossfade() const override;
- void render(PaintParameters&) override;
+ void render(PaintParameters&) override {}
bool queryIntersectsFeature(
const GeometryCoordinates&,