summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-05 18:51:15 +0300
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-07-05 18:51:15 +0300
commitd2297f1b0169c33da67b29d8d043b8745ac149f0 (patch)
tree5070a3987aafe2a302e2c2f9c7610e609168eba4
parentca646fef52275816bc83e3c503e87ca4cc631493 (diff)
downloadqtlocation-mapboxgl-d2297f1b0169c33da67b29d8d043b8745ac149f0.tar.gz
[core] Renderer and loader for RenderHeatmapLayer. Drop RenderLayer::upload().
-rw-r--r--src/mbgl/renderer/layers/render_heatmap_layer.cpp290
-rw-r--r--src/mbgl/renderer/layers/render_heatmap_layer.hpp18
-rw-r--r--src/mbgl/renderer/layers/render_line_layer.hpp1
-rw-r--r--src/mbgl/renderer/render_layer.cpp2
-rw-r--r--src/mbgl/renderer/render_layer.hpp3
5 files changed, 155 insertions, 159 deletions
diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
index 4b80dee5e7..2a39fb5a35 100644
--- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp
+++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp
@@ -1,5 +1,6 @@
#include <mbgl/renderer/layers/render_heatmap_layer.hpp>
#include <mbgl/renderer/buckets/heatmap_bucket.hpp>
+#include <mbgl/renderer/color_ramp_render_data.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_static_data.hpp>
@@ -25,171 +26,177 @@ inline const HeatmapLayer::Impl& impl(const Immutable<Layer::Impl>& impl) {
RenderHeatmapLayer::RenderHeatmapLayer(Immutable<HeatmapLayer::Impl> _impl)
: RenderLayer(makeMutable<HeatmapLayerProperties>(std::move(_impl))),
- unevaluated(impl(baseImpl).paint.untransitioned()), colorRamp({256, 1}) {
+ unevaluated(impl(baseImpl).paint.untransitioned()),
+ sharedRenderData(std::make_shared<RenderData>()) {
}
RenderHeatmapLayer::~RenderHeatmapLayer() = default;
-void RenderHeatmapLayer::transition(const TransitionParameters& parameters) {
- unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
- updateColorRamp();
-}
-
-void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters) {
- auto properties = makeMutable<HeatmapLayerProperties>(
- staticImmutableCast<HeatmapLayer::Impl>(baseImpl),
- unevaluated.evaluate(parameters));
-
- passes = (properties->evaluated.get<style::HeatmapOpacity>() > 0)
- ? (RenderPass::Translucent | RenderPass::Pass3D)
- : RenderPass::None;
-
- evaluatedProperties = std::move(properties);
-}
-
-bool RenderHeatmapLayer::hasTransition() const {
- return unevaluated.hasTransition();
-}
-
-bool RenderHeatmapLayer::hasCrossfade() const {
- return false;
-}
-
-void RenderHeatmapLayer::upload(gfx::UploadPass& uploadPass) {
- if (!colorRampTexture) {
- colorRampTexture =
- uploadPass.createTexture(colorRamp, gfx::TextureChannelDataType::UnsignedByte);
- }
-}
-
-void RenderHeatmapLayer::render(PaintParameters& parameters) {
- if (parameters.pass == RenderPass::Opaque) {
- return;
- }
-
- if (parameters.pass == RenderPass::Pass3D) {
- const auto& viewportSize = parameters.staticData.backendSize;
- const auto size = Size{viewportSize.width / 4, viewportSize.height / 4};
-
- assert(colorRampTexture);
-
- if (!renderTexture || renderTexture->getSize() != size) {
- renderTexture.reset();
- if (parameters.context.supportsHalfFloatTextures) {
- renderTexture = parameters.context.createOffscreenTexture(size, gfx::TextureChannelDataType::HalfFloat);
-
- if (!renderTexture->isRenderable()) {
- // can't render to a half-float texture; falling back to unsigned byte one
- renderTexture.reset();
- parameters.context.supportsHalfFloatTextures = false;
+LayerRenderer RenderHeatmapLayer::createRenderer() {
+ return [colorRampData = colorRamp, textureData = sharedRenderData](PaintParameters& parameters, const LayerRenderItem& renderItem) {
+ if (parameters.pass == RenderPass::Opaque) {
+ return;
+ }
+ const auto& renderTiles = renderItem.renderTiles;
+ const auto layerId = renderItem.evaluatedProperties->baseImpl->id;
+
+ if (parameters.pass == RenderPass::Pass3D) {
+ const auto& viewportSize = parameters.staticData.backendSize;
+ const auto size = Size{viewportSize.width / 4, viewportSize.height / 4};
+
+ assert(colorRampData);
+ assert(colorRampData->texture);
+ assert(textureData);
+
+ if (!textureData->texture || textureData->texture->getSize() != size) {
+ textureData->texture.reset();
+ if (parameters.context.supportsHalfFloatTextures) {
+ textureData->texture = parameters.context.createOffscreenTexture(size, gfx::TextureChannelDataType::HalfFloat);
+
+ if (!textureData->texture->isRenderable()) {
+ // can't render to a half-float texture; falling back to unsigned byte one
+ textureData->texture.reset();
+ parameters.context.supportsHalfFloatTextures = false;
+ }
}
- }
- if (!renderTexture) {
- renderTexture = parameters.context.createOffscreenTexture(size, gfx::TextureChannelDataType::UnsignedByte);
+ if (!textureData->texture) {
+ textureData->texture = parameters.context.createOffscreenTexture(size, gfx::TextureChannelDataType::UnsignedByte);
+ }
}
- }
- auto renderPass = parameters.encoder->createRenderPass(
- "heatmap texture", { *renderTexture, Color{ 0.0f, 0.0f, 0.0f, 1.0f }, {}, {} });
+ auto renderPass = parameters.encoder->createRenderPass(
+ "heatmap texture", { *textureData->texture, Color{ 0.0f, 0.0f, 0.0f, 1.0f }, {}, {} });
- for (const RenderTile& tile : renderTiles) {
- const LayerRenderData* renderData = tile.getLayerRenderData(*baseImpl);
- if (!renderData) {
- continue;
+ for (const RenderTile& tile : renderTiles) {
+ const LayerRenderData* renderData = tile.getLayerRenderData(*renderItem.evaluatedProperties->baseImpl);
+ if (!renderData) {
+ continue;
+ }
+ auto& bucket = static_cast<HeatmapBucket&>(*renderData->bucket);
+ const auto& evaluated = getEvaluated<HeatmapLayerProperties>(renderData->layerProperties);
+
+ const auto extrudeScale = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
+
+ const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(layerId);
+
+ auto& programInstance = parameters.programs.getHeatmapLayerPrograms().heatmap;
+
+ const auto allUniformValues = programInstance.computeAllUniformValues(
+ HeatmapProgram::LayoutUniformValues {
+ uniforms::intensity::Value( evaluated.get<style::HeatmapIntensity>() ),
+ uniforms::matrix::Value( tile.matrix ),
+ uniforms::heatmap::extrude_scale::Value( extrudeScale )
+ },
+ paintPropertyBinders,
+ evaluated,
+ parameters.state.getZoom()
+ );
+ const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
+ *bucket.vertexBuffer,
+ paintPropertyBinders,
+ evaluated
+ );
+
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+
+ programInstance.draw(
+ parameters.context,
+ *renderPass,
+ gfx::Triangles(),
+ parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::StencilMode::disabled(),
+ gfx::ColorMode::additive(),
+ gfx::CullFaceMode::disabled(),
+ *bucket.indexBuffer,
+ bucket.segments,
+ allUniformValues,
+ allAttributeBindings,
+ HeatmapProgram::TextureBindings{},
+ layerId
+ );
}
- auto& bucket = static_cast<HeatmapBucket&>(*renderData->bucket);
- const auto& evaluated = getEvaluated<HeatmapLayerProperties>(renderData->layerProperties);
- const auto extrudeScale = tile.id.pixelsToTileUnits(1, parameters.state.getZoom());
+ } else if (parameters.pass == RenderPass::Translucent) {
+ const auto& size = parameters.staticData.backendSize;
+
+ mat4 viewportMat;
+ matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
- const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
+ const Properties<>::PossiblyEvaluated properties;
+ const HeatmapTextureProgram::Binders paintAttributeData{ properties, 0 };
- auto& programInstance = parameters.programs.getHeatmapLayerPrograms().heatmap;
+ auto& programInstance = parameters.programs.getHeatmapLayerPrograms().heatmapTexture;
const auto allUniformValues = programInstance.computeAllUniformValues(
- HeatmapProgram::LayoutUniformValues {
- uniforms::intensity::Value( evaluated.get<style::HeatmapIntensity>() ),
- uniforms::matrix::Value( tile.matrix ),
- uniforms::heatmap::extrude_scale::Value( extrudeScale )
+ HeatmapTextureProgram::LayoutUniformValues{
+ uniforms::matrix::Value( viewportMat ),
+ uniforms::world::Value( size ),
+ uniforms::opacity::Value( getEvaluated<HeatmapLayerProperties>(renderItem.evaluatedProperties).get<HeatmapOpacity>() )
},
- paintPropertyBinders,
- evaluated,
+ paintAttributeData,
+ properties,
parameters.state.getZoom()
);
const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *bucket.vertexBuffer,
- paintPropertyBinders,
- evaluated
+ *parameters.staticData.heatmapTextureVertexBuffer,
+ paintAttributeData,
+ properties
);
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
+ renderItem.checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
+ assert(textureData->texture);
programInstance.draw(
parameters.context,
- *renderPass,
+ *parameters.renderPass,
gfx::Triangles(),
- parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly),
+ gfx::DepthMode::disabled(),
gfx::StencilMode::disabled(),
- gfx::ColorMode::additive(),
+ parameters.colorModeForRenderPass(),
gfx::CullFaceMode::disabled(),
- *bucket.indexBuffer,
- bucket.segments,
+ *parameters.staticData.quadTriangleIndexBuffer,
+ parameters.staticData.heatmapTextureSegments,
allUniformValues,
allAttributeBindings,
- HeatmapProgram::TextureBindings{},
- getID()
+ HeatmapTextureProgram::TextureBindings{
+ textures::image::Value{ textureData->texture->getTexture().getResource(), gfx::TextureFilterType::Linear },
+ textures::color_ramp::Value{ colorRampData->texture->getResource(), gfx::TextureFilterType::Linear },
+ },
+ layerId
);
}
+ };
+}
- } else if (parameters.pass == RenderPass::Translucent) {
- const auto& size = parameters.staticData.backendSize;
-
- mat4 viewportMat;
- matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
-
- const Properties<>::PossiblyEvaluated properties;
- const HeatmapTextureProgram::Binders paintAttributeData{ properties, 0 };
-
- auto& programInstance = parameters.programs.getHeatmapLayerPrograms().heatmapTexture;
-
- const auto allUniformValues = programInstance.computeAllUniformValues(
- HeatmapTextureProgram::LayoutUniformValues{
- uniforms::matrix::Value( viewportMat ),
- uniforms::world::Value( size ),
- uniforms::opacity::Value( getEvaluated<HeatmapLayerProperties>(evaluatedProperties).get<HeatmapOpacity>() )
- },
- paintAttributeData,
- properties,
- parameters.state.getZoom()
- );
- const auto allAttributeBindings = programInstance.computeAllAttributeBindings(
- *parameters.staticData.heatmapTextureVertexBuffer,
- paintAttributeData,
- properties
- );
-
- checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings));
-
- programInstance.draw(
- parameters.context,
- *parameters.renderPass,
- gfx::Triangles(),
- gfx::DepthMode::disabled(),
- gfx::StencilMode::disabled(),
- parameters.colorModeForRenderPass(),
- gfx::CullFaceMode::disabled(),
- *parameters.staticData.quadTriangleIndexBuffer,
- parameters.staticData.heatmapTextureSegments,
- allUniformValues,
- allAttributeBindings,
- HeatmapTextureProgram::TextureBindings{
- textures::image::Value{ renderTexture->getTexture().getResource(), gfx::TextureFilterType::Linear },
- textures::color_ramp::Value{ colorRampTexture->getResource(), gfx::TextureFilterType::Linear },
- },
- getID()
- );
- }
+LayerUploader RenderHeatmapLayer::createUploader() {
+ return [colorRampData = colorRamp] (gfx::UploadPass& uploadPass) {
+ if (colorRampData) colorRampData->upload(uploadPass);
+ };
+}
+
+void RenderHeatmapLayer::transition(const TransitionParameters& parameters) {
+ unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated));
+ updateColorRamp();
+}
+
+void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters) {
+ auto properties = makeMutable<HeatmapLayerProperties>(
+ staticImmutableCast<HeatmapLayer::Impl>(baseImpl),
+ unevaluated.evaluate(parameters));
+
+ passes = (properties->evaluated.get<style::HeatmapOpacity>() > 0)
+ ? (RenderPass::Translucent | RenderPass::Pass3D)
+ : RenderPass::None;
+
+ evaluatedProperties = std::move(properties);
+}
+
+bool RenderHeatmapLayer::hasTransition() const {
+ return unevaluated.hasTransition();
+}
+
+bool RenderHeatmapLayer::hasCrossfade() const {
+ return false;
}
void RenderHeatmapLayer::updateColorRamp() {
@@ -197,20 +204,7 @@ void RenderHeatmapLayer::updateColorRamp() {
if (colorValue.isUndefined()) {
colorValue = HeatmapLayer::getDefaultHeatmapColor();
}
-
- const auto length = colorRamp.bytes();
-
- for (uint32_t i = 0; i < length; i += 4) {
- const auto color = colorValue.evaluate(static_cast<double>(i) / length);
- colorRamp.data[i + 0] = std::floor(color.r * 255);
- colorRamp.data[i + 1] = std::floor(color.g * 255);
- colorRamp.data[i + 2] = std::floor(color.b * 255);
- colorRamp.data[i + 3] = std::floor(color.a * 255);
- }
-
- if (colorRampTexture) {
- colorRampTexture = nullopt;
- }
+ colorRamp = std::make_shared<ColorRampRenderData>(colorValue);
}
bool RenderHeatmapLayer::queryIntersectsFeature(
diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.hpp b/src/mbgl/renderer/layers/render_heatmap_layer.hpp
index 27e27adb28..229a0eabbd 100644
--- a/src/mbgl/renderer/layers/render_heatmap_layer.hpp
+++ b/src/mbgl/renderer/layers/render_heatmap_layer.hpp
@@ -3,24 +3,28 @@
#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/style/layers/heatmap_layer_impl.hpp>
#include <mbgl/style/layers/heatmap_layer_properties.hpp>
-#include <mbgl/gfx/texture.hpp>
#include <mbgl/gfx/offscreen_texture.hpp>
-#include <mbgl/util/optional.hpp>
namespace mbgl {
+class ColorRampRenderData;
+
class RenderHeatmapLayer final : public RenderLayer {
public:
+ struct RenderData {
+ std::unique_ptr<gfx::OffscreenTexture> texture = nullptr;
+ };
explicit RenderHeatmapLayer(Immutable<style::HeatmapLayer::Impl>);
~RenderHeatmapLayer() override;
private:
+ LayerRenderer createRenderer() override;
+ LayerUploader createUploader() override;
void transition(const TransitionParameters&) override;
void evaluate(const PropertyEvaluationParameters&) override;
bool hasTransition() const override;
bool hasCrossfade() const override;
- void upload(gfx::UploadPass&) override;
- void render(PaintParameters&) override;
+ void render(PaintParameters&) override {}
bool queryIntersectsFeature(
const GeometryCoordinates&,
@@ -32,11 +36,11 @@ private:
// Paint properties
style::HeatmapPaintProperties::Unevaluated unevaluated;
- PremultipliedImage colorRamp;
- std::unique_ptr<gfx::OffscreenTexture> renderTexture;
- optional<gfx::Texture> colorRampTexture;
+ // Data shared between renderItems.
+ std::shared_ptr<RenderData> sharedRenderData;
void updateColorRamp();
+ std::shared_ptr<ColorRampRenderData> colorRamp;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp
index e300f95e5b..930e83ddc1 100644
--- a/src/mbgl/renderer/layers/render_line_layer.hpp
+++ b/src/mbgl/renderer/layers/render_line_layer.hpp
@@ -17,7 +17,6 @@ public:
~RenderLineLayer() override;
private:
- // LayerRenderItem createRenderItem() override;
LayerRenderer createRenderer() override;
LayerUploader createUploader() override;
void transition(const TransitionParameters&) override;
diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp
index 7d02ccb050..3813e9f6b6 100644
--- a/src/mbgl/renderer/render_layer.cpp
+++ b/src/mbgl/renderer/render_layer.cpp
@@ -63,7 +63,7 @@ LayerRenderer RenderLayer::createRenderer() {
}
LayerUploader RenderLayer::createUploader() {
- return [this](gfx::UploadPass& pass){ upload(pass); };
+ return {};
}
RenderLayer::RenderLayer(Immutable<style::LayerProperties> properties)
diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp
index 6752fd3dc8..dbc3572e86 100644
--- a/src/mbgl/renderer/render_layer.hpp
+++ b/src/mbgl/renderer/render_layer.hpp
@@ -57,7 +57,7 @@ public:
RenderTiles renderTiles;
LayerRenderer renderer;
- LayerUploader uploader; // optionally initialized.
+ LayerUploader uploader;
Immutable<style::LayerProperties> evaluatedProperties;
void checkRenderability(const PaintParameters&, uint32_t activeBindingCount) const;
@@ -114,7 +114,6 @@ public:
// Checks whether the given zoom is inside this layer zoom range.
bool supportsZoom(float zoom) const;
- virtual void upload(gfx::UploadPass&) {}
virtual void render(PaintParameters&) = 0;
// Check wether the given geometry intersects