diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2018-05-04 01:31:43 +0200 |
---|---|---|
committer | Lauren Budorick <lauren@mapbox.com> | 2018-05-03 16:31:43 -0700 |
commit | c3346f473ac7e3d49219c8dbc381d92f8fe3f017 (patch) | |
tree | 7e7d1c1569c849192209b0c5f5a58ef7736896a1 /src/mbgl/renderer | |
parent | f6da3ba9be27ff9b279730603c517c4cb5e57007 (diff) | |
download | qtlocation-mapboxgl-c3346f473ac7e3d49219c8dbc381d92f8fe3f017.tar.gz |
[core] Don't crash when attribute count is exceeded
Diffstat (limited to 'src/mbgl/renderer')
-rw-r--r-- | src/mbgl/renderer/layers/render_background_layer.cpp | 63 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_circle_layer.cpp | 37 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp | 91 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_fill_layer.cpp | 66 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_heatmap_layer.cpp | 68 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_hillshade_layer.cpp | 65 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_line_layer.cpp | 27 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_raster_layer.cpp | 33 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.cpp | 31 | ||||
-rw-r--r-- | src/mbgl/renderer/render_layer.cpp | 29 | ||||
-rw-r--r-- | src/mbgl/renderer/render_layer.hpp | 11 | ||||
-rw-r--r-- | src/mbgl/renderer/render_tile.cpp | 70 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 24 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_image_source.cpp | 28 |
14 files changed, 462 insertions, 181 deletions
diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index aebc4cc9aa..f22402ac98 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -49,6 +49,35 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { const Properties<>::PossiblyEvaluated properties; const BackgroundProgram::PaintPropertyBinders paintAttributeData(properties, 0); + auto draw = [&](auto& program, auto&& uniformValues) { + const auto allUniformValues = program.computeAllUniformValues( + std::move(uniformValues), + paintAttributeData, + properties, + parameters.state.getZoom() + ); + const auto allAttributeBindings = program.computeAllAttributeBindings( + parameters.staticData.tileVertexBuffer, + paintAttributeData, + properties + ); + + checkRenderability(parameters, program.activeBindingCount(allAttributeBindings)); + + program.draw( + parameters.context, + gl::Triangles(), + parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), + gl::StencilMode::disabled(), + parameters.colorModeForRenderPass(), + parameters.staticData.quadTriangleIndexBuffer, + parameters.staticData.tileTriangleSegments, + allUniformValues, + allAttributeBindings, + getID() + ); + }; + if (!evaluated.get<BackgroundPattern>().to.empty()) { optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<BackgroundPattern>().from); optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<BackgroundPattern>().to); @@ -59,12 +88,8 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { parameters.imageManager.bind(parameters.context, 0); for (const auto& tileID : util::tileCover(parameters.state, parameters.state.getIntegerZoom())) { - parameters.programs.backgroundPattern.draw( - parameters.context, - gl::Triangles(), - parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), - gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), + draw( + parameters.programs.backgroundPattern, BackgroundPatternUniforms::values( parameters.matrixForTile(tileID), evaluated.get<BackgroundOpacity>(), @@ -74,36 +99,18 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { evaluated.get<BackgroundPattern>(), tileID, parameters.state - ), - parameters.staticData.tileVertexBuffer, - parameters.staticData.quadTriangleIndexBuffer, - parameters.staticData.tileTriangleSegments, - paintAttributeData, - properties, - parameters.state.getZoom(), - getID() + ) ); } } else { for (const auto& tileID : util::tileCover(parameters.state, parameters.state.getIntegerZoom())) { - parameters.programs.background.draw( - parameters.context, - gl::Triangles(), - parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), - gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), + draw( + parameters.programs.background, BackgroundProgram::UniformValues { uniforms::u_matrix::Value{ parameters.matrixForTile(tileID) }, uniforms::u_color::Value{ evaluated.get<BackgroundColor>() }, uniforms::u_opacity::Value{ evaluated.get<BackgroundOpacity>() }, - }, - parameters.staticData.tileVertexBuffer, - parameters.staticData.quadTriangleIndexBuffer, - parameters.staticData.tileTriangleSegments, - paintAttributeData, - properties, - parameters.state.getZoom(), - getID() + } ); } } diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index 6092ff5452..4c96137143 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -59,14 +59,11 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { assert(dynamic_cast<CircleBucket*>(tile.tile.getBucket(*baseImpl))); CircleBucket& bucket = *reinterpret_cast<CircleBucket*>(tile.tile.getBucket(*baseImpl)); - parameters.programs.circle.get(evaluated).draw( - parameters.context, - gl::Triangles(), - parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), - parameters.mapMode != MapMode::Continuous - ? parameters.stencilModeForClipping(tile.clip) - : gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), + const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + + auto& programInstance = parameters.programs.circle.get(evaluated); + + const auto allUniformValues = programInstance.computeAllUniformValues( CircleProgram::UniformValues { uniforms::u_matrix::Value{ tile.translatedMatrix(evaluated.get<CircleTranslate>(), @@ -82,12 +79,30 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { uniforms::u_camera_to_center_distance::Value{ parameters.state.getCameraToCenterDistance() }, uniforms::u_pitch_with_map::Value{ pitchWithMap } }, + paintPropertyBinders, + evaluated, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( *bucket.vertexBuffer, + paintPropertyBinders, + evaluated + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( + parameters.context, + gl::Triangles(), + parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), + parameters.mapMode != MapMode::Continuous + ? parameters.stencilModeForClipping(tile.clip) + : gl::StencilMode::disabled(), + parameters.colorModeForRenderPass(), *bucket.indexBuffer, bucket.segments, - bucket.paintPropertyBinders.at(getID()), - evaluated, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); } diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index fbd6160e8a..00ab05858f 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -68,24 +68,53 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* parameters.context.setStencilMode(gl::StencilMode::disabled()); parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {}); + auto draw = [&](auto& programInstance, const auto& tileBucket, auto&& uniformValues) { + const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID()); + + const auto allUniformValues = programInstance.computeAllUniformValues( + std::move(uniformValues), + paintPropertyBinders, + evaluated, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( + *tileBucket.vertexBuffer, + paintPropertyBinders, + evaluated + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( + parameters.context, + gl::Triangles(), + parameters.depthModeFor3D(gl::DepthMode::ReadWrite), + gl::StencilMode::disabled(), + parameters.colorModeForRenderPass(), + *tileBucket.indexBuffer, + tileBucket.triangleSegments, + allUniformValues, + allAttributeBindings, + getID()); + }; + if (evaluated.get<FillExtrusionPattern>().from.empty()) { for (const RenderTile& tile : renderTiles) { assert(dynamic_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl))); FillExtrusionBucket& bucket = *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)); - parameters.programs.fillExtrusion.get(evaluated).draw( - parameters.context, gl::Triangles(), - parameters.depthModeFor3D(gl::DepthMode::ReadWrite), - gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), + draw( + parameters.programs.fillExtrusion.get(evaluated), + bucket, FillExtrusionUniforms::values( tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), evaluated.get<FillExtrusionTranslateAnchor>(), parameters.state), - parameters.state, parameters.evaluatedLight), - *bucket.vertexBuffer, *bucket.indexBuffer, bucket.triangleSegments, - bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(), - getID()); + parameters.state, + parameters.evaluatedLight + ) + ); } } else { optional<ImagePosition> imagePosA = @@ -104,10 +133,9 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* FillExtrusionBucket& bucket = *reinterpret_cast<FillExtrusionBucket*>(tile.tile.getBucket(*baseImpl)); - parameters.programs.fillExtrusionPattern.get(evaluated).draw( - parameters.context, gl::Triangles(), - parameters.depthModeFor3D(gl::DepthMode::ReadWrite), - gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), + draw( + parameters.programs.fillExtrusionPattern.get(evaluated), + bucket, FillExtrusionPatternUniforms::values( tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), evaluated.get<FillExtrusionTranslateAnchor>(), @@ -115,10 +143,9 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, evaluated.get<FillExtrusionPattern>(), tile.id, parameters.state, -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f, - parameters.evaluatedLight), - *bucket.vertexBuffer, *bucket.indexBuffer, bucket.triangleSegments, - bucket.paintPropertyBinders.at(getID()), evaluated, parameters.state.getZoom(), - getID()); + parameters.evaluatedLight + ) + ); } } @@ -131,19 +158,39 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1); const Properties<>::PossiblyEvaluated properties; + const ExtrusionTextureProgram::PaintPropertyBinders paintAttributeData{ properties, 0 }; + + auto& programInstance = parameters.programs.extrusionTexture; - parameters.programs.extrusionTexture.draw( - parameters.context, gl::Triangles(), gl::DepthMode::disabled(), - gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), + const auto allUniformValues = programInstance.computeAllUniformValues( ExtrusionTextureProgram::UniformValues{ uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, uniforms::u_image::Value{ 0 }, - uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() } }, + uniforms::u_opacity::Value{ evaluated.get<FillExtrusionOpacity>() } + }, + paintAttributeData, + properties, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( parameters.staticData.extrusionTextureVertexBuffer, + paintAttributeData, + properties + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( + parameters.context, + gl::Triangles(), + gl::DepthMode::disabled(), + gl::StencilMode::disabled(), + parameters.colorModeForRenderPass(), parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.extrusionTextureSegments, - ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties, - parameters.state.getZoom(), getID()); + allUniformValues, + allAttributeBindings, + getID()); } } diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 22cb9563c1..2607ebc170 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -69,12 +69,11 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { const auto& depthMode, const auto& indexBuffer, const auto& segments) { - program.get(evaluated).draw( - parameters.context, - drawMode, - depthMode, - parameters.stencilModeForClipping(tile.clip), - parameters.colorModeForRenderPass(), + auto& programInstance = program.get(evaluated); + + const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + + const auto allUniformValues = programInstance.computeAllUniformValues( FillProgram::UniformValues { uniforms::u_matrix::Value{ tile.translatedMatrix(evaluated.get<FillTranslate>(), @@ -83,12 +82,28 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { }, uniforms::u_world::Value{ parameters.context.viewport.getCurrentValue().size }, }, + paintPropertyBinders, + evaluated, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( *bucket.vertexBuffer, + paintPropertyBinders, + evaluated + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( + parameters.context, + drawMode, + depthMode, + parameters.stencilModeForClipping(tile.clip), + parameters.colorModeForRenderPass(), indexBuffer, segments, - bucket.paintPropertyBinders.at(getID()), - evaluated, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); }; @@ -139,12 +154,11 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { const auto& depthMode, const auto& indexBuffer, const auto& segments) { - program.get(evaluated).draw( - parameters.context, - drawMode, - depthMode, - parameters.stencilModeForClipping(tile.clip), - parameters.colorModeForRenderPass(), + auto& programInstance = program.get(evaluated); + + const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + + const auto allUniformValues = programInstance.computeAllUniformValues( FillPatternUniforms::values( tile.translatedMatrix(evaluated.get<FillTranslate>(), evaluated.get<FillTranslateAnchor>(), @@ -157,12 +171,28 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { tile.id, parameters.state ), + paintPropertyBinders, + evaluated, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( *bucket.vertexBuffer, + paintPropertyBinders, + evaluated + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( + parameters.context, + drawMode, + depthMode, + parameters.stencilModeForClipping(tile.clip), + parameters.colorModeForRenderPass(), indexBuffer, segments, - bucket.paintPropertyBinders.at(getID()), - evaluated, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); }; diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index 4f2e899220..86884b01a4 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -92,23 +92,38 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { ? parameters.stencilModeForClipping(tile.clip) : gl::StencilMode::disabled(); - parameters.programs.heatmap.get(evaluated).draw( + const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + + auto& programInstance = parameters.programs.heatmap.get(evaluated); + + const auto allUniformValues = programInstance.computeAllUniformValues( + HeatmapProgram::UniformValues { + uniforms::u_intensity::Value{ evaluated.get<style::HeatmapIntensity>() }, + uniforms::u_matrix::Value{ tile.matrix }, + uniforms::heatmap::u_extrude_scale::Value{ extrudeScale } + }, + paintPropertyBinders, + evaluated, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( + *bucket.vertexBuffer, + paintPropertyBinders, + evaluated + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( parameters.context, gl::Triangles(), parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), stencilMode, gl::ColorMode::additive(), - HeatmapProgram::UniformValues { - uniforms::u_intensity::Value{evaluated.get<style::HeatmapIntensity>()}, - uniforms::u_matrix::Value{tile.matrix}, - uniforms::heatmap::u_extrude_scale::Value{extrudeScale} - }, - *bucket.vertexBuffer, *bucket.indexBuffer, bucket.segments, - bucket.paintPropertyBinders.at(getID()), - evaluated, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); } @@ -123,20 +138,41 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1); const Properties<>::PossiblyEvaluated properties; + const HeatmapTextureProgram::PaintPropertyBinders paintAttributeData{ properties, 0 }; + + auto& programInstance = parameters.programs.heatmapTexture; - parameters.programs.heatmapTexture.draw( - parameters.context, gl::Triangles(), gl::DepthMode::disabled(), - gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), + const auto allUniformValues = programInstance.computeAllUniformValues( HeatmapTextureProgram::UniformValues{ uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size }, uniforms::u_image::Value{ 0 }, uniforms::u_color_ramp::Value{ 1 }, - uniforms::u_opacity::Value{ evaluated.get<HeatmapOpacity>() } }, + uniforms::u_opacity::Value{ evaluated.get<HeatmapOpacity>() } + }, + paintAttributeData, + properties, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( parameters.staticData.extrusionTextureVertexBuffer, + paintAttributeData, + properties + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( + parameters.context, + gl::Triangles(), + gl::DepthMode::disabled(), + gl::StencilMode::disabled(), + parameters.colorModeForRenderPass(), parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.extrusionTextureSegments, - HeatmapTextureProgram::PaintPropertyBinders{ properties, 0 }, properties, - parameters.state.getZoom(), getID()); + allUniformValues, + allAttributeBindings, + getID() + ); } } diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index bcfd4ffe99..411305edf4 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -69,12 +69,11 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src const auto& indexBuffer, const auto& segments, const UnwrappedTileID& id) { - parameters.programs.hillshade.draw( - parameters.context, - gl::Triangles(), - parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), - gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), + auto& programInstance = parameters.programs.hillshade; + + const HillshadeProgram::PaintPropertyBinders paintAttributeData{ evaluated, 0 }; + + const auto allUniformValues = programInstance.computeAllUniformValues( HillshadeProgram::UniformValues { uniforms::u_matrix::Value{ matrix }, uniforms::u_image::Value{ 0 }, @@ -84,12 +83,28 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src uniforms::u_light::Value{ getLight(parameters) }, uniforms::u_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, + gl::Triangles(), + parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), + gl::StencilMode::disabled(), + parameters.colorModeForRenderPass(), indexBuffer, segments, - HillshadeProgram::PaintPropertyBinders { evaluated, 0 }, - evaluated, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); }; @@ -112,13 +127,11 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src parameters.context.bindTexture(*bucket.dem, 0, gl::TextureFilter::Nearest, gl::TextureMipMap::No, gl::TextureWrap::Clamp, gl::TextureWrap::Clamp); const Properties<>::PossiblyEvaluated properties; + const HillshadePrepareProgram::PaintPropertyBinders paintAttributeData{ properties, 0 }; - parameters.programs.hillshadePrepare.draw( - parameters.context, - gl::Triangles(), - parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), - gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), + auto& programInstance = parameters.programs.hillshadePrepare; + + const auto allUniformValues = programInstance.computeAllUniformValues( HillshadePrepareProgram::UniformValues { uniforms::u_matrix::Value { mat }, uniforms::u_dimension::Value { {{uint16_t(tilesize * 2), uint16_t(tilesize * 2) }} }, @@ -126,12 +139,28 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src uniforms::u_maxzoom::Value{ float(maxzoom) }, uniforms::u_image::Value{ 0 } }, + paintAttributeData, + properties, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( parameters.staticData.rasterVertexBuffer, + paintAttributeData, + properties + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( + parameters.context, + gl::Triangles(), + parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), + gl::StencilMode::disabled(), + parameters.colorModeForRenderPass(), parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.rasterSegments, - HillshadePrepareProgram::PaintPropertyBinders { properties, 0 }, - properties, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); bucket.texture = std::move(view.getTexture()); diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 1b4a1c0ff7..e7fe4d34b2 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -62,19 +62,34 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { LineBucket& bucket = *reinterpret_cast<LineBucket*>(tile.tile.getBucket(*baseImpl)); auto draw = [&] (auto& program, auto&& uniformValues) { - program.get(evaluated).draw( + auto& programInstance = program.get(evaluated); + + const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + + const auto allUniformValues = programInstance.computeAllUniformValues( + std::move(uniformValues), + paintPropertyBinders, + evaluated, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( + *bucket.vertexBuffer, + paintPropertyBinders, + evaluated + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( parameters.context, gl::Triangles(), parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), parameters.stencilModeForClipping(tile.clip), parameters.colorModeForRenderPass(), - std::move(uniformValues), - *bucket.vertexBuffer, *bucket.indexBuffer, bucket.segments, - bucket.paintPropertyBinders.at(getID()), - evaluated, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); }; diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp index b41b2ac560..f202ed4ebb 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.cpp +++ b/src/mbgl/renderer/layers/render_raster_layer.cpp @@ -73,16 +73,15 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source if (parameters.pass != RenderPass::Translucent) return; + RasterProgram::PaintPropertyBinders paintAttributeData{ evaluated, 0 }; + auto draw = [&] (const mat4& matrix, const auto& vertexBuffer, const auto& indexBuffer, const auto& segments) { - parameters.programs.raster.draw( - parameters.context, - gl::Triangles(), - parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), - gl::StencilMode::disabled(), - parameters.colorModeForRenderPass(), + auto& programInstance = parameters.programs.raster; + + const auto allUniformValues = programInstance.computeAllUniformValues( RasterProgram::UniformValues { uniforms::u_matrix::Value{ matrix }, uniforms::u_image0::Value{ 0 }, @@ -98,12 +97,28 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source uniforms::u_scale_parent::Value{ 1.0f }, uniforms::u_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, + gl::Triangles(), + parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), + gl::StencilMode::disabled(), + parameters.colorModeForRenderPass(), indexBuffer, segments, - RasterProgram::PaintPropertyBinders { evaluated, 0 }, - evaluated, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); }; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 9e493003c0..e48c0e2f92 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -88,7 +88,26 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { const auto& binders, const auto& paintProperties) { - program.get(paintProperties).draw( + auto& programInstance = program.get(paintProperties); + + const auto allUniformValues = programInstance.computeAllUniformValues( + std::move(uniformValues), + *symbolSizeBinder, + binders, + paintProperties, + parameters.state.getZoom() + ); + const auto allAttributeBindings = programInstance.computeAllAttributeBindings( + *buffers.vertexBuffer, + *buffers.dynamicVertexBuffer, + *buffers.opacityVertexBuffer, + binders, + paintProperties + ); + + checkRenderability(parameters, programInstance.activeBindingCount(allAttributeBindings)); + + programInstance.draw( parameters.context, gl::Triangles(), values_.pitchAlignment == AlignmentType::Map @@ -96,16 +115,10 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { : gl::DepthMode::disabled(), gl::StencilMode::disabled(), parameters.colorModeForRenderPass(), - std::move(uniformValues), - *buffers.vertexBuffer, - *buffers.dynamicVertexBuffer, - *buffers.opacityVertexBuffer, - *symbolSizeBinder, *buffers.indexBuffer, buffers.segments, - binders, - paintProperties, - parameters.state.getZoom(), + allUniformValues, + allAttributeBindings, getID() ); }; diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index bcdc175f14..a667d5837e 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -9,8 +9,10 @@ #include <mbgl/renderer/layers/render_raster_layer.hpp> #include <mbgl/renderer/layers/render_symbol_layer.hpp> #include <mbgl/renderer/layers/render_heatmap_layer.hpp> +#include <mbgl/renderer/paint_parameters.hpp> #include <mbgl/style/types.hpp> #include <mbgl/renderer/render_tile.hpp> +#include <mbgl/util/logging.hpp> namespace mbgl { @@ -73,5 +75,32 @@ void RenderLayer::setRenderTiles(std::vector<std::reference_wrapper<RenderTile>> renderTiles = std::move(tiles); } +void RenderLayer::checkRenderability(const PaintParameters& parameters, + const uint32_t activeBindingCount) { + // Only warn once for every layer. + if (hasRenderFailures) { + return; + } + + if (activeBindingCount > parameters.context.maximumVertexBindingCount) { + Log::Error(Event::OpenGL, + "The layer '%s' uses more data-driven properties than the current device " + "supports, and will have rendering errors. To ensure compatibility with this " + "device, use %d fewer data driven properties in this layer.", + getID().c_str(), + activeBindingCount - parameters.context.minimumRequiredVertexBindingCount); + hasRenderFailures = true; + } else if (activeBindingCount > parameters.context.minimumRequiredVertexBindingCount) { + Log::Error(Event::OpenGL, + "The layer '%s' uses more data-driven properties than some devices may support. " + "Though it will render correctly on this device, it may have rendering errors " + "on other devices. To ensure compatibility with all devices, use %d fewer " + "data-driven properties in this layer.", + getID().c_str(), + activeBindingCount - parameters.context.minimumRequiredVertexBindingCount); + hasRenderFailures = true; + } +} + } //namespace mbgl diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 55831cb72c..5b92ffa4db 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -82,6 +82,11 @@ public: friend std::string layoutKey(const RenderLayer&); protected: + // Checks whether the current hardware can render this layer. If it can't, we'll show a warning + // in the console to inform the developer. + void checkRenderability(const PaintParameters&, uint32_t activeBindingCount); + +protected: // renderTiles are exposed directly to CrossTileSymbolIndex and Placement so they // can update opacities in the symbol buckets immediately before rendering friend class CrossTileSymbolIndex; @@ -92,6 +97,12 @@ protected: // Stores what render passes this layer is currently enabled for. This depends on the // evaluated StyleProperties object and is updated accordingly. RenderPass passes = RenderPass::None; + +private: + // Some layers may not render correctly on some hardware when the vertex attribute limit of + // that GPU is exceeded. More attributes are used when adding many data driven paint properties + // to a layer. + bool hasRenderFailures = false; }; } // namespace mbgl diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index 35b34833e4..64790938ef 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -74,6 +74,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { static const style::Properties<>::PossiblyEvaluated properties {}; static const DebugProgram::PaintPropertyBinders paintAttributeData(properties, 0); + auto& program = parameters.programs.debug; + if (parameters.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) { if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() || tile.debugBucket->complete != tile.isComplete() || @@ -85,41 +87,51 @@ void RenderTile::finishRender(PaintParameters& parameters) { tile.expires, parameters.debugOptions, parameters.context); } - parameters.programs.debug.draw( + const auto allAttributeBindings = program.computeAllAttributeBindings( + *tile.debugBucket->vertexBuffer, + paintAttributeData, + properties + ); + + program.draw( parameters.context, gl::Lines { 4.0f * parameters.pixelRatio }, gl::DepthMode::disabled(), parameters.stencilModeForClipping(clip), gl::ColorMode::unblended(), - DebugProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_color::Value{ Color::white() } - }, - *tile.debugBucket->vertexBuffer, *tile.debugBucket->indexBuffer, tile.debugBucket->segments, - paintAttributeData, - properties, - parameters.state.getZoom(), + program.computeAllUniformValues( + DebugProgram::UniformValues { + uniforms::u_matrix::Value{ matrix }, + uniforms::u_color::Value{ Color::white() } + }, + paintAttributeData, + properties, + parameters.state.getZoom() + ), + allAttributeBindings, "debug" ); - parameters.programs.debug.draw( + program.draw( parameters.context, gl::Lines { 2.0f * parameters.pixelRatio }, gl::DepthMode::disabled(), parameters.stencilModeForClipping(clip), gl::ColorMode::unblended(), - DebugProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_color::Value{ Color::black() } - }, - *tile.debugBucket->vertexBuffer, *tile.debugBucket->indexBuffer, tile.debugBucket->segments, - paintAttributeData, - properties, - parameters.state.getZoom(), + program.computeAllUniformValues( + DebugProgram::UniformValues { + uniforms::u_matrix::Value{ matrix }, + uniforms::u_color::Value{ Color::black() } + }, + paintAttributeData, + properties, + parameters.state.getZoom() + ), + allAttributeBindings, "debug" ); } @@ -131,16 +143,22 @@ void RenderTile::finishRender(PaintParameters& parameters) { gl::DepthMode::disabled(), parameters.stencilModeForClipping(clip), gl::ColorMode::unblended(), - DebugProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_color::Value{ Color::red() } - }, - parameters.staticData.tileVertexBuffer, parameters.staticData.tileBorderIndexBuffer, parameters.staticData.tileBorderSegments, - paintAttributeData, - properties, - parameters.state.getZoom(), + program.computeAllUniformValues( + DebugProgram::UniformValues { + uniforms::u_matrix::Value{ matrix }, + uniforms::u_color::Value{ Color::red() } + }, + paintAttributeData, + properties, + parameters.state.getZoom() + ), + program.computeAllAttributeBindings( + parameters.staticData.tileVertexBuffer, + paintAttributeData, + properties + ), "debug" ); } diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 2ac714e122..7b25b37cf2 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -495,7 +495,9 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { static const ClippingMaskProgram::PaintPropertyBinders paintAttributeData(properties, 0); for (const auto& clipID : parameters.clipIDGenerator.getClipIDs()) { - parameters.staticData.programs.clippingMask.draw( + auto& program = parameters.staticData.programs.clippingMask; + + program.draw( parameters.context, gl::Triangles(), gl::DepthMode::disabled(), @@ -508,15 +510,21 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { gl::StencilMode::Replace }, gl::ColorMode::disabled(), - ClippingMaskProgram::UniformValues { - uniforms::u_matrix::Value{ parameters.matrixForTile(clipID.first) }, - }, - parameters.staticData.tileVertexBuffer, parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.tileTriangleSegments, - paintAttributeData, - properties, - parameters.state.getZoom(), + program.computeAllUniformValues( + ClippingMaskProgram::UniformValues { + uniforms::u_matrix::Value{ parameters.matrixForTile(clipID.first) }, + }, + paintAttributeData, + properties, + parameters.state.getZoom() + ), + program.computeAllAttributeBindings( + parameters.staticData.tileVertexBuffer, + paintAttributeData, + properties + ), "clipping" ); } diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index 31a5916a34..4946b0bc30 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -58,24 +58,32 @@ void RenderImageSource::finishRender(PaintParameters& parameters) { static const style::Properties<>::PossiblyEvaluated properties {}; static const DebugProgram::PaintPropertyBinders paintAttributeData(properties, 0); + auto& programInstance = parameters.programs.debug; + for (auto matrix : matrices) { - parameters.programs.debug.draw( + programInstance.draw( parameters.context, gl::LineStrip { 4.0f * parameters.pixelRatio }, gl::DepthMode::disabled(), gl::StencilMode::disabled(), gl::ColorMode::unblended(), - DebugProgram::UniformValues { - uniforms::u_matrix::Value{ matrix }, - uniforms::u_color::Value{ Color::red() } - }, - parameters.staticData.tileVertexBuffer, parameters.staticData.tileBorderIndexBuffer, parameters.staticData.tileBorderSegments, - paintAttributeData, - properties, - parameters.state.getZoom(), - "debug" + programInstance.computeAllUniformValues( + DebugProgram::UniformValues { + uniforms::u_matrix::Value{ matrix }, + uniforms::u_color::Value{ Color::red() } + }, + paintAttributeData, + properties, + parameters.state.getZoom() + ), + programInstance.computeAllAttributeBindings( + parameters.staticData.tileVertexBuffer, + paintAttributeData, + properties + ), + "image" ); } } |