From c505d3077e0cfd91a31c2454ad6cb5ea4a9d16a2 Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Fri, 19 May 2023 09:58:27 -0700 Subject: [PATCH] apply color attributes, refactor (#1148) --- CMakeLists.txt | 1 + include/mbgl/gfx/drawable.hpp | 16 +++- include/mbgl/gfx/drawable_builder.hpp | 17 ++++ include/mbgl/gl/drawable_gl.hpp | 7 +- .../mbgl/shaders/gl/drawable_fill_outline.hpp | 84 +++++++++++++++++++ include/mbgl/shaders/shader_manifest.hpp | 1 + include/mbgl/shaders/shader_source.hpp | 1 + shaders/drawable.fill_outline.fragment.glsl | 17 ++++ shaders/drawable.fill_outline.vertex.glsl | 17 ++++ shaders/manifest.json | 7 ++ src/mbgl/gfx/drawable_builder.cpp | 75 ++++++++++++----- src/mbgl/gfx/drawable_builder_impl.hpp | 4 +- src/mbgl/gfx/vertex_vector.hpp | 4 + src/mbgl/gl/drawable_gl.cpp | 21 +++-- src/mbgl/gl/drawable_gl_builder.cpp | 8 +- src/mbgl/gl/drawable_gl_impl.hpp | 17 ++-- src/mbgl/gl/layer_group_gl.cpp | 4 +- src/mbgl/gl/renderer_backend.cpp | 5 +- .../layers/render_background_layer.hpp | 2 + .../renderer/layers/render_fill_layer.cpp | 75 +++++++++++++---- .../renderer/layers/render_fill_layer.hpp | 3 + src/mbgl/renderer/paint_property_binder.hpp | 30 +++++++ src/mbgl/renderer/render_layer.hpp | 1 - 23 files changed, 347 insertions(+), 70 deletions(-) create mode 100644 include/mbgl/shaders/gl/drawable_fill_outline.hpp create mode 100644 shaders/drawable.fill_outline.fragment.glsl create mode 100644 shaders/drawable.fill_outline.vertex.glsl diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b4a67fa6..14bb28fb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -930,6 +930,7 @@ if(MLN_WITH_OPENGL) ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_background.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background_pattern.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/circle.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/clipping_mask.hpp diff --git a/include/mbgl/gfx/drawable.hpp b/include/mbgl/gfx/drawable.hpp index 8c1d540f7..5cea68315 100644 --- a/include/mbgl/gfx/drawable.hpp +++ b/include/mbgl/gfx/drawable.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -54,9 +55,15 @@ public: /// Test whether to draw this drawable in a given render pass. /// If multiple render pass bits are set, all must be present. - bool hasRenderPass(mbgl::RenderPass value) const { - using T = std::underlying_type::type; - return (static_cast(renderPass) & static_cast(value)) == static_cast(value); + bool hasRenderPass(const mbgl::RenderPass value) const { + return (mbgl::underlying_type(renderPass) & mbgl::underlying_type(value)) != 0; + } + + /// Test whether to draw this drawable in a given render pass. + /// If multiple render pass bits are set, all must be present. + bool hasAllRenderPasses(const mbgl::RenderPass value) const { + const auto underlying_value = mbgl::underlying_type(value); + return (mbgl::underlying_type(renderPass) & underlying_value) == underlying_value; } /// not used for anything yet @@ -84,7 +91,8 @@ public: virtual void setVertexAttributes(const gfx::VertexAttributeArray&) = 0; virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0; - virtual std::vector& getIndexData() const = 0; + virtual std::vector& getLineIndexData() const = 0; + virtual std::vector& getTriangleIndexData() const = 0; /// Attach a tweaker to be run on this drawable for each frame void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); } diff --git a/include/mbgl/gfx/drawable_builder.hpp b/include/mbgl/gfx/drawable_builder.hpp index 70fb1d54f..6925e839c 100644 --- a/include/mbgl/gfx/drawable_builder.hpp +++ b/include/mbgl/gfx/drawable_builder.hpp @@ -109,6 +109,23 @@ public: void setVertexAttributes(const VertexAttributeArray&); void setVertexAttributes(VertexAttributeArray&&); + /// Add some vertex elements, returns the index of the first one added + std::size_t addVertices(const std::vector>& vertices, + std::size_t vertexOffset, + std::size_t vertexLength); + + /// Add lines based on existing vertices + void addLines(const std::vector& indexes, + std::size_t indexOffset, + std::size_t indexLength, + std::size_t baseIndex = 0); + + /// Add triangles based on existing vertices + void addTriangles(const std::vector& indexes, + std::size_t indexOffset, + std::size_t indexLength, + std::size_t baseIndex = 0); + /// Add already-set-up triangles directly void addTriangles(const std::vector>& vertices, std::size_t vertexOffset, diff --git a/include/mbgl/gl/drawable_gl.hpp b/include/mbgl/gl/drawable_gl.hpp index f1b757005..8847da65c 100644 --- a/include/mbgl/gl/drawable_gl.hpp +++ b/include/mbgl/gl/drawable_gl.hpp @@ -26,8 +26,11 @@ public: void draw(const PaintParameters&) const override; - void setIndexData(std::vector indexes, std::size_t indexOffset = 0, std::size_t indexLength = 0); - std::vector& getIndexData() const override; + void setLineIndexData(std::vector indexes); + void setTriangleIndexData(std::vector indexes); + + std::vector& getLineIndexData() const override; + std::vector& getTriangleIndexData() const override; const gfx::VertexAttributeArray& getVertexAttributes() const override; void setVertexAttributes(const gfx::VertexAttributeArray& value) override; diff --git a/include/mbgl/shaders/gl/drawable_fill_outline.hpp b/include/mbgl/shaders/gl/drawable_fill_outline.hpp new file mode 100644 index 000000000..24c1f8dfe --- /dev/null +++ b/include/mbgl/shaders/gl/drawable_fill_outline.hpp @@ -0,0 +1,84 @@ +// Generated code, do not modify this file! +// Generated on 2023-05-18T18:41:48.652Z by timsylvester using shaders/generate_shader_code.js + +#pragma once +#include + +namespace mbgl { +namespace shaders { + +template <> +struct ShaderSource { + static constexpr const char* name = "FillOutlineShader"; + static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos; + +uniform mat4 u_matrix; +uniform vec2 u_world; + +out vec2 v_pos; + +#ifndef HAS_UNIFORM_u_outline_color +uniform lowp float u_outline_color_t; +layout (location = 1) in highp vec4 a_outline_color; +out highp vec4 outline_color; +#else +uniform highp vec4 u_outline_color; +#endif +#ifndef HAS_UNIFORM_u_opacity +uniform lowp float u_opacity_t; +layout (location = 2) in lowp vec2 a_opacity; +out lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +void main() { + #ifndef HAS_UNIFORM_u_outline_color +outline_color = unpack_mix_color(a_outline_color, u_outline_color_t); +#else +highp vec4 outline_color = u_outline_color; +#endif + #ifndef HAS_UNIFORM_u_opacity +opacity = unpack_mix_vec2(a_opacity, u_opacity_t); +#else +lowp float opacity = u_opacity; +#endif + + gl_Position = u_matrix * vec4(a_pos, 0, 1); + v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world; +} +)"; + static constexpr const char* fragment = R"(in vec2 v_pos; + +#ifndef HAS_UNIFORM_u_outline_color +in highp vec4 outline_color; +#else +uniform highp vec4 u_outline_color; +#endif +#ifndef HAS_UNIFORM_u_opacity +in lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + +void main() { + #ifdef HAS_UNIFORM_u_outline_color +highp vec4 outline_color = u_outline_color; +#endif + #ifdef HAS_UNIFORM_u_opacity +lowp float opacity = u_opacity; +#endif + + float dist = length(v_pos - gl_FragCoord.xy); + float alpha = 1.0 - smoothstep(0.0, 1.0, dist); + fragColor = outline_color * (alpha * opacity); + +#ifdef OVERDRAW_INSPECTOR + fragColor = vec4(1.0); +#endif +} +)"; +}; + +} // namespace shaders +} // namespace mbgl diff --git a/include/mbgl/shaders/shader_manifest.hpp b/include/mbgl/shaders/shader_manifest.hpp index 92656186c..2baf4803f 100644 --- a/include/mbgl/shaders/shader_manifest.hpp +++ b/include/mbgl/shaders/shader_manifest.hpp @@ -7,6 +7,7 @@ #ifdef MBGL_RENDER_BACKEND_OPENGL #include #include +#include #include #include #include diff --git a/include/mbgl/shaders/shader_source.hpp b/include/mbgl/shaders/shader_source.hpp index fa874c895..4b3e00efd 100644 --- a/include/mbgl/shaders/shader_source.hpp +++ b/include/mbgl/shaders/shader_source.hpp @@ -13,6 +13,7 @@ enum class BuiltIn { None, BackgroundShader, FillShader, + FillOutlineShader, Prelude, BackgroundProgram, BackgroundPatternProgram, diff --git a/shaders/drawable.fill_outline.fragment.glsl b/shaders/drawable.fill_outline.fragment.glsl new file mode 100644 index 000000000..f13b94eda --- /dev/null +++ b/shaders/drawable.fill_outline.fragment.glsl @@ -0,0 +1,17 @@ +in vec2 v_pos; + +#pragma mapbox: define highp vec4 outline_color +#pragma mapbox: define lowp float opacity + +void main() { + #pragma mapbox: initialize highp vec4 outline_color + #pragma mapbox: initialize lowp float opacity + + float dist = length(v_pos - gl_FragCoord.xy); + float alpha = 1.0 - smoothstep(0.0, 1.0, dist); + fragColor = outline_color * (alpha * opacity); + +#ifdef OVERDRAW_INSPECTOR + fragColor = vec4(1.0); +#endif +} diff --git a/shaders/drawable.fill_outline.vertex.glsl b/shaders/drawable.fill_outline.vertex.glsl new file mode 100644 index 000000000..dea871d58 --- /dev/null +++ b/shaders/drawable.fill_outline.vertex.glsl @@ -0,0 +1,17 @@ +layout (location = 0) in vec2 a_pos; + +uniform mat4 u_matrix; +uniform vec2 u_world; + +out vec2 v_pos; + +#pragma mapbox: define highp vec4 outline_color +#pragma mapbox: define lowp float opacity + +void main() { + #pragma mapbox: initialize highp vec4 outline_color + #pragma mapbox: initialize lowp float opacity + + gl_Position = u_matrix * vec4(a_pos, 0, 1); + v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world; +} diff --git a/shaders/manifest.json b/shaders/manifest.json index a0099e144..4bf774136 100644 --- a/shaders/manifest.json +++ b/shaders/manifest.json @@ -13,6 +13,13 @@ "glsl_frag": "drawable.fill.fragment.glsl", "uses_ubos": false }, + { + "name": "FillOutlineShader", + "header": "drawable_fill_outline", + "glsl_vert": "drawable.fill_outline.vertex.glsl", + "glsl_frag": "drawable.fill_outline.fragment.glsl", + "uses_ubos": false + }, { "name": "Prelude", diff --git a/src/mbgl/gfx/drawable_builder.cpp b/src/mbgl/gfx/drawable_builder.cpp index 7ec2c8212..22a78765d 100644 --- a/src/mbgl/gfx/drawable_builder.cpp +++ b/src/mbgl/gfx/drawable_builder.cpp @@ -1,6 +1,8 @@ #include + #include #include +#include namespace mbgl { namespace gfx { @@ -42,8 +44,18 @@ void DrawableBuilder::flush() { if (auto drawAttrs = getVertexAttributes().clone()) { vertexAttrs.observeAttributes([&](const std::string& iName, const VertexAttribute& iAttr) { if (auto& drawAttr = drawAttrs->getOrAdd(iName)) { - for (std::size_t i = 0; i < impl->vertices.elements(); ++i) { - drawAttr->setVariant(i, iAttr.get(0)); + if (iAttr.getCount() == 1) { + // Apply the value to all vertexes + for (std::size_t i = 0; i < impl->vertices.elements(); ++i) { + drawAttr->setVariant(i, iAttr.get(0)); + } + } else if (iAttr.getCount() == impl->vertices.elements()) { + for (std::size_t i = 0; i < impl->vertices.elements(); ++i) { + drawAttr->setVariant(i, iAttr.get(i)); + } + } else { + // throw? + Log::Warning(Event::General, "Invalid attribute count"); } } }); @@ -85,7 +97,7 @@ void DrawableBuilder::addTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1 impl->vertices.emplace_back(Impl::VT({{{x0, y0}}})); impl->vertices.emplace_back(Impl::VT({{{x1, y1}}})); impl->vertices.emplace_back(Impl::VT({{{x2, y2}}})); - impl->indexes.emplace_back(n, n + 1, n + 2); + impl->triangleIndexes.emplace_back(n, n + 1, n + 2); if (colorMode == ColorMode::PerVertex) { impl->colors.insert(impl->colors.end(), 3, impl->currentColor); } @@ -94,7 +106,7 @@ void DrawableBuilder::addTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1 void DrawableBuilder::appendTriangle(int16_t x0, int16_t y0) { const auto n = (uint16_t)impl->vertices.elements(); impl->vertices.emplace_back(Impl::VT({{{x0, y0}}})); - impl->indexes.emplace_back(n - 2, n - 1, n); + impl->triangleIndexes.emplace_back(n - 2, n - 1, n); if (colorMode == ColorMode::PerVertex) { impl->colors.emplace_back(impl->currentColor); } @@ -113,6 +125,44 @@ void DrawableBuilder::setVertexAttributes(VertexAttributeArray&& attrs) { vertexAttrs = attrs; } +std::size_t DrawableBuilder::addVertices(const std::vector>& vertices, + std::size_t vertexOffset, + std::size_t vertexLength) { + const auto baseIndex = impl->vertices.elements(); + std::for_each(std::next(vertices.begin(), vertexOffset), + std::next(vertices.begin(), vertexOffset + vertexLength), + [&](const std::array& x) { impl->vertices.emplace_back(Impl::VT({{x}})); }); + if (colorMode == ColorMode::PerVertex) { + for (size_t i = 0; i < vertexLength; ++i) { + impl->colors.emplace_back(impl->currentColor); + } + } + return baseIndex; +} + +void DrawableBuilder::addLines(const std::vector& indexes, + std::size_t indexOffset, + std::size_t indexLength, + std::size_t baseIndex) { + for (auto i = std::next(indexes.begin(), indexOffset); + i != std::next(indexes.begin(), indexOffset + indexLength);) { + impl->lineIndexes.emplace_back(static_cast(*i++ + baseIndex), + static_cast(*i++ + baseIndex)); + } +} + +void DrawableBuilder::addTriangles(const std::vector& indexes, + std::size_t indexOffset, + std::size_t indexLength, + std::size_t baseIndex) { + for (auto i = std::next(indexes.begin(), indexOffset); + i != std::next(indexes.begin(), indexOffset + indexLength);) { + impl->triangleIndexes.emplace_back(static_cast(*i++ + baseIndex), + static_cast(*i++ + baseIndex), + static_cast(*i++ + baseIndex)); + } +} + void DrawableBuilder::addTriangles(const std::vector>& vertices, std::size_t vertexOffset, std::size_t vertexLength, @@ -127,21 +177,8 @@ void DrawableBuilder::addTriangles(const std::vector>& ve // std::next(indexes.begin(), indexOffset), // std::next(indexes.begin(), indexOffset + indexLength)); - const auto baseIndex = impl->vertices.elements(); - std::for_each(std::next(vertices.begin(), vertexOffset), - std::next(vertices.begin(), vertexOffset + vertexLength), - [&](const std::array& x) { impl->vertices.emplace_back(Impl::VT({{x}})); }); - for (auto i = std::next(indexes.begin(), indexOffset); - i != std::next(indexes.begin(), indexOffset + indexLength);) { - impl->indexes.emplace_back(static_cast(*i++ + baseIndex), - static_cast(*i++ + baseIndex), - static_cast(*i++ + baseIndex)); - } - if (colorMode == ColorMode::PerVertex) { - for (size_t i = 0; i < vertexLength; ++i) { - impl->colors.emplace_back(impl->currentColor); - } - } + const auto baseIndex = addVertices(vertices, vertexOffset, vertexLength); + addTriangles(indexes, indexOffset, indexLength, baseIndex); } } // namespace gfx diff --git a/src/mbgl/gfx/drawable_builder_impl.hpp b/src/mbgl/gfx/drawable_builder_impl.hpp index 47a8c5bb9..3229b5d4c 100644 --- a/src/mbgl/gfx/drawable_builder_impl.hpp +++ b/src/mbgl/gfx/drawable_builder_impl.hpp @@ -12,8 +12,8 @@ namespace gfx { struct DrawableBuilder::Impl { using VT = gfx::detail::VertexType>; gfx::VertexVector vertices; - gfx::IndexVector indexes; - SegmentVector> segments; + gfx::IndexVector triangleIndexes; + gfx::IndexVector lineIndexes; Color currentColor = Color::white(); std::vector colors; }; diff --git a/src/mbgl/gfx/vertex_vector.hpp b/src/mbgl/gfx/vertex_vector.hpp index fdda3c750..10c1afd9e 100644 --- a/src/mbgl/gfx/vertex_vector.hpp +++ b/src/mbgl/gfx/vertex_vector.hpp @@ -22,6 +22,10 @@ public: assert(n < v.size()); return v.at(n); } + const Vertex& at(std::size_t n) const { + assert(n < v.size()); + return v.at(n); + } std::size_t elements() const { return v.size(); } diff --git a/src/mbgl/gl/drawable_gl.cpp b/src/mbgl/gl/drawable_gl.cpp index b6a7e57a4..b630d6a94 100644 --- a/src/mbgl/gl/drawable_gl.cpp +++ b/src/mbgl/gl/drawable_gl.cpp @@ -23,16 +23,20 @@ void DrawableGL::draw(const PaintParameters& parameters) const { unbindUniformBuffers(); } -void DrawableGL::setIndexData(std::vector indexes, - const std::size_t indexOffset, - const std::size_t indexLength) { - impl->indexes = std::move(indexes); - impl->indexOffset = indexOffset; - impl->indexLength = indexLength; +void DrawableGL::setLineIndexData(std::vector indexes) { + impl->lineIndexes = std::move(indexes); } -std::vector& DrawableGL::getIndexData() const { - return impl->indexes; +void DrawableGL::setTriangleIndexData(std::vector indexes) { + impl->triangleIndexes = std::move(indexes); +} + +std::vector& DrawableGL::getLineIndexData() const { + return impl->lineIndexes; +} + +std::vector& DrawableGL::getTriangleIndexData() const { + return impl->triangleIndexes; } const gl::VertexArray& DrawableGL::getVertexArray() const { @@ -67,7 +71,6 @@ void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_, gfx::IndexBuffer&& indexBuffer_) { impl->vertexArray = std::move(vertexArray_); impl->attributeBuffer = std::move(attributeBuffer_); - impl->attributeOffset = 0; impl->indexBuffer = std::move(indexBuffer_); } diff --git a/src/mbgl/gl/drawable_gl_builder.cpp b/src/mbgl/gl/drawable_gl_builder.cpp index 0d740b489..e41225bfa 100644 --- a/src/mbgl/gl/drawable_gl_builder.cpp +++ b/src/mbgl/gl/drawable_gl_builder.cpp @@ -41,11 +41,11 @@ void DrawableGLBuilder::init() { } } - constexpr auto indexOffset = 0; - const auto indexCount = impl->indexes.elements(); - drawableGL.setIndexData(impl->indexes.vector(), indexOffset, indexCount); + drawableGL.setLineIndexData(impl->lineIndexes.vector()); + drawableGL.setTriangleIndexData(impl->triangleIndexes.vector()); - impl->indexes.clear(); + impl->lineIndexes.clear(); + impl->triangleIndexes.clear(); impl->vertices.clear(); impl->colors.clear(); } diff --git a/src/mbgl/gl/drawable_gl_impl.hpp b/src/mbgl/gl/drawable_gl_impl.hpp index c61cc7c67..f5745e1fa 100644 --- a/src/mbgl/gl/drawable_gl_impl.hpp +++ b/src/mbgl/gl/drawable_gl_impl.hpp @@ -29,18 +29,20 @@ public: void draw(const PaintParameters& parameters) const { auto& glContext = static_cast(parameters.context); - glContext.draw(drawMode, indexOffset, indexLength); + if (!triangleIndexes.empty()) { + glContext.draw(gfx::Triangles(), lineIndexes.size(), triangleIndexes.size()); + } + if (!lineIndexes.empty()) { + glContext.draw(gfx::Lines(1), 0, lineIndexes.size()); + } } - const gfx::Triangles drawMode; - // const gfx::DrawModeType type = gfx::DrawModeType::Triangles; - // ShaderID shaderId; // RenderbufferID renderTarget; std::vector textures; - // std::vector vertData; - std::vector indexes; + std::vector lineIndexes; + std::vector triangleIndexes; VertexAttributeArrayGL vertexAttributes; @@ -50,9 +52,6 @@ public: UniformBufferArrayGL uniformBuffers; - std::size_t indexOffset = 0; - std::size_t indexLength = 0; - std::size_t attributeOffset = 0; gfx::DepthMode depthMode = gfx::DepthMode::disabled(); gfx::StencilMode stencilMode; gfx::ColorMode colorMode; diff --git a/src/mbgl/gl/layer_group_gl.cpp b/src/mbgl/gl/layer_group_gl.cpp index 030cc7683..ec24dba6d 100644 --- a/src/mbgl/gl/layer_group_gl.cpp +++ b/src/mbgl/gl/layer_group_gl.cpp @@ -25,7 +25,9 @@ void TileLayerGroupGL::upload(gfx::Context& context, gfx::UploadPass& uploadPass const auto usage = gfx::BufferUsageType::StaticDraw; // Build index buffer - const auto& indexData = drawable.getIndexData(); + auto indexData = drawable.getLineIndexData(); + indexData.insert( + indexData.end(), drawable.getTriangleIndexData().begin(), drawable.getTriangleIndexData().end()); auto indexBuffer = gfx::IndexBuffer{ indexData.size(), uploadPass.createIndexBufferResource(indexData.data(), indexData.size() * sizeof(indexData[0]), usage)}; diff --git a/src/mbgl/gl/renderer_backend.cpp b/src/mbgl/gl/renderer_backend.cpp index 372dbabfc..a0e9471ab 100644 --- a/src/mbgl/gl/renderer_backend.cpp +++ b/src/mbgl/gl/renderer_backend.cpp @@ -93,8 +93,9 @@ void registerTypes(gfx::ShaderRegistry& registry, gl::Context& glContext, const } void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramParameters& programParameters) { - registerTypes( - shaders, static_cast(*context), programParameters); + registerTypes(shaders, static_cast(*context), programParameters); } } // namespace gl diff --git a/src/mbgl/renderer/layers/render_background_layer.hpp b/src/mbgl/renderer/layers/render_background_layer.hpp index 04e718145..1efd0b8ff 100644 --- a/src/mbgl/renderer/layers/render_background_layer.hpp +++ b/src/mbgl/renderer/layers/render_background_layer.hpp @@ -48,6 +48,8 @@ private: // Programs std::shared_ptr backgroundProgram; std::shared_ptr backgroundPatternProgram; + + gfx::ShaderProgramBasePtr shader; }; struct alignas(16) BackgroundLayerUBO { diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 5da921c9a..31819c589 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -64,6 +64,8 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) { } properties->renderPasses = mbgl::underlying_type(passes); evaluatedProperties = std::move(properties); + + evaluatedPropertiesChange = true; } bool RenderFillLayer::hasTransition() const { @@ -74,9 +76,15 @@ bool RenderFillLayer::hasCrossfade() const { return getCrossfade(evaluatedProperties).t != 1; } +static bool enableDefaultRender = false; + void RenderFillLayer::render(PaintParameters& parameters) { assert(renderTiles); + if (!enableDefaultRender) { + return; + } + if (!parameters.shaders.populate(fillProgram)) return; if (!parameters.shaders.populate(fillPatternProgram)) return; if (!parameters.shaders.populate(fillOutlineProgram)) return; @@ -277,11 +285,14 @@ void RenderFillLayer::update(const int32_t layerIndex, UniqueChangeRequestVec& changes) { std::unique_lock guard(mutex); - if (!shader) { - shader = context.getGenericShader(shaders, "FillShader"); + if (!fillShader) { + fillShader = context.getGenericShader(shaders, "FillShader"); + } + if (!outlineShader) { + outlineShader = context.getGenericShader(shaders, "FillOutlineShader"); } - if (!shader || !renderTiles || renderTiles->empty()) { + if (!fillShader || !outlineShader || !renderTiles || renderTiles->empty()) { if (tileLayerGroup) { stats.tileDrawablesRemoved += tileLayerGroup->getDrawableCount(); tileLayerGroup->clearDrawables(); @@ -309,6 +320,10 @@ void RenderFillLayer::update(const int32_t layerIndex, gfx::VertexAttributeArray vertexAttrs; for (const auto renderPass : {RenderPass::Opaque, RenderPass::Translucent}) { + if (!(mbgl::underlying_type(renderPass) & evaluatedProperties->renderPasses)) { + continue; + } + tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) { // Has this tile dropped out of the cover set? const auto tileID = drawable->getTileID(); @@ -342,25 +357,48 @@ void RenderFillLayer::update(const int32_t layerIndex, auto& bucket = static_cast(*renderData->bucket); const auto& evaluated = getEvaluated(renderData->layerProperties); const auto evalColor = evaluated.get().constantOr(Color()); - const auto fillOpacity = evaluated.get().constantOr(1); + const auto fillOpacity = evaluated.get().constantOr(0); const auto fillColor = evalColor * (fillOpacity > 0.0f ? fillOpacity : 1.0f); + const auto fillAA = evaluated.get(); const auto fillRenderPass = (fillColor.a >= 1.0f /* && parameters.currentLayer >= parameters.opaquePassCutoff*/) ? RenderPass::Opaque : RenderPass::Translucent; - if (fillRenderPass != renderPass || fillColor.a <= 0.0f) { + if (fillRenderPass != renderPass) { removeTile(); continue; } vertexAttrs.clear(); - if (auto& attr = vertexAttrs.getOrAdd("a_color")) { - attr->set(0, gfx::Drawable::colorAttrRGBA(evalColor)); + + const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + + if (auto& p1 = paintPropertyBinders.get()) { + const auto count = p1->getVertexCount(); + // check that vertexVector.elements() == sum(segments.vertexLength) + if (auto& attr = vertexAttrs.getOrAdd("a_color")) { + for (std::size_t i = 0; i < count; ++i) { + const auto& packed = + static_cast>*>( + p1->getVertexValue(i)) + ->a1; + attr->set(i, {packed[0], packed[1], packed[0], packed[1]}); + } + } } - if (auto& attr = vertexAttrs.getOrAdd("a_opacity")) { - attr->set(0, {fillOpacity, fillOpacity}); + if (auto& p1 = paintPropertyBinders.get()) { + const auto count = p1->getVertexCount(); + if (auto& attr = vertexAttrs.getOrAdd("a_opacity")) { + for (std::size_t i = 0; i < count; ++i) { + const auto& opacity = + static_cast>*>( + p1->getVertexValue(i)) + ->a1; + attr->set(i, {opacity[0], opacity[0]}); + } + } } if (evaluatedPropertiesChange) { @@ -378,7 +416,7 @@ void RenderFillLayer::update(const int32_t layerIndex, if (!builder) { builder = context.createDrawableBuilder("fill"); - builder->setShader(shader); + builder->setShader(fillShader); builder->addTweaker(context.createDrawableTweaker()); builder->setColorMode(gfx::DrawableBuilder::ColorMode::None); builder->setDepthType(gfx::DepthMaskType::ReadWrite); @@ -396,15 +434,18 @@ void RenderFillLayer::update(const int32_t layerIndex, std::vector> rawVerts(verts.size()); std::transform(verts.begin(), verts.end(), rawVerts.begin(), [](const auto& x) { return x.a1; }); + builder->addVertices(rawVerts, 0, rawVerts.size()); + for (const auto& seg : bucket.triangleSegments) { - builder->addTriangles(rawVerts, - seg.vertexOffset, - seg.vertexLength, - bucket.triangles.vector(), - seg.indexOffset, - seg.indexLength); + builder->addTriangles(bucket.triangles.vector(), seg.indexOffset, seg.indexLength); } + if (fillAA) { + // TODO: Different drawable? Multiple concurrent builders? + for (const auto& seg : bucket.lineSegments) { + builder->addLines(bucket.lines.vector(), seg.indexOffset, seg.indexLength); + } + } // evaluated.get(), // evaluated.get(), // parameters.stencilModeForClipping(tile.id), @@ -447,7 +488,7 @@ void RenderFillLayer::update(const int32_t layerIndex, tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable)); ++stats.tileDrawablesAdded; // Log::Warning(Event::General, "Adding drawable for " + util::toString(tileID) + " total " + - // std::to_string(stats.tileDrawablesAdded+1)); + // std::to_string(stats.tileDrawablesAdded+1)); } } } else { diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp index d7afa8470..39349cdb3 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_layer.hpp @@ -54,6 +54,9 @@ private: std::shared_ptr fillPatternProgram; std::shared_ptr fillOutlineProgram; std::shared_ptr fillOutlinePatternProgram; + + gfx::ShaderProgramBasePtr fillShader; + gfx::ShaderProgramBasePtr outlineShader; }; } // namespace mbgl diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index ffda59189..80d7af55a 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -128,6 +128,10 @@ public: virtual std::tuple...> uniformValue( const PossiblyEvaluatedType& currentValue) const = 0; + virtual std::size_t getVertexCount() const = 0; + virtual const /*std::tuple...>&*/ void* getVertexValue( + std::size_t index) const = 0; + static std::unique_ptr create(const PossiblyEvaluatedType& value, float zoom, T defaultValue); PaintPropertyStatistics statistics; @@ -163,6 +167,9 @@ public: return std::tuple{currentValue.constantOr(constant)}; } + std::size_t getVertexCount() const override { return 1; } + const /*std::tuple>&*/ void* getVertexValue(std::size_t) const override { return &constant; } + private: T constant; }; @@ -208,6 +215,11 @@ public: return constantPatternPositions; } + std::size_t getVertexCount() const override { return 0; } + const /*std::tuple>&*/ void* getVertexValue(std::size_t) const override { + return nullptr; // ? + } + private: Faded constant; std::tuple, std::array> constantPatternPositions; @@ -306,6 +318,11 @@ public: } } + std::size_t getVertexCount() const override { return vertexVector.elements(); } + const /*std::tuple>&*/ void* getVertexValue(std::size_t index) const override { + return &vertexVector.at(index); + } + private: style::PropertyExpression expression; T defaultValue; @@ -425,6 +442,11 @@ public: } } + std::size_t getVertexCount() const override { return vertexVector.elements(); } + const /*std::tuple>&*/ void* getVertexValue(std::size_t index) const override { + return &vertexVector.at(index); + } + private: style::PropertyExpression expression; T defaultValue; @@ -535,6 +557,9 @@ public: return {}; } + std::size_t getVertexCount() const override { return 0; } + const /*std::tuple>&*/ void* getVertexValue(std::size_t) const override { return nullptr; } + private: style::PropertyExpression expression; T defaultValue; @@ -698,6 +723,11 @@ public: binders.template get()->uniformValue(currentProperties.template get())...)); } + template + const auto& get() const { + return binders.template get

(); + } + template const auto& statistics() const { return binders.template get

()->statistics; diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index cbe8c4623..b28123908 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -169,7 +169,6 @@ protected: TileLayerGroupPtr tileLayerGroup; std::mutex mutex; - gfx::ShaderProgramBasePtr shader; bool evaluatedPropertiesChange = false; gfx::UniformBufferPtr uniformBuffer = nullptr;