Drawable performance fixes (#1592)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Tim Sylvester <tim@wetdogweather.com>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include <mbgl/gfx/drawable_data.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
@@ -227,6 +228,12 @@ public:
|
||||
/// Set drawable data
|
||||
void setData(UniqueDrawableData&& value) { drawableData = std::move(value); }
|
||||
|
||||
/// Set drawable user-defined type
|
||||
void setType(std::size_t type_) { type = type_; }
|
||||
|
||||
/// Get drawable user-defined type
|
||||
size_t getType() const { return type; }
|
||||
|
||||
protected:
|
||||
bool enabled = true;
|
||||
bool enableColor = true;
|
||||
@@ -250,6 +257,8 @@ protected:
|
||||
|
||||
Textures textures;
|
||||
std::vector<DrawableTweakerPtr> tweakers;
|
||||
|
||||
std::size_t type = 0;
|
||||
};
|
||||
|
||||
using DrawablePtr = std::shared_ptr<Drawable>;
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
|
||||
protected:
|
||||
BufferID id = 0;
|
||||
uint32_t hash;
|
||||
};
|
||||
|
||||
/// Stores a collection of uniform buffers by name
|
||||
@@ -42,8 +43,7 @@ public:
|
||||
|
||||
private:
|
||||
std::unique_ptr<gfx::UniformBuffer> copy(const gfx::UniformBuffer& uniformBuffers) override {
|
||||
return std::unique_ptr<gfx::UniformBuffer>(
|
||||
new UniformBufferGL(static_cast<const UniformBufferGL&>(uniformBuffers)));
|
||||
return std::make_unique<UniformBufferGL>(static_cast<const UniformBufferGL&>(uniformBuffers));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,5 +15,7 @@ enum CompressionFormat {
|
||||
std::string compress(const std::string& raw, int windowBits = CompressionFormat::ZLIB);
|
||||
std::string decompress(const std::string& raw, int windowBits = CompressionFormat::DETECT);
|
||||
|
||||
std::uint32_t crc32(const void* raw, size_t size);
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -106,5 +106,20 @@ std::string decompress(const std::string &raw, int windowBits) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::uint32_t crc32(const void *raw, size_t size) {
|
||||
auto hash = ::crc32(0L, Z_NULL, 0);
|
||||
if (raw) {
|
||||
const auto *p = static_cast<const Bytef *>(raw);
|
||||
while (size > 0) {
|
||||
const auto blockSize = static_cast<uInt>(size);
|
||||
hash = ::crc32(hash, p, blockSize);
|
||||
p += blockSize;
|
||||
size -= blockSize;
|
||||
}
|
||||
}
|
||||
return static_cast<std::uint32_t>(hash);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -19,8 +19,13 @@ layout (std140) uniform SymbolDrawableUBO {
|
||||
highp float u_pitch;
|
||||
bool u_rotate_symbol;
|
||||
highp float u_aspect_ratio;
|
||||
highp vec2 u_pad1;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDynamicUBO {
|
||||
highp float u_fade_change;
|
||||
highp float u_pad2;
|
||||
highp float u_pad7;
|
||||
highp vec2 u_pad8;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDrawablePaintUBO {
|
||||
|
||||
@@ -15,8 +15,13 @@ layout (std140) uniform SymbolDrawableUBO {
|
||||
highp float u_pitch;
|
||||
bool u_rotate_symbol;
|
||||
highp float u_aspect_ratio;
|
||||
highp vec2 u_pad1;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDynamicUBO {
|
||||
highp float u_fade_change;
|
||||
highp float u_pad2;
|
||||
highp float u_pad7;
|
||||
highp vec2 u_pad8;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDrawablePaintUBO {
|
||||
|
||||
@@ -27,8 +27,13 @@ layout (std140) uniform SymbolDrawableUBO {
|
||||
highp float u_pitch;
|
||||
bool u_rotate_symbol;
|
||||
highp float u_aspect_ratio;
|
||||
highp vec2 u_pad1;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDynamicUBO {
|
||||
highp float u_fade_change;
|
||||
highp float u_pad2;
|
||||
highp float u_pad7;
|
||||
highp vec2 u_pad8;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDrawablePaintUBO {
|
||||
|
||||
@@ -18,8 +18,13 @@ layout (std140) uniform SymbolDrawableUBO {
|
||||
highp float u_pitch;
|
||||
bool u_rotate_symbol;
|
||||
highp float u_aspect_ratio;
|
||||
highp vec2 u_pad1;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDynamicUBO {
|
||||
highp float u_fade_change;
|
||||
highp float u_pad2;
|
||||
highp float u_pad7;
|
||||
highp vec2 u_pad8;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDrawablePaintUBO {
|
||||
|
||||
@@ -26,8 +26,13 @@ layout (std140) uniform SymbolDrawableUBO {
|
||||
highp float u_pitch;
|
||||
bool u_rotate_symbol;
|
||||
highp float u_aspect_ratio;
|
||||
highp vec2 u_pad1;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDynamicUBO {
|
||||
highp float u_fade_change;
|
||||
highp float u_pad2;
|
||||
highp float u_pad7;
|
||||
highp vec2 u_pad8;
|
||||
};
|
||||
|
||||
layout (std140) uniform SymbolDrawablePaintUBO {
|
||||
|
||||
@@ -80,10 +80,10 @@ void DrawableGL::setIndexData(gfx::IndexVectorBasePtr indexes, std::vector<Uniqu
|
||||
impl->segments = std::move(segments);
|
||||
}
|
||||
|
||||
void DrawableGL::setVertices(std::vector<uint8_t>&& data, std::size_t count, gfx::AttributeDataType type) {
|
||||
void DrawableGL::setVertices(std::vector<uint8_t>&& data, std::size_t count, gfx::AttributeDataType type_) {
|
||||
impl->vertexData = std::move(data);
|
||||
impl->vertexCount = count;
|
||||
impl->vertexType = type;
|
||||
impl->vertexType = type_;
|
||||
}
|
||||
|
||||
const gfx::VertexAttributeArray& DrawableGL::getVertexAttributes() const {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <mbgl/gl/uniform_buffer_gl.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/platform/gl_functions.hpp>
|
||||
#include <mbgl/util/compression.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <cassert>
|
||||
@@ -10,11 +11,12 @@ namespace gl {
|
||||
|
||||
using namespace platform;
|
||||
|
||||
UniformBufferGL::UniformBufferGL(const void* data, std::size_t size_)
|
||||
: UniformBuffer(size_) {
|
||||
UniformBufferGL::UniformBufferGL(const void* data_, std::size_t size_)
|
||||
: UniformBuffer(size_),
|
||||
hash(util::crc32(data_, size_)) {
|
||||
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, id));
|
||||
MBGL_CHECK_ERROR(glBufferData(GL_UNIFORM_BUFFER, size, data, GL_DYNAMIC_DRAW));
|
||||
MBGL_CHECK_ERROR(glBufferData(GL_UNIFORM_BUFFER, size, data_, GL_DYNAMIC_DRAW));
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, 0));
|
||||
}
|
||||
|
||||
@@ -25,8 +27,8 @@ UniformBufferGL::~UniformBufferGL() {
|
||||
}
|
||||
}
|
||||
|
||||
void UniformBufferGL::update(const void* data, std::size_t size_) {
|
||||
assert(size == size_);
|
||||
void UniformBufferGL::update(const void* data_, std::size_t size_) {
|
||||
assert(size == size_); // && size == data.size());
|
||||
if (size != size_) {
|
||||
Log::Error(
|
||||
Event::General,
|
||||
@@ -34,9 +36,13 @@ void UniformBufferGL::update(const void* data, std::size_t size_) {
|
||||
return;
|
||||
}
|
||||
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, id));
|
||||
MBGL_CHECK_ERROR(glBufferSubData(GL_UNIFORM_BUFFER, 0, size_, data));
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, 0));
|
||||
const uint32_t newHash = util::crc32(data_, size_);
|
||||
if (newHash != hash) {
|
||||
hash = newHash;
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, id));
|
||||
MBGL_CHECK_ERROR(glBufferSubData(GL_UNIFORM_BUFFER, 0, size_, data_));
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, 0));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
|
||||
@@ -154,6 +154,21 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
}
|
||||
return lineGradientPropertiesBuffer;
|
||||
};
|
||||
const auto getLinePatternPropsBuffer = [&]() {
|
||||
if (!linePatternPropertiesBuffer) {
|
||||
const LinePatternPropertiesUBO linePatternPropertiesUBO{
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
linePatternPropertiesBuffer = context.createUniformBuffer(&linePatternPropertiesUBO,
|
||||
sizeof(linePatternPropertiesUBO));
|
||||
}
|
||||
return linePatternPropertiesBuffer;
|
||||
};
|
||||
const auto getLineSDFPropsBuffer = [&]() {
|
||||
if (!lineSDFPropertiesBuffer) {
|
||||
const LineSDFPropertiesUBO lineSDFPropertiesUBO{
|
||||
@@ -182,115 +197,120 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
constexpr bool nearClipped = false;
|
||||
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
const auto& shaderUniforms = shader->getUniformBlocks();
|
||||
|
||||
const auto matrix = getTileMatrix(
|
||||
tileID, renderTree, parameters.state, translation, anchor, nearClipped, inViewportPixelUnits);
|
||||
|
||||
// simple line
|
||||
if (shaderUniforms.get(std::string(LineUBOName))) {
|
||||
// main UBO
|
||||
const LineUBO lineUBO{
|
||||
/*matrix = */ util::cast<float>(matrix),
|
||||
/*units_to_pixels = */ {1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio = */ parameters.pixelRatio};
|
||||
uniforms.createOrUpdate(LineUBOName, &lineUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.addOrReplace(LinePropertiesUBOName, getLinePropsBuffer());
|
||||
}
|
||||
// gradient line
|
||||
else if (shaderUniforms.get(std::string(LineGradientUBOName))) {
|
||||
// main UBO
|
||||
const LineGradientUBO lineGradientUBO{
|
||||
/*matrix = */ util::cast<float>(matrix),
|
||||
/*units_to_pixels = */ {1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio = */ parameters.pixelRatio};
|
||||
uniforms.createOrUpdate(LineGradientUBOName, &lineGradientUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.addOrReplace(LineGradientPropertiesUBOName, getLineGradientPropsBuffer());
|
||||
}
|
||||
// pattern line
|
||||
else if (shaderUniforms.get(std::string(LinePatternUBOName))) {
|
||||
// main UBO
|
||||
Size textureSize{0, 0};
|
||||
if (const auto index = shader->getSamplerLocation("u_image")) {
|
||||
if (const auto& texture = drawable.getTexture(index.value())) {
|
||||
textureSize = texture->getSize();
|
||||
}
|
||||
}
|
||||
const LinePatternUBO linePatternUBO{
|
||||
/*matrix =*/util::cast<float>(matrix),
|
||||
/*scale =*/
|
||||
{parameters.pixelRatio,
|
||||
1 / tileID.pixelsToTileUnits(1, parameters.state.getIntegerZoom()),
|
||||
crossfade.fromScale,
|
||||
crossfade.toScale},
|
||||
/*texsize =*/{static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
|
||||
/*units_to_pixels =*/{1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio =*/1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio =*/parameters.pixelRatio,
|
||||
/*fade =*/crossfade.t,
|
||||
0};
|
||||
uniforms.createOrUpdate(LinePatternUBOName, &linePatternUBO, context);
|
||||
|
||||
// properties UBO
|
||||
const LinePatternPropertiesUBO linePatternPropertiesUBO{
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
uniforms.createOrUpdate(LinePatternPropertiesUBOName, &linePatternPropertiesUBO, context);
|
||||
}
|
||||
// SDF line
|
||||
else if (shaderUniforms.get(std::string(LineSDFUBOName))) {
|
||||
if (const auto& data = drawable.getData()) {
|
||||
const gfx::LineDrawableData& lineData = static_cast<const gfx::LineDrawableData&>(*data);
|
||||
const auto& dashPatternTexture = parameters.lineAtlas.getDashPatternTexture(
|
||||
evaluated.get<LineDasharray>().from, evaluated.get<LineDasharray>().to, lineData.linePatternCap);
|
||||
|
||||
// texture
|
||||
if (const auto index = shader->getSamplerLocation("u_image")) {
|
||||
if (!drawable.getTexture(index.value())) {
|
||||
const auto& texture = dashPatternTexture.getTexture();
|
||||
drawable.setEnabled(!!texture);
|
||||
if (texture) {
|
||||
drawable.setTexture(texture, index.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
LineType type = static_cast<LineType>(drawable.getType());
|
||||
|
||||
switch (type) {
|
||||
case LineType::Simple: {
|
||||
// main UBO
|
||||
const LinePatternPos& posA = dashPatternTexture.getFrom();
|
||||
const LinePatternPos& posB = dashPatternTexture.getTo();
|
||||
const float widthA = posA.width * crossfade.fromScale;
|
||||
const float widthB = posB.width * crossfade.toScale;
|
||||
const LineSDFUBO lineSDFUBO{
|
||||
/* matrix = */ util::cast<float>(matrix),
|
||||
/* units_to_pixels = */
|
||||
{1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/* patternscale_a = */
|
||||
{1.0f / tileID.pixelsToTileUnits(widthA, parameters.state.getIntegerZoom()), -posA.height / 2.0f},
|
||||
/* patternscale_b = */
|
||||
{1.0f / tileID.pixelsToTileUnits(widthB, parameters.state.getIntegerZoom()), -posB.height / 2.0f},
|
||||
/* ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/* device_pixel_ratio = */ parameters.pixelRatio,
|
||||
/* tex_y_a = */ posA.y,
|
||||
/* tex_y_b = */ posB.y,
|
||||
/* sdfgamma = */ static_cast<float>(dashPatternTexture.getSize().width) /
|
||||
(std::min(widthA, widthB) * 256.0f * parameters.pixelRatio) / 2.0f,
|
||||
/* mix = */ crossfade.t};
|
||||
uniforms.createOrUpdate(LineSDFUBOName, &lineSDFUBO, context);
|
||||
const LineUBO lineUBO{
|
||||
/*matrix = */ util::cast<float>(matrix),
|
||||
/*units_to_pixels = */ {1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio = */ parameters.pixelRatio};
|
||||
uniforms.createOrUpdate(LineUBOName, &lineUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.addOrReplace(LineSDFPropertiesUBOName, getLineSDFPropsBuffer());
|
||||
}
|
||||
uniforms.addOrReplace(LinePropertiesUBOName, getLinePropsBuffer());
|
||||
} break;
|
||||
|
||||
case LineType::Gradient: {
|
||||
// main UBO
|
||||
const LineGradientUBO lineGradientUBO{
|
||||
/*matrix = */ util::cast<float>(matrix),
|
||||
/*units_to_pixels = */ {1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio = */ parameters.pixelRatio};
|
||||
uniforms.createOrUpdate(LineGradientUBOName, &lineGradientUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.addOrReplace(LineGradientPropertiesUBOName, getLineGradientPropsBuffer());
|
||||
} break;
|
||||
|
||||
case LineType::Pattern: {
|
||||
// main UBO
|
||||
Size textureSize{0, 0};
|
||||
if (const auto index = shader->getSamplerLocation("u_image")) {
|
||||
if (const auto& texture = drawable.getTexture(index.value())) {
|
||||
textureSize = texture->getSize();
|
||||
}
|
||||
}
|
||||
const LinePatternUBO linePatternUBO{
|
||||
/*matrix =*/util::cast<float>(matrix),
|
||||
/*scale =*/
|
||||
{parameters.pixelRatio,
|
||||
1 / tileID.pixelsToTileUnits(1, parameters.state.getIntegerZoom()),
|
||||
crossfade.fromScale,
|
||||
crossfade.toScale},
|
||||
/*texsize =*/{static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
|
||||
/*units_to_pixels =*/{1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio =*/1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio =*/parameters.pixelRatio,
|
||||
/*fade =*/crossfade.t,
|
||||
0};
|
||||
uniforms.createOrUpdate(LinePatternUBOName, &linePatternUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.addOrReplace(LinePatternPropertiesUBOName, getLinePatternPropsBuffer());
|
||||
} break;
|
||||
|
||||
case LineType::SDF: {
|
||||
if (const auto& data = drawable.getData()) {
|
||||
const gfx::LineDrawableData& lineData = static_cast<const gfx::LineDrawableData&>(*data);
|
||||
const auto& dashPatternTexture = parameters.lineAtlas.getDashPatternTexture(
|
||||
evaluated.get<LineDasharray>().from,
|
||||
evaluated.get<LineDasharray>().to,
|
||||
lineData.linePatternCap);
|
||||
|
||||
// texture
|
||||
if (const auto index = shader->getSamplerLocation("u_image")) {
|
||||
if (!drawable.getTexture(index.value())) {
|
||||
const auto& texture = dashPatternTexture.getTexture();
|
||||
drawable.setEnabled(!!texture);
|
||||
if (texture) {
|
||||
drawable.setTexture(texture, index.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// main UBO
|
||||
const LinePatternPos& posA = dashPatternTexture.getFrom();
|
||||
const LinePatternPos& posB = dashPatternTexture.getTo();
|
||||
const float widthA = posA.width * crossfade.fromScale;
|
||||
const float widthB = posB.width * crossfade.toScale;
|
||||
const LineSDFUBO lineSDFUBO{
|
||||
/* matrix = */ util::cast<float>(matrix),
|
||||
/* units_to_pixels = */
|
||||
{1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/* patternscale_a = */
|
||||
{1.0f / tileID.pixelsToTileUnits(widthA, parameters.state.getIntegerZoom()),
|
||||
-posA.height / 2.0f},
|
||||
/* patternscale_b = */
|
||||
{1.0f / tileID.pixelsToTileUnits(widthB, parameters.state.getIntegerZoom()),
|
||||
-posB.height / 2.0f},
|
||||
/* ratio = */ 1.0f /
|
||||
tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/* device_pixel_ratio = */ parameters.pixelRatio,
|
||||
/* tex_y_a = */ posA.y,
|
||||
/* tex_y_b = */ posB.y,
|
||||
/* sdfgamma = */ static_cast<float>(dashPatternTexture.getSize().width) /
|
||||
(std::min(widthA, widthB) * 256.0f * parameters.pixelRatio) / 2.0f,
|
||||
/* mix = */ crossfade.t};
|
||||
uniforms.createOrUpdate(LineSDFUBOName, &lineSDFUBO, context);
|
||||
|
||||
// properties UBO
|
||||
uniforms.addOrReplace(LineSDFPropertiesUBOName, getLineSDFPropsBuffer());
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
using namespace std::string_literals;
|
||||
Log::Error(Event::General,
|
||||
"LineLayerTweaker: unknown line type: "s + std::to_string(mbgl::underlying_type(type)));
|
||||
} break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,6 +15,14 @@ using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
||||
Line layer specific tweaker
|
||||
*/
|
||||
class LineLayerTweaker : public LayerTweaker {
|
||||
public:
|
||||
enum class LineType {
|
||||
Simple,
|
||||
Pattern,
|
||||
Gradient,
|
||||
SDF
|
||||
};
|
||||
|
||||
public:
|
||||
LineLayerTweaker(Immutable<style::LayerProperties> properties)
|
||||
: LayerTweaker(properties){};
|
||||
@@ -26,6 +34,7 @@ public:
|
||||
protected:
|
||||
gfx::UniformBufferPtr linePropertiesBuffer;
|
||||
gfx::UniformBufferPtr lineGradientPropertiesBuffer;
|
||||
gfx::UniformBufferPtr linePatternPropertiesBuffer;
|
||||
gfx::UniformBufferPtr lineSDFPropertiesBuffer;
|
||||
};
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
stats.drawablesRemoved += tileLayerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) {
|
||||
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
|
||||
const auto& tileID = drawable.getTileID();
|
||||
if (drawable.getRenderPass() != passes || (tileID && !hasRenderTile(*tileID))) {
|
||||
if (tileID && !hasRenderTile(*tileID)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -568,6 +568,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
// update existing drawables
|
||||
tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
|
||||
// TODO: use line type
|
||||
// simple line interpolation UBO
|
||||
if (drawable.getShader()->getUniformBlocks().get(std::string(LineInterpolationUBOName))) {
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
@@ -619,6 +620,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round ? LinePatternCap::Round
|
||||
: LinePatternCap::Square;
|
||||
for (auto& drawable : builder->clearDrawables()) {
|
||||
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::SDF));
|
||||
drawable->setTileID(tileID);
|
||||
drawable->setData(std::make_unique<gfx::LineDrawableData>(cap));
|
||||
drawable->mutableUniformBuffers().createOrUpdate(
|
||||
@@ -666,6 +668,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
// finish
|
||||
builder->flush();
|
||||
for (auto& drawable : builder->clearDrawables()) {
|
||||
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Pattern));
|
||||
drawable->setTileID(tileID);
|
||||
drawable->mutableUniformBuffers().createOrUpdate(
|
||||
LinePatternInterpolationUBOName, &linePatternInterpolationUBO, context);
|
||||
@@ -709,6 +712,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
// finish
|
||||
builder->flush();
|
||||
for (auto& drawable : builder->clearDrawables()) {
|
||||
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Gradient));
|
||||
drawable->setTileID(tileID);
|
||||
drawable->mutableUniformBuffers().createOrUpdate(
|
||||
LineGradientInterpolationUBOName, &lineGradientInterpolationUBO, context);
|
||||
@@ -738,6 +742,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
// finish
|
||||
builder->flush();
|
||||
for (auto& drawable : builder->clearDrawables()) {
|
||||
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Simple));
|
||||
drawable->setTileID(tileID);
|
||||
drawable->mutableUniformBuffers().createOrUpdate(
|
||||
LineInterpolationUBOName, &lineInterpolationUBO, context);
|
||||
|
||||
@@ -37,12 +37,20 @@ struct alignas(16) SymbolDrawableUBO {
|
||||
/* 220 */ float pitch;
|
||||
/* 224 */ /*bool*/ int rotate_symbol;
|
||||
/* 228 */ float aspect_ratio;
|
||||
/* 232 */ float fade_change;
|
||||
/* 236 */ float pad;
|
||||
/* 232 */ std::array<float, 2> pad;
|
||||
/* 240 */
|
||||
};
|
||||
static_assert(sizeof(SymbolDrawableUBO) == 15 * 16);
|
||||
|
||||
/// Dynamic UBO
|
||||
struct alignas(16) SymbolDynamicUBO {
|
||||
/* 0 */ float fade_change;
|
||||
/* 4 */ float pad1;
|
||||
/* 8 */ std::array<float, 2> pad2;
|
||||
/* 16 */
|
||||
};
|
||||
static_assert(sizeof(SymbolDynamicUBO) == 16);
|
||||
|
||||
/// Evaluated properties that do not depend on the tile
|
||||
struct alignas(16) SymbolDrawablePaintUBO {
|
||||
/* 0 */ Color fill_color;
|
||||
@@ -161,27 +169,29 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
// Unpitched point labels need to have their rotation applied after projection
|
||||
const bool rotateInShader = rotateWithMap && !pitchWithMap && !alongLine;
|
||||
|
||||
const SymbolDrawableUBO drawableUBO = {
|
||||
/*.matrix=*/util::cast<float>(matrix),
|
||||
/*.label_plane_matrix=*/util::cast<float>(labelPlaneMatrix),
|
||||
/*.coord_matrix=*/util::cast<float>(glCoordMatrix),
|
||||
const SymbolDrawableUBO drawableUBO = {/*.matrix=*/util::cast<float>(matrix),
|
||||
/*.label_plane_matrix=*/util::cast<float>(labelPlaneMatrix),
|
||||
/*.coord_matrix=*/util::cast<float>(glCoordMatrix),
|
||||
|
||||
/*.texsize=*/toArray(getTexSize(drawable, texUniformName)),
|
||||
/*.texsize_icon=*/toArray(getTexSize(drawable, texIconUniformName)),
|
||||
/*.texsize=*/toArray(getTexSize(drawable, texUniformName)),
|
||||
/*.texsize_icon=*/toArray(getTexSize(drawable, texIconUniformName)),
|
||||
|
||||
/*.gamma_scale=*/gammaScale,
|
||||
/*.device_pixel_ratio=*/parameters.pixelRatio,
|
||||
/*.gamma_scale=*/gammaScale,
|
||||
/*.device_pixel_ratio=*/parameters.pixelRatio,
|
||||
|
||||
/*.camera_to_center_distance=*/camDist,
|
||||
/*.pitch=*/static_cast<float>(state.getPitch()),
|
||||
/*.rotate_symbol=*/rotateInShader,
|
||||
/*.aspect_ratio=*/state.getSize().aspectRatio(),
|
||||
/*.fade_change=*/parameters.symbolFadeChange,
|
||||
/*.pad=*/0,
|
||||
};
|
||||
/*.camera_to_center_distance=*/camDist,
|
||||
/*.pitch=*/static_cast<float>(state.getPitch()),
|
||||
/*.rotate_symbol=*/rotateInShader,
|
||||
/*.aspect_ratio=*/state.getSize().aspectRatio(),
|
||||
/*.pad=*/{0, 0}};
|
||||
|
||||
const SymbolDynamicUBO dynamicUBO = {/*.fade_change=*/parameters.symbolFadeChange,
|
||||
/*.pad1=*/0,
|
||||
/*.pad2=*/{0, 0}};
|
||||
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.createOrUpdate(SymbolDrawableUBOName, &drawableUBO, context);
|
||||
uniforms.createOrUpdate(SymbolDynamicUBOName, &dynamicUBO, context);
|
||||
uniforms.addOrReplace(SymbolDrawablePaintUBOName, isText ? textPaintBuffer : iconPaintBuffer);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
void execute(LayerGroupBase&, const RenderTree&, const PaintParameters&) override;
|
||||
|
||||
static constexpr std::string_view SymbolDrawableUBOName = "SymbolDrawableUBO";
|
||||
static constexpr std::string_view SymbolDynamicUBOName = "SymbolDynamicUBO";
|
||||
static constexpr std::string_view SymbolDrawablePaintUBOName = "SymbolDrawablePaintUBO";
|
||||
static constexpr std::string_view SymbolDrawableTilePropsUBOName = "SymbolDrawableTilePropsUBO";
|
||||
static constexpr std::string_view SymbolDrawableInterpolateUBOName = "SymbolDrawableInterpolateUBO";
|
||||
|
||||
Reference in New Issue
Block a user