summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-08 11:45:19 +0300
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-08 11:45:19 +0300
commitb481469394a7c55ec43aeaec5a19622a2fae7df5 (patch)
treedcf4cb75d6ee06df82b44cc017125194caa7d8d4
parentd2297f1b0169c33da67b29d8d043b8745ac149f0 (diff)
downloadqtlocation-mapboxgl-b481469394a7c55ec43aeaec5a19622a2fae7df5.tar.gz
[core] Renderer for RenderHillshadeLayer and RenderRasterLayer
-rw-r--r--src/mbgl/renderer/layers/render_hillshade_layer.cpp312
-rw-r--r--src/mbgl/renderer/layers/render_hillshade_layer.hpp6
-rw-r--r--src/mbgl/renderer/layers/render_raster_layer.cpp277
-rw-r--r--src/mbgl/renderer/layers/render_raster_layer.hpp3
4 files changed, 306 insertions, 292 deletions
diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp
index 2cbb77f24b..49fc5eedc5 100644
--- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp
+++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp
@@ -29,194 +29,202 @@ RenderHillshadeLayer::RenderHillshadeLayer(Immutable<style::HillshadeLayer::Impl
RenderHillshadeLayer::~RenderHillshadeLayer() = default;
-const std::array<float, 2> RenderHillshadeLayer::getLatRange(const UnwrappedTileID& id) {
+namespace {
+std::array<float, 2> getLatRange(const UnwrappedTileID& id) {
const LatLng latlng0 = LatLng(id);
const LatLng latlng1 = LatLng(UnwrappedTileID(id.canonical.z, id.canonical.x, id.canonical.y + 1));
return {{ (float)latlng0.latitude(), (float)latlng1.latitude() }};
}
-const std::array<float, 2> RenderHillshadeLayer::getLight(const PaintParameters& parameters) {
- const auto& evaluated = static_cast<const HillshadeLayerProperties&>(*evaluatedProperties).evaluated;
+std::array<float, 2> getLight(const PaintParameters& parameters, const HillshadePaintProperties::PossiblyEvaluated& evaluated) {
float azimuthal = evaluated.get<HillshadeIlluminationDirection>() * util::DEG2RAD;
- if (evaluated.get<HillshadeIlluminationAnchor>() == HillshadeIlluminationAnchorType::Viewport) azimuthal = azimuthal - parameters.state.getBearing();
+ if (evaluated.get<HillshadeIlluminationAnchor>() == HillshadeIlluminationAnchorType::Viewport) {
+ azimuthal = azimuthal - parameters.state.getBearing();
+ }
return {{evaluated.get<HillshadeExaggeration>(), azimuthal}};
}
+} // namespace
-void RenderHillshadeLayer::transition(const TransitionParameters& parameters) {
- unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
-}
+LayerRenderer RenderHillshadeLayer::createRenderer() {
+ return [maxzoom = this->maxzoom](PaintParameters& parameters, const LayerRenderItem& renderItem) {
+ if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D) return;
-void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& parameters) {
- auto properties = makeMutable<HillshadeLayerProperties>(
- staticImmutableCast<HillshadeLayer::Impl>(baseImpl),
- unevaluated.evaluate(parameters));
- passes = (properties->evaluated.get<style::HillshadeExaggeration >() > 0)
- ? (RenderPass::Translucent | RenderPass::Pass3D)
- : RenderPass::None;
+ const auto& renderTiles = renderItem.renderTiles;
+ const auto& evaluated = getEvaluated<HillshadeLayerProperties>(renderItem.evaluatedProperties);
+ const auto& baseImpl = *renderItem.evaluatedProperties->baseImpl;
- evaluatedProperties = std::move(properties);
-}
+ auto draw = [&] (const mat4& matrix,
+ const auto& vertexBuffer,
+ const auto& indexBuffer,
+ const auto& segments,
+ const UnwrappedTileID& id,
+ const auto& textureBindings) {
+ auto& programInstance = parameters.programs.getHillshadeLayerPrograms().hillshade;
-bool RenderHillshadeLayer::hasTransition() const {
- return unevaluated.hasTransition();
-}
-
-bool RenderHillshadeLayer::hasCrossfade() const {
- return false;
-}
-
-void RenderHillshadeLayer::prepare(const LayerPrepareParameters& params) {
- RenderLayer::prepare(params);
- maxzoom = params.source->getMaxZoom();
-}
-
-void RenderHillshadeLayer::render(PaintParameters& parameters) {
- if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D)
- return;
- const auto& evaluated = static_cast<const HillshadeLayerProperties&>(*evaluatedProperties).evaluated;
- auto draw = [&] (const mat4& matrix,
- const auto& vertexBuffer,
- const auto& indexBuffer,
- const auto& segments,
- const UnwrappedTileID& id,
- const auto& textureBindings) {
- auto& programInstance = parameters.programs.getHillshadeLayerPrograms().hillshade;
-
- const HillshadeProgram::Binders paintAttributeData{ evaluated, 0 };
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- HillshadeProgram::LayoutUniformValues {
- uniforms::matrix::Value( matrix ),
- uniforms::highlight::Value( evaluated.get<HillshadeHighlightColor>() ),
- uniforms::shadow::Value( evaluated.get<HillshadeShadowColor>() ),
- uniforms::accent::Value( evaluated.get<HillshadeAccentColor>() ),
- uniforms::light::Value( getLight(parameters) ),
- uniforms::latrange::Value( getLatRange(id) ),
- },
- paintAttributeData,
- evaluated,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- vertexBuffer,
- paintAttributeData,
- evaluated
- );
-
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- indexBuffer,
- segments,
- allUniformValues,
- allAttributeBindings,
- textureBindings,
- getID() + "/" + util::toString(id)
- );
- };
-
- mat4 mat;
- matrix::ortho(mat, 0, util::EXTENT, -util::EXTENT, 0, 0, 1);
- matrix::translate(mat, mat, 0, -util::EXTENT, 0);
-
- for (const RenderTile& tile : renderTiles) {
- auto* bucket_ = tile.getBucket(*baseImpl);
- if (!bucket_) {
- continue;
- }
- auto& bucket = static_cast<HillshadeBucket&>(*bucket_);
-
- if (!bucket.hasData()){
- continue;
- }
-
- if (!bucket.isPrepared() && parameters.pass == RenderPass::Pass3D) {
- assert(bucket.dem);
- const uint16_t stride = bucket.getDEMData().stride;
- const uint16_t tilesize = bucket.getDEMData().dim;
- auto view = parameters.context.createOffscreenTexture({ tilesize, tilesize });
-
- auto renderPass = parameters.encoder->createRenderPass(
- "hillshade prepare", { *view, Color{ 0.0f, 0.0f, 0.0f, 0.0f }, {}, {} });
-
- const Properties<>::PossiblyEvaluated properties;
- const HillshadePrepareProgram::Binders paintAttributeData{ properties, 0 };
-
- auto& programInstance = parameters.programs.getHillshadeLayerPrograms().hillshadePrepare;
+ const HillshadeProgram::Binders paintAttributeData{ evaluated, 0 };
const auto allUniformValues = programInstance.computeAllUniformValues(
- HillshadePrepareProgram::LayoutUniformValues {
- uniforms::matrix::Value( mat ),
- uniforms::dimension::Value( {{stride, stride}} ),
- uniforms::zoom::Value( float(tile.id.canonical.z) ),
- uniforms::maxzoom::Value( float(maxzoom) ),
+ HillshadeProgram::LayoutUniformValues {
+ uniforms::matrix::Value( matrix ),
+ uniforms::highlight::Value( evaluated.get<HillshadeHighlightColor>() ),
+ uniforms::shadow::Value( evaluated.get<HillshadeShadowColor>() ),
+ uniforms::accent::Value( evaluated.get<HillshadeAccentColor>() ),
+ uniforms::light::Value( getLight(parameters, evaluated) ),
+ uniforms::latrange::Value( getLatRange(id) ),
},
paintAttributeData,
- properties,
+ evaluated,
parameters.state.getZoom()
);
const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *parameters.staticData.rasterVertexBuffer,
+ vertexBuffer,
paintAttributeData,
- properties
+ evaluated
);
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
programInstance.draw(
parameters.context,
- *renderPass,
+ *parameters.renderPass,
gfx::Triangles(),
parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
gfx::StencilMode::disabled(),
parameters.colorModeForRenderPass(),
gfx::CullFaceMode::disabled(),
- *parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.rasterSegments,
+ indexBuffer,
+ segments,
allUniformValues,
allAttributeBindings,
- HillshadePrepareProgram::TextureBindings{
- textures::image::Value{ bucket.dem->getResource() },
- },
- getID() + "/p/" + util::toString(tile.id)
+ textureBindings,
+ baseImpl.id + "/" + util::toString(id)
);
- bucket.texture = std::move(view->getTexture());
- bucket.setPrepared(true);
- } else if (parameters.pass == RenderPass::Translucent) {
- assert(bucket.texture);
-
- if (bucket.vertexBuffer && bucket.indexBuffer && !bucket.segments.empty()) {
- // Draw only the parts of the tile that aren't drawn by another tile in the layer.
- draw(parameters.matrixForTile(tile.id, true),
- *bucket.vertexBuffer,
- *bucket.indexBuffer,
- bucket.segments,
- tile.id,
- HillshadeProgram::TextureBindings{
- textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear },
- });
- } else {
- // Draw the full tile.
- draw(parameters.matrixForTile(tile.id, true),
- *parameters.staticData.rasterVertexBuffer,
- *parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.rasterSegments,
- tile.id,
- HillshadeProgram::TextureBindings{
- textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear },
- });
+ };
+
+ mat4 mat;
+ matrix::ortho(mat, 0, util::EXTENT, -util::EXTENT, 0, 0, 1);
+ matrix::translate(mat, mat, 0, -util::EXTENT, 0);
+
+ for (const RenderTile& tile : renderTiles) {
+ auto* bucket_ = tile.getBucket(baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ auto& bucket = static_cast<HillshadeBucket&>(*bucket_);
+
+ if (!bucket.hasData()) {
+ continue;
+ }
+
+ if (!bucket.isPrepared() && parameters.pass == RenderPass::Pass3D) {
+ assert(bucket.dem);
+ const uint16_t stride = bucket.getDEMData().stride;
+ const uint16_t tilesize = bucket.getDEMData().dim;
+ auto view = parameters.context.createOffscreenTexture({ tilesize, tilesize });
+
+ auto renderPass = parameters.encoder->createRenderPass(
+ "hillshade prepare", { *view, Color{ 0.0f, 0.0f, 0.0f, 0.0f }, {}, {} });
+
+ const Properties<>::PossiblyEvaluated properties;
+ const HillshadePrepareProgram::Binders paintAttributeData{ properties, 0 };
+
+ auto& programInstance = parameters.programs.getHillshadeLayerPrograms().hillshadePrepare;
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ HillshadePrepareProgram::LayoutUniformValues {
+ uniforms::matrix::Value( mat ),
+ uniforms::dimension::Value( {{stride, stride}} ),
+ uniforms::zoom::Value( float(tile.id.canonical.z) ),
+ uniforms::maxzoom::Value( float(maxzoom) ),
+ },
+ paintAttributeData,
+ properties,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *parameters.staticData.rasterVertexBuffer,
+ paintAttributeData,
+ properties
+ );
+
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ *renderPass,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ *parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.rasterSegments,
+ allUniformValues,
+ allAttributeBindings,
+ HillshadePrepareProgram::TextureBindings{
+ textures::image::Value{ bucket.dem->getResource() },
+ },
+ baseImpl.id + "/p/" + util::toString(tile.id)
+ );
+ bucket.texture = std::move(view->getTexture());
+ bucket.setPrepared(true);
+ } else if (parameters.pass == RenderPass::Translucent) {
+ assert(bucket.texture);
+
+ if (bucket.vertexBuffer && bucket.indexBuffer && !bucket.segments.empty()) {
+ // Draw only the parts of the tile that aren't drawn by another tile in the layer.
+ draw(parameters.matrixForTile(tile.id, true),
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments,
+ tile.id,
+ HillshadeProgram::TextureBindings{
+ textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear },
+ });
+ } else {
+ // Draw the full tile.
+ draw(parameters.matrixForTile(tile.id, true),
+ *parameters.staticData.rasterVertexBuffer,
+ *parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.rasterSegments,
+ tile.id,
+ HillshadeProgram::TextureBindings{
+ textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear },
+ });
+ }
}
+
+
}
-
+ };
+}
- }
+void RenderHillshadeLayer::transition(const TransitionParameters& parameters) {
+ unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
+}
+
+void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& parameters) {
+ auto properties = makeMutable<HillshadeLayerProperties>(
+ staticImmutableCast<HillshadeLayer::Impl>(baseImpl),
+ unevaluated.evaluate(parameters));
+ passes = (properties->evaluated.get<style::HillshadeExaggeration >() > 0)
+ ? (RenderPass::Translucent | RenderPass::Pass3D)
+ : RenderPass::None;
+
+ evaluatedProperties = std::move(properties);
+}
+
+bool RenderHillshadeLayer::hasTransition() const {
+ return unevaluated.hasTransition();
+}
+
+bool RenderHillshadeLayer::hasCrossfade() const {
+ return false;
+}
+
+void RenderHillshadeLayer::prepare(const LayerPrepareParameters& params) {
+ RenderLayer::prepare(params);
+ maxzoom = params.source->getMaxZoom();
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.hpp b/src/mbgl/renderer/layers/render_hillshade_layer.hpp
index 61f5c507a9..068c7b14ca 100644
--- a/src/mbgl/renderer/layers/render_hillshade_layer.hpp
+++ b/src/mbgl/renderer/layers/render_hillshade_layer.hpp
@@ -13,20 +13,18 @@ public:
~RenderHillshadeLayer() 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 {}
void prepare(const LayerPrepareParameters&) override;
// Paint properties
style::HillshadePaintProperties::Unevaluated unevaluated;
uint8_t maxzoom = util::TERRAIN_RGB_MAXZOOM;
-
- const std::array<float, 2> getLatRange(const UnwrappedTileID& id);
- const std::array<float, 2> getLight(const PaintParameters& parameters);
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp
index e22e14275c..b5bcfd11df 100644
--- a/src/mbgl/renderer/layers/render_raster_layer.cpp
+++ b/src/mbgl/renderer/layers/render_raster_layer.cpp
@@ -25,27 +25,8 @@ RenderRasterLayer::RenderRasterLayer(Immutable<style::RasterLayer::Impl> _impl)
RenderRasterLayer::~RenderRasterLayer() = default;
-void RenderRasterLayer::transition(const TransitionParameters& parameters) {
- unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
-}
-
-void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters) {
- auto properties = makeMutable<RasterLayerProperties>(
- staticImmutableCast<RasterLayer::Impl>(baseImpl),
- unevaluated.evaluate(parameters));
- passes = properties->evaluated.get<style::RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
- evaluatedProperties = std::move(properties);
-}
-
-bool RenderRasterLayer::hasTransition() const {
- return unevaluated.hasTransition();
-}
-
-bool RenderRasterLayer::hasCrossfade() const {
- return false;
-}
-
-static float saturationFactor(float saturation) {
+namespace {
+float saturationFactor(float saturation) {
if (saturation > 0) {
return 1 - 1 / (1.001 - saturation);
} else {
@@ -53,7 +34,7 @@ static float saturationFactor(float saturation) {
}
}
-static float contrastFactor(float contrast) {
+float contrastFactor(float contrast) {
if (contrast > 0) {
return 1 / (1 - contrast);
} else {
@@ -61,7 +42,7 @@ static float contrastFactor(float contrast) {
}
}
-static std::array<float, 3> spinWeights(float spin) {
+std::array<float, 3> spinWeights(float spin) {
spin *= util::DEG2RAD;
float s = std::sin(spin);
float c = std::cos(spin);
@@ -72,124 +53,150 @@ static std::array<float, 3> spinWeights(float spin) {
}};
return spin_weights;
}
+} // namespace
+
+LayerRenderer RenderRasterLayer::createRenderer() {
+ return [imageData = this->imageData](PaintParameters& parameters, const LayerRenderItem& renderItem) {
+ if (parameters.pass != RenderPass::Translucent) return;
+
+ const auto& renderTiles = renderItem.renderTiles;
+ const auto& evaluated = getEvaluated<RasterLayerProperties>(renderItem.evaluatedProperties);
+ const auto& baseImpl = *renderItem.evaluatedProperties->baseImpl;
+
+ RasterProgram::Binders paintAttributeData{ evaluated, 0 };
+
+ auto draw = [&] (const mat4& matrix,
+ const auto& vertexBuffer,
+ const auto& indexBuffer,
+ const auto& segments,
+ const auto& textureBindings,
+ const std::string& drawScopeID) {
+ auto& programInstance = parameters.programs.getRasterLayerPrograms().raster;
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ RasterProgram::LayoutUniformValues {
+ uniforms::matrix::Value( matrix ),
+ uniforms::opacity::Value( evaluated.get<RasterOpacity>() ),
+ uniforms::fade_t::Value( 1 ),
+ uniforms::brightness_low::Value( evaluated.get<RasterBrightnessMin>() ),
+ uniforms::brightness_high::Value( evaluated.get<RasterBrightnessMax>() ),
+ uniforms::saturation_factor::Value( saturationFactor(evaluated.get<RasterSaturation>()) ),
+ uniforms::contrast_factor::Value( contrastFactor(evaluated.get<RasterContrast>()) ),
+ uniforms::spin_weights::Value( spinWeights(evaluated.get<RasterHueRotate>()) ),
+ uniforms::buffer_scale::Value( 1.0f ),
+ uniforms::scale_parent::Value( 1.0f ),
+ uniforms::tl_parent::Value( std::array<float, 2> {{ 0.0f, 0.0f }} ),
+ },
+ paintAttributeData,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ vertexBuffer,
+ paintAttributeData,
+ evaluated
+ );
+
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ *parameters.renderPass,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::StencilMode::disabled(),
+ parameters.colorModeForRenderPass(),
+ gfx::CullFaceMode::disabled(),
+ indexBuffer,
+ segments,
+ allUniformValues,
+ allAttributeBindings,
+ textureBindings,
+ baseImpl.id + "/" + drawScopeID
+ );
+ };
+
+ const gfx::TextureFilterType filter = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest ? gfx::TextureFilterType::Nearest : gfx::TextureFilterType::Linear;
+
+ if (imageData && !imageData->bucket->needsUpload()) {
+ RasterBucket& bucket = *imageData->bucket;
+ assert(bucket.texture);
-void RenderRasterLayer::prepare(const LayerPrepareParameters& params) {
- RenderLayer::prepare(params);
- imageData = params.source->getImageRenderData();
+ size_t i = 0;
+ for (const auto& matrix_ : imageData->matrices) {
+ draw(matrix_,
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments,
+ RasterProgram::TextureBindings{
+ textures::image0::Value{ bucket.texture->getResource(), filter },
+ textures::image1::Value{ bucket.texture->getResource(), filter },
+ },
+ bucket.drawScopeID + std::to_string(i++));
+ }
+ } else {
+ for (const RenderTile& tile : renderTiles) {
+ auto* bucket_ = tile.getBucket(baseImpl);
+ if (!bucket_) {
+ continue;
+ }
+ auto& bucket = static_cast<RasterBucket&>(*bucket_);
+
+ if (!bucket.hasData())
+ continue;
+
+ assert(bucket.texture);
+ if (bucket.vertexBuffer && bucket.indexBuffer && !bucket.segments.empty()) {
+ // Draw only the parts of the tile that aren't drawn by another tile in the layer.
+ draw(parameters.matrixForTile(tile.id, true),
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments,
+ RasterProgram::TextureBindings{
+ textures::image0::Value{ bucket.texture->getResource(), filter },
+ textures::image1::Value{ bucket.texture->getResource(), filter },
+ },
+ bucket.drawScopeID);
+ } else {
+ // Draw the full tile.
+ draw(parameters.matrixForTile(tile.id, true),
+ *parameters.staticData.rasterVertexBuffer,
+ *parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.rasterSegments,
+ RasterProgram::TextureBindings{
+ textures::image0::Value{ bucket.texture->getResource(), filter },
+ textures::image1::Value{ bucket.texture->getResource(), filter },
+ },
+ bucket.drawScopeID);
+ }
+ }
+ }
+ };
}
-void RenderRasterLayer::render(PaintParameters& parameters) {
- if (parameters.pass != RenderPass::Translucent)
- return;
- const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
- RasterProgram::Binders paintAttributeData{ evaluated, 0 };
-
- auto draw = [&] (const mat4& matrix,
- const auto& vertexBuffer,
- const auto& indexBuffer,
- const auto& segments,
- const auto& textureBindings,
- const std::string& drawScopeID) {
- auto& programInstance = parameters.programs.getRasterLayerPrograms().raster;
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- RasterProgram::LayoutUniformValues {
- uniforms::matrix::Value( matrix ),
- uniforms::opacity::Value( evaluated.get<RasterOpacity>() ),
- uniforms::fade_t::Value( 1 ),
- uniforms::brightness_low::Value( evaluated.get<RasterBrightnessMin>() ),
- uniforms::brightness_high::Value( evaluated.get<RasterBrightnessMax>() ),
- uniforms::saturation_factor::Value( saturationFactor(evaluated.get<RasterSaturation>()) ),
- uniforms::contrast_factor::Value( contrastFactor(evaluated.get<RasterContrast>()) ),
- uniforms::spin_weights::Value( spinWeights(evaluated.get<RasterHueRotate>()) ),
- uniforms::buffer_scale::Value( 1.0f ),
- uniforms::scale_parent::Value( 1.0f ),
- uniforms::tl_parent::Value( std::array<float, 2> {{ 0.0f, 0.0f }} ),
- },
- paintAttributeData,
- evaluated,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- vertexBuffer,
- paintAttributeData,
- evaluated
- );
-
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- indexBuffer,
- segments,
- allUniformValues,
- allAttributeBindings,
- textureBindings,
- getID() + "/" + drawScopeID
- );
- };
+void RenderRasterLayer::transition(const TransitionParameters& parameters) {
+ unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
+}
- const gfx::TextureFilterType filter = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest ? gfx::TextureFilterType::Nearest : gfx::TextureFilterType::Linear;
-
- if (imageData && !imageData->bucket->needsUpload()) {
- RasterBucket& bucket = *imageData->bucket;
- assert(bucket.texture);
-
- size_t i = 0;
- for (const auto& matrix_ : imageData->matrices) {
- draw(matrix_,
- *bucket.vertexBuffer,
- *bucket.indexBuffer,
- bucket.segments,
- RasterProgram::TextureBindings{
- textures::image0::Value{ bucket.texture->getResource(), filter },
- textures::image1::Value{ bucket.texture->getResource(), filter },
- },
- bucket.drawScopeID + std::to_string(i++));
- }
- } else {
- for (const RenderTile& tile : renderTiles) {
- auto* bucket_ = tile.getBucket(*baseImpl);
- if (!bucket_) {
- continue;
- }
- auto& bucket = static_cast<RasterBucket&>(*bucket_);
+void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters) {
+ auto properties = makeMutable<RasterLayerProperties>(
+ staticImmutableCast<RasterLayer::Impl>(baseImpl),
+ unevaluated.evaluate(parameters));
+ passes = properties->evaluated.get<style::RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
+ evaluatedProperties = std::move(properties);
+}
- if (!bucket.hasData())
- continue;
+bool RenderRasterLayer::hasTransition() const {
+ return unevaluated.hasTransition();
+}
- assert(bucket.texture);
- if (bucket.vertexBuffer && bucket.indexBuffer && !bucket.segments.empty()) {
- // Draw only the parts of the tile that aren't drawn by another tile in the layer.
- draw(parameters.matrixForTile(tile.id, true),
- *bucket.vertexBuffer,
- *bucket.indexBuffer,
- bucket.segments,
- RasterProgram::TextureBindings{
- textures::image0::Value{ bucket.texture->getResource(), filter },
- textures::image1::Value{ bucket.texture->getResource(), filter },
- },
- bucket.drawScopeID);
- } else {
- // Draw the full tile.
- draw(parameters.matrixForTile(tile.id, true),
- *parameters.staticData.rasterVertexBuffer,
- *parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.rasterSegments,
- RasterProgram::TextureBindings{
- textures::image0::Value{ bucket.texture->getResource(), filter },
- textures::image1::Value{ bucket.texture->getResource(), filter },
- },
- bucket.drawScopeID);
- }
- }
- }
+bool RenderRasterLayer::hasCrossfade() const {
+ return false;
+}
+
+void RenderRasterLayer::prepare(const LayerPrepareParameters& params) {
+ RenderLayer::prepare(params);
+ imageData = params.source->getImageRenderData();
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/layers/render_raster_layer.hpp b/src/mbgl/renderer/layers/render_raster_layer.hpp
index 94bbd36a0d..6f2c52b654 100644
--- a/src/mbgl/renderer/layers/render_raster_layer.hpp
+++ b/src/mbgl/renderer/layers/render_raster_layer.hpp
@@ -14,12 +14,13 @@ public:
~RenderRasterLayer() override;
private:
+ LayerRenderer createRenderer() override;
void transition(const TransitionParameters&) override;
void evaluate(const PropertyEvaluationParameters&) override;
bool hasTransition() const override;
bool hasCrossfade() const override;
void prepare(const LayerPrepareParameters&) override;
- void render(PaintParameters&) override;
+ void render(PaintParameters&) override {}
// Paint properties
style::RasterPaintProperties::Unevaluated unevaluated;