diff --git a/include/mbgl/renderer/layer_tweaker.hpp b/include/mbgl/renderer/layer_tweaker.hpp index 518b7276b..5613d98b5 100644 --- a/include/mbgl/renderer/layer_tweaker.hpp +++ b/include/mbgl/renderer/layer_tweaker.hpp @@ -6,6 +6,10 @@ #include namespace mbgl { +namespace gfx { +class UniformBuffer; +using UniformBufferPtr = std::shared_ptr; +} // namespace gfx namespace style { class LayerProperties; enum class TranslateAnchorType : bool; diff --git a/include/mbgl/shaders/gl/drawable_fill.hpp b/include/mbgl/shaders/gl/drawable_fill.hpp index 927feb5be..b65c3fde3 100644 --- a/include/mbgl/shaders/gl/drawable_fill.hpp +++ b/include/mbgl/shaders/gl/drawable_fill.hpp @@ -8,25 +8,33 @@ namespace shaders { template <> struct ShaderSource { static constexpr const char* name = "FillShader"; - static constexpr const char* vertex = R"(layout (std140) uniform FillDrawableUBO { + static constexpr const char* vertex = R"(layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; +layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; highp vec2 u_world; highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; @@ -57,25 +65,33 @@ lowp float opacity = u_opacity; gl_Position = u_matrix * vec4(a_pos, 0, 1); } )"; - static constexpr const char* fragment = R"(layout (std140) uniform FillDrawableUBO { + static constexpr const char* fragment = R"(layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; +layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; highp vec2 u_world; highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/include/mbgl/shaders/gl/drawable_fill_outline.hpp b/include/mbgl/shaders/gl/drawable_fill_outline.hpp index 1b0399e51..0201e004a 100644 --- a/include/mbgl/shaders/gl/drawable_fill_outline.hpp +++ b/include/mbgl/shaders/gl/drawable_fill_outline.hpp @@ -8,25 +8,33 @@ namespace shaders { template <> struct ShaderSource { static constexpr const char* name = "FillOutlineShader"; - static constexpr const char* vertex = R"(layout (std140) uniform FillDrawableUBO { + static constexpr const char* vertex = R"(layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; +layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; highp vec2 u_world; highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; @@ -60,25 +68,33 @@ lowp float opacity = u_opacity; v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world; } )"; - static constexpr const char* fragment = R"(layout (std140) uniform FillDrawableUBO { + static constexpr const char* fragment = R"(layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; +layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; highp vec2 u_world; highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp b/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp index 114be8ea1..c1a50e9f1 100644 --- a/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp +++ b/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp @@ -8,25 +8,33 @@ namespace shaders { template <> struct ShaderSource { static constexpr const char* name = "FillOutlinePatternShader"; - static constexpr const char* vertex = R"(layout (std140) uniform FillDrawableUBO { + static constexpr const char* vertex = R"(layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; +layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; highp vec2 u_world; highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; @@ -88,25 +96,33 @@ mediump vec4 pattern_to = u_pattern_to; v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world; } )"; - static constexpr const char* fragment = R"(layout (std140) uniform FillDrawableUBO { + static constexpr const char* fragment = R"(layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; +layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; highp vec2 u_world; highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/include/mbgl/shaders/gl/drawable_fill_pattern.hpp b/include/mbgl/shaders/gl/drawable_fill_pattern.hpp index 4b8fa7e4c..f76aecd2c 100644 --- a/include/mbgl/shaders/gl/drawable_fill_pattern.hpp +++ b/include/mbgl/shaders/gl/drawable_fill_pattern.hpp @@ -8,25 +8,33 @@ namespace shaders { template <> struct ShaderSource { static constexpr const char* name = "FillPatternShader"; - static constexpr const char* vertex = R"(layout (std140) uniform FillDrawableUBO { + static constexpr const char* vertex = R"(layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; +layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; highp vec2 u_world; highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; @@ -84,25 +92,33 @@ mediump vec4 pattern_to = u_pattern_to; v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, toScale * display_size_b, tileZoomRatio, a_pos); } )"; - static constexpr const char* fragment = R"(layout (std140) uniform FillDrawableUBO { + static constexpr const char* fragment = R"(layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; +layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; highp vec2 u_world; highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; @@ -138,6 +154,10 @@ mediump vec4 pattern_to = u_pattern_to; vec2 pattern_tl_b = pattern_to.xy; vec2 pattern_br_b = pattern_to.zw; + if (u_texsize.x < 1.0 || u_texsize.y < 1.0) { + discard; + } + vec2 imagecoord = mod(v_pos_a, 1.0); vec2 pos = mix(pattern_tl_a / u_texsize, pattern_br_a / u_texsize, imagecoord); vec4 color1 = texture(u_image, pos); diff --git a/shaders/drawable.fill.fragment.glsl b/shaders/drawable.fill.fragment.glsl index 9928bcf69..1eeadc94a 100644 --- a/shaders/drawable.fill.fragment.glsl +++ b/shaders/drawable.fill.fragment.glsl @@ -1,3 +1,13 @@ +layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; @@ -5,18 +15,16 @@ layout (std140) uniform FillDrawableUBO { highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/shaders/drawable.fill.vertex.glsl b/shaders/drawable.fill.vertex.glsl index 287fa98ad..77e2cb16a 100644 --- a/shaders/drawable.fill.vertex.glsl +++ b/shaders/drawable.fill.vertex.glsl @@ -1,3 +1,13 @@ +layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; @@ -5,18 +15,16 @@ layout (std140) uniform FillDrawableUBO { highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/shaders/drawable.fill_outline.fragment.glsl b/shaders/drawable.fill_outline.fragment.glsl index 487135248..b2be2c4cf 100644 --- a/shaders/drawable.fill_outline.fragment.glsl +++ b/shaders/drawable.fill_outline.fragment.glsl @@ -1,3 +1,13 @@ +layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; @@ -5,18 +15,16 @@ layout (std140) uniform FillDrawableUBO { highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/shaders/drawable.fill_outline.vertex.glsl b/shaders/drawable.fill_outline.vertex.glsl index ca9be397a..41218a869 100644 --- a/shaders/drawable.fill_outline.vertex.glsl +++ b/shaders/drawable.fill_outline.vertex.glsl @@ -1,3 +1,13 @@ +layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; @@ -5,18 +15,16 @@ layout (std140) uniform FillDrawableUBO { highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/shaders/drawable.fill_outline_pattern.fragment.glsl b/shaders/drawable.fill_outline_pattern.fragment.glsl index 4fce1b650..8bbf277f8 100644 --- a/shaders/drawable.fill_outline_pattern.fragment.glsl +++ b/shaders/drawable.fill_outline_pattern.fragment.glsl @@ -1,3 +1,13 @@ +layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; @@ -5,18 +15,16 @@ layout (std140) uniform FillDrawableUBO { highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/shaders/drawable.fill_outline_pattern.vertex.glsl b/shaders/drawable.fill_outline_pattern.vertex.glsl index 819bf6bea..2b5dd2a1a 100644 --- a/shaders/drawable.fill_outline_pattern.vertex.glsl +++ b/shaders/drawable.fill_outline_pattern.vertex.glsl @@ -1,3 +1,13 @@ +layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; @@ -5,18 +15,16 @@ layout (std140) uniform FillDrawableUBO { highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/shaders/drawable.fill_pattern.fragment.glsl b/shaders/drawable.fill_pattern.fragment.glsl index ff7a90c48..1308b0845 100644 --- a/shaders/drawable.fill_pattern.fragment.glsl +++ b/shaders/drawable.fill_pattern.fragment.glsl @@ -1,3 +1,13 @@ +layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; @@ -5,18 +15,16 @@ layout (std140) uniform FillDrawableUBO { highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; @@ -40,6 +48,10 @@ void main() { vec2 pattern_tl_b = pattern_to.xy; vec2 pattern_br_b = pattern_to.zw; + if (u_texsize.x < 1.0 || u_texsize.y < 1.0) { + discard; + } + vec2 imagecoord = mod(v_pos_a, 1.0); vec2 pos = mix(pattern_tl_a / u_texsize, pattern_br_a / u_texsize, imagecoord); vec4 color1 = texture(u_image, pos); diff --git a/shaders/drawable.fill_pattern.vertex.glsl b/shaders/drawable.fill_pattern.vertex.glsl index 4e902b079..a6ab36193 100644 --- a/shaders/drawable.fill_pattern.vertex.glsl +++ b/shaders/drawable.fill_pattern.vertex.glsl @@ -1,3 +1,13 @@ +layout (std140) uniform FillInterpolateUBO { + highp float u_color_t; + highp float u_opacity_t; + highp float u_outline_color_t; + highp float u_pattern_from_t; + highp float u_pattern_to_t; + highp float u_fade; + highp float u_padding_interp1; + highp float u_padding_interp2; +}; layout (std140) uniform FillDrawableUBO { highp mat4 u_matrix; highp vec4 u_scale; @@ -5,18 +15,16 @@ layout (std140) uniform FillDrawableUBO { highp vec2 u_pixel_coord_upper; highp vec2 u_pixel_coord_lower; highp vec2 u_texsize; - highp float u_fade; - - highp float u_color_t; - highp float u_opacity_t; - highp float u_outline_color_t; - highp float u_pattern_from_t; - highp float u_pattern_to_t; - - highp vec2 u_color; - highp vec2 u_opacity; - highp vec2 u_outline_color_pad; +}; +layout (std140) uniform FillDrawablePropsUBO { + highp vec4 u_color; highp vec4 u_outline_color; + highp float u_opacity; + highp float padding_props1; + highp float padding_props2; + highp float padding_props3; +}; +layout (std140) uniform FillDrawableTilePropsUBO { highp vec4 u_pattern_from; highp vec4 u_pattern_to; }; diff --git a/src/mbgl/gl/drawable_gl.cpp b/src/mbgl/gl/drawable_gl.cpp index fe874d91a..b643ca98e 100644 --- a/src/mbgl/gl/drawable_gl.cpp +++ b/src/mbgl/gl/drawable_gl.cpp @@ -58,7 +58,7 @@ void DrawableGL::draw(const PaintParameters& parameters) const { for (const auto& seg : impl->segments) { const auto& glSeg = static_cast(*seg); const auto& mlSeg = glSeg.getSegment(); - if (glSeg.getVertexArray().isValid()) { + if (mlSeg.indexLength > 0 && glSeg.getVertexArray().isValid()) { glContext.bindVertexArray = glSeg.getVertexArray().getID(); glContext.draw(glSeg.getMode(), mlSeg.indexOffset, mlSeg.indexLength); } @@ -111,6 +111,7 @@ void DrawableGL::bindUniformBuffers() const { for (const auto& element : shaderGL.getUniformBlocks().getMap()) { const auto& uniformBuffer = getUniformBuffers().get(element.first); if (!uniformBuffer) { + assert(false); continue; } element.second->bindBuffer(*uniformBuffer); @@ -162,8 +163,14 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) { auto& glSeg = static_cast(*seg); const auto& mlSeg = glSeg.getSegment(); + if (mlSeg.indexLength == 0) { + continue; + } + for (auto& binding : bindings) { - binding->vertexOffset = static_cast(mlSeg.vertexOffset); + if (binding) { + binding->vertexOffset = static_cast(mlSeg.vertexOffset); + } } auto vertexArray = glContext.createVertexArray(); diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp index e66fc7851..13bdc5b81 100644 --- a/src/mbgl/gl/upload_pass.cpp +++ b/src/mbgl/gl/upload_pass.cpp @@ -178,7 +178,9 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings( return; } - bindings[defaultGL.getIndex()] = { + const auto index = static_cast(defaultGL.getIndex()); + bindings.resize(std::max(bindings.size(), index + 1)); + bindings[index] = { /*.attribute = */ {defaultAttr.getDataType(), offset}, /* vertexStride = */ static_cast(stride), /* vertexBufferResource = */ nullptr, // buffer details established later diff --git a/src/mbgl/renderer/layers/circle_layer_tweaker.hpp b/src/mbgl/renderer/layers/circle_layer_tweaker.hpp index 878f17a77..2016d299e 100644 --- a/src/mbgl/renderer/layers/circle_layer_tweaker.hpp +++ b/src/mbgl/renderer/layers/circle_layer_tweaker.hpp @@ -4,11 +4,6 @@ namespace mbgl { -namespace gfx { -class UniformBuffer; -using UniformBufferPtr = std::shared_ptr; -} // namespace gfx - /** Circle layer specific tweaker */ diff --git a/src/mbgl/renderer/layers/fill_layer_tweaker.cpp b/src/mbgl/renderer/layers/fill_layer_tweaker.cpp index 91b6c86c0..d1d0f9ac6 100644 --- a/src/mbgl/renderer/layers/fill_layer_tweaker.cpp +++ b/src/mbgl/renderer/layers/fill_layer_tweaker.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -17,33 +18,28 @@ namespace mbgl { using namespace style; struct alignas(16) FillDrawableUBO { - std::array matrix; + /* 0 */ std::array matrix; /* 64 */ std::array scale; - std::array world; + /* 80 */ std::array world; /* 88 */ std::array pixel_coord_upper; /* 96 */ std::array pixel_coord_lower; /* 104 */ std::array texsize; - /* 112 */ float fade; - - // Attribute interpolations (used without HAS_UNIFORM_u_*) - /* 116 */ float color_t; - /* 120 */ float opacity_t; - /* 124 */ float outline_color_t; - /* 128 */ float pattern_from_t; - /* 132 */ float pattern_to_t; - - // Uniform alternates for attributes (used with HAS_UNIFORM_u_*) - /* 136 */ std::array color; - /* 144 */ std::array opacity; - /* 152 */ std::array outline_color_pad; - /* 160 */ std::array outline_color; - /* 176 */ std::array pattern_from; - /* 208 */ std::array pattern_to; - - /* */ // std::array padding; - /* 208 */ + /* 112 */ }; -static_assert(sizeof(FillDrawableUBO) == 208); +static_assert(sizeof(FillDrawableUBO) == 112); + +/// Evaluated properties that do not depend on the tile +struct alignas(16) FillDrawablePropsUBO { + /* 0 */ Color color; + /* 16 */ Color outline_color; + /* 32 */ float opacity; + /* 36 */ std::array padding; + /* 48 */ +}; +static_assert(sizeof(FillDrawablePropsUBO) == 48); + +static constexpr std::string_view FillDrawableUBOName = "FillDrawableUBO"; +static constexpr std::string_view FillDrawablePropsUBOName = "FillDrawablePropsUBO"; void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const RenderTree& renderTree, @@ -61,50 +57,25 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str()); #endif + if (!propsBuffer) { + const FillDrawablePropsUBO paramsUBO = { + /* .color = */ evaluated.get().constantOr(FillColor::defaultValue()), + /* .outline_color = */ evaluated.get().constantOr(FillOutlineColor::defaultValue()), + /* .opacity = */ evaluated.get().constantOr(FillOpacity::defaultValue()), + /* .padding = */ {0}, + }; + propsBuffer = parameters.context.createUniformBuffer(¶msUBO, sizeof(paramsUBO)); + } + layerGroup.observeDrawables([&](gfx::Drawable& drawable) { + drawable.mutableUniformBuffers().addOrReplace(FillDrawablePropsUBOName, propsBuffer); + if (!drawable.getTileID()) { return; } - /*mat4 matrix = drawable.getMatrix(); - if (drawable.getTileID()) { - const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); - const auto tileMat = parameters.matrixForTile(tileID); - matrix::multiply(matrix, drawable.getMatrix(), tileMat); - matrix = tileMat; - } - - const auto renderableSize = parameters.backend.getDefaultRenderable().getSize(); - - gfx::DrawableUBO drawableUBO; - drawableUBO.matrix = util::cast(matrix); - drawableUBO.world = {(float)renderableSize.width, (float)renderableSize.height}; - auto uniformBuffer = context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO)); - drawable.mutableUniformBuffers().addOrReplace("DrawableUBO", uniformBuffer);*/ const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); - const auto& colorProperty = evaluated.get(); - const auto color = (colorProperty.isConstant() && colorProperty.constant()) ? *colorProperty.constant() - : Color(0.0f, 0.0f, 0.0f, 0.0f); - - const auto& outlineColorProperty = evaluated.get(); - const auto outlineColor = (outlineColorProperty.isConstant() && outlineColorProperty.constant()) - ? *outlineColorProperty.constant() - : Color(0.0f, 0.0f, 0.0f, 0.0f); - - const auto& opacityProperty = evaluated.get(); - const auto opacity = (opacityProperty.isConstant() && opacityProperty.constant()) ? *opacityProperty.constant() - : 1.0f; - - const auto& fillPatternProperty = evaluated.get(); - if (fillPatternProperty.isConstant() && fillPatternProperty.constant()) { - Faded pattern = *fillPatternProperty.constant(); - const auto& patternFrom = pattern.from; - const auto& patternTo = pattern.to; - [[maybe_unused]] const auto& idFrom = patternFrom.id(); - [[maybe_unused]] const auto& idTo = patternTo.id(); - } - const auto& translation = evaluated.get(); const auto anchor = evaluated.get(); constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix @@ -114,7 +85,7 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, // from FillPatternProgram::layoutUniformValues const auto renderableSize = parameters.backend.getDefaultRenderable().getSize(); const auto intZoom = parameters.state.getIntegerZoom(); - const auto tileRatio = 1 / tileID.pixelsToTileUnits(1, intZoom); + const auto tileRatio = 1.0f / tileID.pixelsToTileUnits(1.0f, intZoom); const int32_t tileSizeAtNearestZoom = static_cast( util::tileSize_D * parameters.state.zoomScale(intZoom - tileID.canonical.z)); const int32_t pixelX = static_cast( @@ -123,10 +94,20 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; const auto pixelRatio = parameters.pixelRatio; - const auto& textures = drawable.getTextures(); - const auto hasTex = !textures.empty() && textures[0].texture; - const Size textureSize = hasTex ? textures[0].texture->getSize() : Size(0, 0); - + Size textureSize = {0, 0}; + if (const auto shader = drawable.getShader()) { + if (const auto index = shader->getSamplerLocation("u_image")) { + const auto& textures = drawable.getTextures(); + const auto src = drawable.getTextureSource(*index); + gfx::Texture2DPtr tex = src ? src() : nullptr; + if (!tex && textures.size() > *index) { + tex = textures[*index].texture; + } + if (tex) { + textureSize = tex->getSize(); + } + } + } const FillDrawableUBO drawableUBO = { /*.matrix=*/util::cast(matrix), /*.scale=*/{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale}, @@ -134,26 +115,10 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, /*.pixel_coord_upper=*/{static_cast(pixelX >> 16), static_cast(pixelY >> 16)}, /*.pixel_coord_lower=*/{static_cast(pixelX & 0xFFFF), static_cast(pixelY & 0xFFFF)}, /*.texsize=*/{static_cast(textureSize.width), static_cast(textureSize.height)}, - /*.fade=*/crossfade.t, - /*.color_t=*/crossfade.t, - /*.opacity_t=*/crossfade.t, - /*.outline_color_t=*/crossfade.t, - /*.pattern_from_t=*/crossfade.t, - /*.pattern_to_t=*/crossfade.t, - /*.color=*/attributeValue(color), - /*.opacity=*/{opacity, opacity}, - /*.outline_color_pad=*/{0.0f}, - /*.outline_color=*/util::cast(outlineColor.toArray()), - /*.pattern_from=*/{0.0f}, - /*.pattern_to=*/{0.0f}, }; - if (auto& ubo = drawable.mutableUniformBuffers().get("FillDrawableUBO")) { - ubo->update(&drawableUBO, sizeof(drawableUBO)); - } else { - drawable.mutableUniformBuffers().addOrReplace( - "FillDrawableUBO", parameters.context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO))); - } + drawable.mutableUniformBuffers().createOrUpdate(FillDrawableUBOName, &drawableUBO, parameters.context); }); } + } // namespace mbgl diff --git a/src/mbgl/renderer/layers/fill_layer_tweaker.hpp b/src/mbgl/renderer/layers/fill_layer_tweaker.hpp index bd765df8f..6062f8f8a 100644 --- a/src/mbgl/renderer/layers/fill_layer_tweaker.hpp +++ b/src/mbgl/renderer/layers/fill_layer_tweaker.hpp @@ -2,6 +2,8 @@ #include +#include + namespace mbgl { /** @@ -16,6 +18,33 @@ public: ~FillLayerTweaker() override = default; void execute(LayerGroupBase&, const RenderTree&, const PaintParameters&) override; + + static constexpr std::string_view FillTilePropsUBOName = "FillDrawableTilePropsUBO"; + static constexpr std::string_view FillInterpolateUBOName = "FillInterpolateUBO"; + +private: + gfx::UniformBufferPtr propsBuffer; }; +/// Evaluated properties that depend on the tile +struct alignas(16) FillDrawableTilePropsUBO { + /* 0 */ std::array pattern_from; + /* 16 */ std::array pattern_to; + /* 32 */ +}; +static_assert(sizeof(FillDrawableTilePropsUBO) == 32); + +/// Attribute interpolations +struct alignas(16) FillInterpolateUBO { + /* 0 */ float color_t; + /* 4 */ float opacity_t; + /* 8 */ float outline_color_t; + /* 12 */ float pattern_from_t; + /* 16 */ float pattern_to_t; + /* 20 */ float fade; + /* 24 */ std::array padding; + /* 32 */ +}; +static_assert(sizeof(FillInterpolateUBO) == 32); + } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_circle_layer.hpp b/src/mbgl/renderer/layers/render_circle_layer.hpp index da0bfb311..5c4d4874c 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.hpp +++ b/src/mbgl/renderer/layers/render_circle_layer.hpp @@ -8,13 +8,6 @@ namespace mbgl { class CircleProgram; -namespace gfx { -class ShaderGroup; -class UniformBuffer; -using ShaderGroupPtr = std::shared_ptr; -using UniformBufferPtr = std::shared_ptr; -} // namespace gfx - class RenderCircleLayer final : public RenderLayer { public: explicit RenderCircleLayer(Immutable); diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index bbb7da2b3..512088402 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,11 @@ using namespace style; namespace { +static constexpr std::string_view FillShaderName = "FillShader"; +static constexpr std::string_view FillOutlineShaderName = "FillOutlineShader"; +static constexpr std::string_view FillPatternShaderName = "FillPatternShader"; +static constexpr std::string_view FillOutlinePatternShaderName = "FillOutlinePatternShader"; + inline const FillLayer::Impl& impl_cast(const Immutable& impl) { assert(impl->getTypeInfo() == FillLayer::Impl::staticTypeInfo()); return static_cast(*impl); @@ -279,98 +285,9 @@ void RenderFillLayer::removeTile(RenderPass renderPass, const OverscaledTileID& stats.tileDrawablesRemoved += tileLayerGroup->removeDrawables(renderPass, tileID).size(); } -using FloatAttr = gfx::AttributeType; -using FloatPairAttr = gfx::AttributeType; -using FloatPair = FloatPairAttr::Value; -using UShortQuadAttr = gfx::AttributeType; -using UShortQuad = UShortQuadAttr::Value; -using FloatVertex = gfx::detail::VertexType; -using FloatPairVertex = gfx::detail::VertexType; -using UShortQuadVertex = gfx::detail::VertexType; -using FloatBinder = PaintPropertyBinder, FloatAttr>; -using FloatPairBinder = - PaintPropertyBinder, FloatPairAttr>; -using ColorBinder = PaintPropertyBinder, FloatPairAttr>; -using ImageBinder = PaintPropertyBinder>, - UShortQuadAttr, - UShortQuadAttr>; - -bool bindFloat(const FloatBinder& binder, gfx::VertexAttributeArray& attrs, std::string attributeName) { - const auto count = binder.getVertexCount(); - if (auto& attr = attrs.getOrAdd(std::move(attributeName))) { - for (std::size_t i = 0; i < count; ++i) { - const auto& value = std::get<0>(binder.getVertexValue(i)).a1; - attr->set(i, value); - } - return true; - } - return false; -} -bool bindFloat(const std::unique_ptr& binder, - gfx::VertexAttributeArray& attrs, - std::string attributeName) { - return binder && bindFloat(*binder, attrs, std::move(attributeName)); -} - -bool bindFloatPair(const FloatPairBinder& binder, gfx::VertexAttributeArray& attrs, std::string attributeName) { - const auto count = binder.getVertexCount(); - // check that vertexVector.elements() == sum(segments.vertexLength) - if (auto& attr = attrs.getOrAdd(std::move(attributeName))) { - for (std::size_t i = 0; i < count; ++i) { - const auto& value = std::get<0>(binder.getVertexValue(i)).a1; - attr->set(i, value); - } - return true; - } - return false; -} -bool bindFloatPair(const std::unique_ptr& binder, - gfx::VertexAttributeArray& attrs, - std::string attributeName) { - return binder && bindFloatPair(*binder, attrs, std::move(attributeName)); -} - -bool bindColor(const ColorBinder& binder, gfx::VertexAttributeArray& attrs, std::string attributeName) { - const auto count = binder.getVertexCount(); - // check that vertexVector.elements() == sum(segments.vertexLength) - if (auto& attr = attrs.getOrAdd(std::move(attributeName))) { - for (std::size_t i = 0; i < count; ++i) { - const auto& value = std::get<0>(binder.getVertexValue(i)).a1; - attr->set(i, value); - } - return true; - } - return false; -} -bool bindColor(const std::unique_ptr& binder, - gfx::VertexAttributeArray& attrs, - std::string attributeName) { - return binder && bindColor(*binder, attrs, std::move(attributeName)); -} - -bool bindImage(const ImageBinder& binder, gfx::VertexAttributeArray& attrs, std::string attributeName) { - const auto count = binder.getVertexCount(); - // check that vertexVector.elements() == sum(segments.vertexLength) - if (auto& attr = attrs.getOrAdd(std::move(attributeName))) { - for (std::size_t i = 0; i < count; ++i) { - const auto& value = std::get<0>(binder.getVertexValue(i)).a1; - attr->set(i, value); - } - return true; - } - return false; -} -bool bindImage(const std::unique_ptr& binder, - gfx::VertexAttributeArray& attrs, - std::string attributeName) { - return binder && bindImage(*binder, attrs, std::move(attributeName)); -} - void RenderFillLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, - const TransformState& /*state*/, + const TransformState& state, [[maybe_unused]] const RenderTree& renderTree, [[maybe_unused]] UniqueChangeRequestVec& changes) { std::unique_lock guard(mutex); @@ -391,17 +308,28 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, tileLayerGroup->setLayerTweaker(std::make_shared(evaluatedProperties)); } - if (!fillShader) { - fillShader = context.getGenericShader(shaders, "FillShader"); + const auto removeAll = [&]() { + if (tileLayerGroup) { + stats.tileDrawablesRemoved += tileLayerGroup->getDrawableCount(); + tileLayerGroup->clearDrawables(); + } + }; + + if (!fillShaderGroup) { + fillShaderGroup = shaders.getShaderGroup(std::string(FillShaderName)); } - if (!outlineShader) { - outlineShader = context.getGenericShader(shaders, "FillOutlineShader"); + if (!outlineShaderGroup) { + outlineShaderGroup = shaders.getShaderGroup(std::string(FillOutlineShaderName)); } - if (!patternShader) { - patternShader = context.getGenericShader(shaders, "FillPatternShader"); + if (!patternShaderGroup) { + patternShaderGroup = shaders.getShaderGroup(std::string(FillPatternShaderName)); } - if (!outlinePatternShader) { - outlinePatternShader = context.getGenericShader(shaders, "FillOutlinePatternShader"); + if (!outlinePatternShaderGroup) { + outlinePatternShaderGroup = shaders.getShaderGroup(std::string(FillOutlinePatternShaderName)); + } + if (!fillShaderGroup || !outlineShaderGroup || !patternShaderGroup || !outlinePatternShaderGroup) { + removeAll(); + return; } std::unordered_set newTileIDs(renderTiles->size()); @@ -420,15 +348,20 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, gfx::VertexAttributeArray patternVertexAttrs; gfx::VertexAttributeArray patternOutlineVertexAttrs; - constexpr auto samplerLocation = 0; const auto layerPrefix = getID() + "/"; const auto renderPass = static_cast(evaluatedProperties->renderPasses); - const auto finish = [&](gfx::DrawableBuilder& builder, const OverscaledTileID& tileID) { + const auto finish = [&](gfx::DrawableBuilder& builder, + const OverscaledTileID& tileID, + const FillInterpolateUBO& interpUBO, + const FillDrawableTilePropsUBO& tileUBO) { builder.flush(); for (auto& drawable : builder.clearDrawables()) { drawable->setTileID(tileID); + auto& uniforms = drawable->mutableUniformBuffers(); + uniforms.createOrUpdate(FillLayerTweaker::FillInterpolateUBOName, &interpUBO, context); + uniforms.createOrUpdate(FillLayerTweaker::FillTilePropsUBOName, &tileUBO, context); tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable)); ++stats.tileDrawablesAdded; } @@ -452,11 +385,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, for (const RenderTile& tile : *renderTiles) { const auto& tileID = tile.getOverscaledTileID(); - // If we already have drawables for this tile, skip. - if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) { - continue; - } - const LayerRenderData* renderData = getRenderDataForPass(tile, renderPass); if (!renderData) { removeTile(renderPass, tileID); @@ -464,9 +392,46 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, } auto& bucket = static_cast(*renderData->bucket); + const auto& binders = bucket.paintPropertyBinders.at(getID()); + const auto& evaluated = getEvaluated(renderData->layerProperties); const auto& crossfade = getCrossfade(renderData->layerProperties); + const auto& fillPatternValue = evaluated.get().constantOr(Faded{"", ""}); + const auto patternPosA = tile.getPattern(fillPatternValue.from.id()); + const auto patternPosB = tile.getPattern(fillPatternValue.to.id()); + binders.setPatternParameters(patternPosA, patternPosB, crossfade); + + const auto zoom = static_cast(state.getZoom()); + const FillInterpolateUBO interpolateUBO = { + /* .color_t = */ std::get<0>(binders.get()->interpolationFactor(zoom)), + /* .opacity_t = */ std::get<0>(binders.get()->interpolationFactor(zoom)), + /* .outline_color_t = */ std::get<0>(binders.get()->interpolationFactor(zoom)), + /* .pattern_from_t = */ std::get<0>(binders.get()->interpolationFactor(zoom)), + /* .pattern_to_t = */ std::get<0>(binders.get()->interpolationFactor(zoom)), + /* .fade = */ crossfade.t, + /* .padding = */ {0}, + }; + + // TODO: only update if properties re-evaluated? + const FillDrawableTilePropsUBO tileProps = { + /* pattern_from = */ patternPosA ? util::cast(patternPosA->tlbr()) : std::array{0}, + /* pattern_to = */ patternPosB ? util::cast(patternPosB->tlbr()) : std::array{0}, + }; + + // If we already have drawables for this tile, update them. + if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) { + // TODO: Share buffers + tileLayerGroup->observeDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) { + drawable.mutableUniformBuffers().createOrUpdate( + FillLayerTweaker::FillInterpolateUBOName, &interpolateUBO, context); + drawable.mutableUniformBuffers().createOrUpdate( + FillLayerTweaker::FillTilePropsUBOName, &tileProps, context); + }); + + continue; + } + std::vector> rawVerts; const auto buildVertices = [&]() { const std::vector>>::Vertex>& @@ -480,25 +445,29 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, fillVertexAttrs.clear(); outlineVertexAttrs.clear(); - const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + // `Fill*Program` all use `style::FillPaintProperties` + const auto fillUniformProps = + fillVertexAttrs.readDataDrivenPaintProperties( + binders, evaluated); + const auto outlineUniformProps = + outlineVertexAttrs.readDataDrivenPaintProperties( + binders, evaluated); if (unevaluated.get().isUndefined()) { // Fill will occur in opaque or translucent pass based on `opaquePassCutoff`. // Outline always occurs in translucent pass, defaults to fill color const auto doOutline = evaluated.get(); - bindColor(paintPropertyBinders.get(), fillVertexAttrs, "a_color"); - bindFloat(paintPropertyBinders.get(), fillVertexAttrs, "a_opacity"); - - if (doOutline) { - bindColor(paintPropertyBinders.get(), outlineVertexAttrs, "a_outline_color"); - bindFloat(paintPropertyBinders.get(), outlineVertexAttrs, "a_opacity"); - } + const auto fillShader = std::static_pointer_cast( + fillShaderGroup->getOrCreateShader(context, fillUniformProps)); + const auto outlineShader = doOutline + ? std::static_pointer_cast( + outlineShaderGroup->getOrCreateShader(context, outlineUniformProps)) + : nullptr; if (!fillBuilder && fillShader) { if (auto builder = context.createDrawableBuilder(layerPrefix + "fill")) { commonInit(*builder); - builder->setShader(fillShader); builder->setDepthType((renderPass == RenderPass::Opaque) ? gfx::DepthMaskType::ReadWrite : gfx::DepthMaskType::ReadOnly); builder->setSubLayerIndex(0); @@ -509,7 +478,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, if (doOutline && !outlineBuilder && outlineShader) { if (auto builder = context.createDrawableBuilder(layerPrefix + "fill-outline")) { commonInit(*builder); - builder->setShader(outlineShader); builder->setLineWidth(2.0f); builder->setDepthType(gfx::DepthMaskType::ReadOnly); builder->setSubLayerIndex(unevaluated.get().isUndefined() ? 2 : 0); @@ -520,21 +488,23 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, if (fillBuilder) { buildVertices(); + fillBuilder->setShader(fillShader); fillBuilder->setVertexAttributes(fillVertexAttrs); fillBuilder->addVertices(rawVerts, 0, rawVerts.size()); fillBuilder->setSegments(gfx::Triangles(), bucket.triangles.vector(), reinterpret_cast>&>(bucket.triangleSegments)); - finish(*fillBuilder, tileID); + finish(*fillBuilder, tileID, interpolateUBO, tileProps); } if (outlineBuilder) { buildVertices(); + outlineBuilder->setShader(outlineShader); outlineBuilder->setVertexAttributes(outlineVertexAttrs); outlineBuilder->addVertices(rawVerts, 0, rawVerts.size()); outlineBuilder->setSegments(gfx::Lines(2), bucket.lines.vector(), reinterpret_cast>&>(bucket.lineSegments)); - finish(*outlineBuilder, tileID); + finish(*outlineBuilder, tileID, interpolateUBO, tileProps); } } else { // FillPattern is defined if ((renderPass & RenderPass::Translucent) == 0) { @@ -543,53 +513,37 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, // Outline does not default to fill in the pattern case const auto doOutline = evaluated.get() && unevaluated.get().isUndefined(); - const auto& fillPatternValue = evaluated.get().constantOr(Faded{"", ""}); - const auto patternPosA = tile.getPattern(fillPatternValue.from.id()); - const auto patternPosB = tile.getPattern(fillPatternValue.to.id()); - paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade); - // if (samplerLocation < 0) curShader->getSamplerLocation("u_image"); + const auto fillShader = std::static_pointer_cast( + patternShaderGroup->getOrCreateShader(context, fillUniformProps)); + const auto outlineShader = doOutline ? std::static_pointer_cast( + outlinePatternShaderGroup->getOrCreateShader( + context, outlineUniformProps)) + : nullptr; - bindFloat(paintPropertyBinders.get(), fillVertexAttrs, "a_opacity"); - bindImage(paintPropertyBinders.get(), fillVertexAttrs, "a_pattern_from"); - bindImage(paintPropertyBinders.get(), fillVertexAttrs, "a_pattern_to"); - - if (doOutline) { - bindFloat(paintPropertyBinders.get(), outlineVertexAttrs, "a_opacity"); - bindImage(paintPropertyBinders.get(), outlineVertexAttrs, "a_pattern_from"); - bindImage(paintPropertyBinders.get(), outlineVertexAttrs, "a_pattern_to"); - } - - if (!patternBuilder && patternShader) { + if (!patternBuilder) { if (auto builder = context.createDrawableBuilder(layerPrefix + "fill-pattern")) { commonInit(*builder); - builder->setShader(patternShader); builder->setDepthType(gfx::DepthMaskType::ReadWrite); builder->setSubLayerIndex(1); builder->setRenderPass(RenderPass::Translucent); - if (const auto& atlases = tile.getAtlasTextures()) { - builder->setTextureSource(samplerLocation, [=]() { return atlases ? atlases->icon : nullptr; }); - } patternBuilder = std::move(builder); } } - if (doOutline && !outlinePatternBuilder && outlinePatternShader) { + if (doOutline && !outlinePatternBuilder) { if (auto builder = context.createDrawableBuilder(layerPrefix + "fill-outline-pattern")) { commonInit(*builder); - builder->setShader(outlinePatternShader); builder->setLineWidth(2.0f); builder->setDepthType(gfx::DepthMaskType::ReadOnly); builder->setSubLayerIndex(2); builder->setRenderPass(RenderPass::Translucent); - if (const auto& atlases = tile.getAtlasTextures()) { - builder->setTextureSource(samplerLocation, [=]() { return atlases ? atlases->icon : nullptr; }); - } outlinePatternBuilder = std::move(builder); } } if (patternBuilder) { buildVertices(); + patternBuilder->setShader(fillShader); patternBuilder->setRenderPass(renderPass); patternBuilder->setVertexAttributes(fillVertexAttrs); patternBuilder->addVertices(rawVerts, 0, rawVerts.size()); @@ -597,10 +551,18 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, gfx::Triangles(), bucket.triangles.vector(), reinterpret_cast>&>(bucket.triangleSegments)); - finish(*patternBuilder, tileID); + + if (const auto& atlases = tile.getAtlasTextures()) { + if (const auto samplerLocation = fillShader->getSamplerLocation("u_image")) { + patternBuilder->setTextureSource(*samplerLocation, [=]() { return atlases->icon; }); + } + } + + finish(*patternBuilder, tileID, interpolateUBO, tileProps); } if (outlinePatternBuilder) { buildVertices(); + outlinePatternBuilder->setShader(outlineShader); outlinePatternBuilder->setRenderPass(renderPass); outlinePatternBuilder->setVertexAttributes(outlineVertexAttrs); outlinePatternBuilder->addVertices(rawVerts, 0, rawVerts.size()); @@ -608,7 +570,14 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders, gfx::Lines(2), bucket.lines.vector(), reinterpret_cast>&>(bucket.lineSegments)); - finish(*outlinePatternBuilder, tileID); + + if (const auto& atlases = tile.getAtlasTextures()) { + if (const auto samplerLocation = outlineShader->getSamplerLocation("u_image")) { + outlinePatternBuilder->setTextureSource(*samplerLocation, [=]() { return atlases->icon; }); + } + } + + finish(*outlinePatternBuilder, tileID, interpolateUBO, tileProps); } } } diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp index 51c5a9a6b..69a176a1a 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_layer.hpp @@ -58,10 +58,10 @@ private: std::shared_ptr fillOutlineProgram; std::shared_ptr fillOutlinePatternProgram; - gfx::ShaderProgramBasePtr fillShader; - gfx::ShaderProgramBasePtr outlineShader; - gfx::ShaderProgramBasePtr patternShader; - gfx::ShaderProgramBasePtr outlinePatternShader; + gfx::ShaderGroupPtr fillShaderGroup; + gfx::ShaderGroupPtr outlineShaderGroup; + gfx::ShaderGroupPtr patternShaderGroup; + gfx::ShaderGroupPtr outlinePatternShaderGroup; }; } // namespace mbgl diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 5a7f32185..95080e505 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -34,7 +34,11 @@ using UniqueChangeRequestVec = std::vector; namespace gfx { class Context; +class ShaderGroup; class ShaderRegistry; +class UniformBuffer; +using ShaderGroupPtr = std::shared_ptr; +using UniformBufferPtr = std::shared_ptr; } // namespace gfx class LayerRenderData {