From a876c965a55213f38b91303c81239fbda0a9f7da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 16 Aug 2019 12:03:53 +0200 Subject: [core] Store SegmentVectors in ephemeral render objects We used some shared SegmentVectors, e.g. for drawing raster or background tiles. In longer running maps, this lead to resource accumulation. By storing the SegmentVectors and the contained gfx::DrawScope objects, we ensure that resources get released when the associated render objects vanish. --- .../renderer/layers/render_hillshade_layer.cpp | 80 +++++++++++----------- 1 file changed, 41 insertions(+), 39 deletions(-) (limited to 'src/mbgl/renderer/layers/render_hillshade_layer.cpp') diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index b570d9c4c9..bf899221f8 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -20,7 +20,7 @@ using namespace style; namespace { -inline const HillshadeLayer::Impl& impl(const Immutable& impl) { +inline const HillshadeLayer::Impl& impl_cast(const Immutable& impl) { assert(impl->getTypeInfo() == HillshadeLayer::Impl::staticTypeInfo()); return static_cast(*impl); } @@ -29,8 +29,7 @@ inline const HillshadeLayer::Impl& impl(const Immutable& imp RenderHillshadeLayer::RenderHillshadeLayer(Immutable _impl) : RenderLayer(makeMutable(std::move(_impl))), - unevaluated(impl(baseImpl).paint.untransitioned()) { -} + unevaluated(impl_cast(baseImpl).paint.untransitioned()) {} RenderHillshadeLayer::~RenderHillshadeLayer() = default; @@ -48,7 +47,7 @@ const std::array RenderHillshadeLayer::getLight(const PaintParameters& } void RenderHillshadeLayer::transition(const TransitionParameters& parameters) { - unevaluated = impl(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); + unevaluated = impl_cast(baseImpl).paint.transitioned(parameters, std::move(unevaluated)); } void RenderHillshadeLayer::evaluate(const PropertyEvaluationParameters& parameters) { @@ -111,21 +110,19 @@ void RenderHillshadeLayer::render(PaintParameters& parameters) { 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) - ); + 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()); }; mat4 mat; @@ -177,29 +174,30 @@ void RenderHillshadeLayer::render(PaintParameters& parameters) { 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() }, - }, - getID() + "/p/" + util::toString(tile.id) - ); + // Copy over the segments so that we can create our own DrawScopes that get destroyed + // after this draw call. + auto segments = parameters.staticData.rasterSegments(); + programInstance.draw(parameters.context, + *renderPass, + gfx::Triangles(), + parameters.depthModeForSublayer(0, gfx::DepthMaskType::ReadOnly), + gfx::StencilMode::disabled(), + parameters.colorModeForRenderPass(), + gfx::CullFaceMode::disabled(), + *parameters.staticData.quadTriangleIndexBuffer, + segments, + allUniformValues, + allAttributeBindings, + HillshadePrepareProgram::TextureBindings{ + textures::image::Value{bucket.dem->getResource()}, + }, + "prepare"); 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()) { + if (bucket.vertexBuffer && bucket.indexBuffer) { // 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, @@ -211,13 +209,17 @@ void RenderHillshadeLayer::render(PaintParameters& parameters) { }); } else { // Draw the full tile. + if (bucket.segments.empty()) { + // Copy over the segments so that we can create our own DrawScopes. + bucket.segments = parameters.staticData.rasterSegments(); + } draw(parameters.matrixForTile(tile.id, true), *parameters.staticData.rasterVertexBuffer, *parameters.staticData.quadTriangleIndexBuffer, - parameters.staticData.rasterSegments, + bucket.segments, tile.id, HillshadeProgram::TextureBindings{ - textures::image::Value{ bucket.texture->getResource(), gfx::TextureFilterType::Linear }, + textures::image::Value{bucket.texture->getResource(), gfx::TextureFilterType::Linear}, }); } } -- cgit v1.2.1