Shared attributes (#1898)

This commit is contained in:
Tim Sylvester
2023-11-28 18:57:51 -08:00
committed by GitHub
parent 5c86aee31a
commit fa9712cd8f
35 changed files with 290 additions and 346 deletions

View File

@@ -40,6 +40,7 @@ using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
using IndexVectorBasePtr = std::shared_ptr<IndexVectorBase>;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
using Texture2DPtr = std::shared_ptr<Texture2D>;
using VertexAttributeArrayPtr = std::shared_ptr<VertexAttributeArray>;
class Drawable {
public:
@@ -188,16 +189,10 @@ public:
virtual void setColorMode(const gfx::ColorMode&);
/// Get the vertex attributes that override default values in the shader program
virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0;
/// Get the mutable vertex attribute array
virtual gfx::VertexAttributeArray& mutableVertexAttributes() = 0;
const gfx::VertexAttributeArrayPtr& getVertexAttributes() const noexcept { return vertexAttributes; }
/// Set vertex attribute array
virtual void setVertexAttributes(const gfx::VertexAttributeArray&) = 0;
/// Set vertex attribute array
virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0;
void setVertexAttributes(gfx::VertexAttributeArrayPtr value) noexcept { vertexAttributes = std::move(value); }
/// Provide raw data for vertices. Incompatible with adding primitives
virtual void setVertices(std::vector<uint8_t>&&, std::size_t, AttributeDataType) = 0;
@@ -259,6 +254,7 @@ protected:
int32_t subLayerIndex = 0;
DepthMaskType depthType; // = DepthMaskType::ReadOnly;
UniqueDrawableData drawableData{};
gfx::VertexAttributeArrayPtr vertexAttributes;
struct Impl;
std::unique_ptr<Impl> impl;

View File

@@ -42,7 +42,7 @@ public:
UniqueDrawable& getCurrentDrawable(bool createIfNone);
/// Close the current drawable, using a new one for any further work
void flush();
void flush(gfx::Context& context);
/// Get all the completed drawables
const std::vector<UniqueDrawable>& getDrawables() const { return drawables; }
@@ -134,9 +134,6 @@ public:
/// Set the shader to be used
void setShader(gfx::ShaderProgramBasePtr value) { shader = std::move(value); }
/// Get the vertex attributes that override default values in the shader program
const gfx::VertexAttributeArray& getVertexAttributes() const;
/// Set the name given to new drawables
void setDrawableName(std::string value) { drawableName = std::move(value); }
@@ -157,9 +154,12 @@ public:
/// Clear the tweaker collection
void clearTweakers() { tweakers.clear(); }
/// Get the vertex attributes that override default values in the shader program
VertexAttributeArrayPtr& getVertexAttributes() { return vertexAttrs; }
const VertexAttributeArrayPtr& getVertexAttributes() const { return vertexAttrs; }
/// A set of attribute values to be added for each vertex
void setVertexAttributes(const VertexAttributeArray& value);
void setVertexAttributes(VertexAttributeArray&&);
void setVertexAttributes(VertexAttributeArrayPtr attrs) { vertexAttrs = std::move(attrs); }
/// Add some vertex elements, returns the index of the first one added
std::size_t addVertices(const std::vector<std::array<int16_t, 2>>& vertices,
@@ -232,6 +232,7 @@ protected:
std::vector<UniqueDrawable> drawables;
gfx::Drawable::Textures textures;
std::vector<DrawableTweakerPtr> tweakers;
gfx::VertexAttributeArrayPtr vertexAttrs;
class Impl;
std::unique_ptr<Impl> impl;

View File

@@ -366,23 +366,11 @@ public:
}
VertexAttributeArray& operator=(VertexAttributeArray&&);
VertexAttributeArray& operator=(const VertexAttributeArray&);
VertexAttributeArray& operator=(const VertexAttributeArray&) = delete;
/// Clone the collection
virtual UniqueVertexAttributeArray clone() const {
auto newAttrs = std::make_unique<VertexAttributeArray>();
newAttrs->copy(*this);
return newAttrs;
}
/// Copy another collection into this one
virtual void copy(const VertexAttributeArray& other) {
for (const auto& kv : other.attrs) {
if (kv.second) {
attrs.insert(std::make_pair(kv.first, copy(*kv.second)));
}
}
}
/// Specialized DataDrivenPaintProperty reader
/// @param binders Property binders for the target shader

View File

@@ -41,12 +41,6 @@ public:
void setVertices(std::vector<uint8_t>&&, std::size_t, gfx::AttributeDataType) override;
const gfx::VertexAttributeArray& getVertexAttributes() const override;
void setVertexAttributes(const gfx::VertexAttributeArray& value) override;
void setVertexAttributes(gfx::VertexAttributeArray&& value) override;
gfx::VertexAttributeArray& mutableVertexAttributes() override;
const gfx::UniformBufferArray& getUniformBuffers() const override;
gfx::UniformBufferArray& mutableUniformBuffers() override;

View File

@@ -61,16 +61,7 @@ public:
VertexAttributeArray::operator=(std::move(other));
return *this;
}
VertexAttributeArrayGL& operator=(const VertexAttributeArrayGL& other) {
VertexAttributeArray::operator=(other);
return *this;
}
std::unique_ptr<VertexAttributeArray> clone() const override {
auto newAttrs = std::make_unique<VertexAttributeArrayGL>();
newAttrs->copy(*this);
return newAttrs;
}
VertexAttributeArrayGL& operator=(const VertexAttributeArrayGL&) = delete;
/// Indicates whether any values have changed
bool isDirty() const override;

View File

@@ -22,6 +22,11 @@ namespace mbgl {
class ProgramParameters;
class RenderStaticData;
namespace gfx {
class VertexAttributeArray;
using VertexAttributeArrayPtr = std::shared_ptr<VertexAttributeArray>;
} // namespace gfx
namespace shaders {
struct ClipUBO;
} // namespace shaders
@@ -85,8 +90,6 @@ public:
RenderTargetPtr createRenderTarget(const Size size, const gfx::TextureChannelDataType type) override;
// UniqueFramebuffer createFramebuffer(const gfx::Texture2D& color);
void resetState(gfx::DepthMode depthMode, gfx::ColorMode colorMode) override;
void setDirtyState() override;
@@ -104,6 +107,8 @@ public:
std::unique_ptr<gfx::DrawScopeResource> createDrawScopeResource() override;
gfx::VertexAttributeArrayPtr createVertexAttributeArray() const override;
#if !defined(NDEBUG)
void visualizeStencilBuffer() override;
void visualizeDepthBuffer(float depthRangeSize) override;

View File

@@ -40,12 +40,6 @@ public:
void setVertices(std::vector<uint8_t>&&, std::size_t, gfx::AttributeDataType) override;
const gfx::VertexAttributeArray& getVertexAttributes() const override;
void setVertexAttributes(const gfx::VertexAttributeArray& value) override;
void setVertexAttributes(gfx::VertexAttributeArray&& value) override;
gfx::VertexAttributeArray& mutableVertexAttributes() override;
const gfx::UniformBufferArray& getUniformBuffers() const override;
gfx::UniformBufferArray& mutableUniformBuffers() override;

View File

@@ -18,17 +18,13 @@ private:
friend VertexAttributeArray;
VertexAttribute(int index_, gfx::AttributeDataType dataType_, std::size_t count_)
: gfx::VertexAttribute(index_, dataType_, count_) {}
VertexAttribute(const VertexAttribute& other)
: gfx::VertexAttribute(other) {}
VertexAttribute(const VertexAttribute& other) = delete;
VertexAttribute(VertexAttribute&& other)
: gfx::VertexAttribute(std::move(other)) {}
public:
~VertexAttribute() override = default;
/// Get the Metal buffer, creating it if necessary
// const gfx::UniqueVertexBufferResource& getBuffer(UploadPass&, const gfx::BufferUsageType);
static const gfx::UniqueVertexBufferResource& getBuffer(gfx::VertexAttribute&,
UploadPass&,
const gfx::BufferUsageType);
@@ -45,16 +41,7 @@ public:
gfx::VertexAttributeArray::operator=(std::move(other));
return *this;
}
VertexAttributeArray& operator=(const VertexAttributeArray& other) {
gfx::VertexAttributeArray::operator=(other);
return *this;
}
gfx::UniqueVertexAttributeArray clone() const override {
auto newAttrs = std::make_unique<VertexAttributeArray>();
newAttrs->copy(*this);
return newAttrs;
}
VertexAttributeArray& operator=(const VertexAttributeArray& other) = delete;
/// Indicates whether any values have changed
bool isDirty() const override;
@@ -63,12 +50,6 @@ private:
gfx::UniqueVertexAttribute create(int index, gfx::AttributeDataType dataType, std::size_t count) const override {
return gfx::UniqueVertexAttribute(new VertexAttribute(index, dataType, count));
}
using gfx::VertexAttributeArray::copy;
gfx::UniqueVertexAttribute copy(const gfx::VertexAttribute& attr) const override {
return gfx::UniqueVertexAttribute(new VertexAttribute(static_cast<const VertexAttribute&>(attr)));
}
};
} // namespace mtl

View File

@@ -48,8 +48,6 @@ public:
protected:
gfx::UniformBlockArray& mutableUniformBlocks() override { return uniformBlocks; }
gfx::VertexAttributeArray& mutableVertexAttributes() override { return vertexAttributes; }
protected:
UniqueProgram glProgram;

View File

@@ -62,7 +62,6 @@ public:
std::optional<uint32_t> getSamplerLocation(const StringIdentity id) const override;
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
gfx::VertexAttributeArray& mutableVertexAttributes() override { return vertexAttributes; }
const gfx::UniformBlockArray& getUniformBlocks() const override { return uniformBlocks; }
gfx::UniformBlockArray& mutableUniformBlocks() override { return uniformBlocks; }

View File

@@ -41,14 +41,8 @@ public:
/// Get the available vertex attributes and their default values
virtual const gfx::VertexAttributeArray& getVertexAttributes() const = 0;
template <typename T>
bool setAttribute(const std::string& name, std::size_t i, T value) {
return set(mutableVertexAttributes(), name, i, value);
}
protected:
virtual gfx::UniformBlockArray& mutableUniformBlocks() = 0;
virtual gfx::VertexAttributeArray& mutableVertexAttributes() = 0;
protected:
util::SimpleIdentity shaderProgramID;

View File

@@ -40,12 +40,14 @@ class Drawable;
class DrawableBuilder;
class ShaderProgramBase;
class Texture2D;
class VertexAttributeArray;
using DrawablePtr = std::shared_ptr<Drawable>;
using UniqueDrawableBuilder = std::unique_ptr<DrawableBuilder>;
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
using Texture2DPtr = std::shared_ptr<Texture2D>;
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
using UniqueDrawableBuilder = std::unique_ptr<DrawableBuilder>;
using VertexAttributeArrayPtr = std::shared_ptr<VertexAttributeArray>;
#endif
class Context {
@@ -57,24 +59,20 @@ public:
static constexpr const uint32_t minimumRequiredVertexBindingCount = 8;
const uint32_t maximumVertexBindingCount;
public:
Context(Context&&) = delete;
Context(const Context&) = delete;
Context& operator=(Context&& other) = delete;
Context& operator=(const Context& other) = delete;
virtual ~Context() = default;
public:
/// Called at the end of a frame.
virtual void performCleanup() = 0;
/// Called when the app receives a memory warning and before it goes to the background.
virtual void reduceMemoryUsage() = 0;
public:
virtual std::unique_ptr<OffscreenTexture> createOffscreenTexture(Size, TextureChannelDataType) = 0;
public:
/// Creates an empty texture with the specified dimensions.
Texture createTexture(const Size size,
TexturePixelType format = TexturePixelType::RGBA,
@@ -82,32 +80,19 @@ public:
return {size, createTextureResource(size, format, type)};
}
protected:
virtual std::unique_ptr<TextureResource> createTextureResource(Size, TexturePixelType, TextureChannelDataType) = 0;
public:
template <RenderbufferPixelType pixelType>
Renderbuffer<pixelType> createRenderbuffer(const Size size) {
return {size, createRenderbufferResource(pixelType, size)};
}
protected:
virtual std::unique_ptr<RenderbufferResource> createRenderbufferResource(RenderbufferPixelType, Size) = 0;
public:
DrawScope createDrawScope() { return DrawScope{createDrawScopeResource()}; }
protected:
virtual std::unique_ptr<DrawScopeResource> createDrawScopeResource() = 0;
public:
virtual std::unique_ptr<CommandEncoder> createCommandEncoder() = 0;
gfx::RenderingStats& renderingStats() { return stats; }
const gfx::RenderingStats& renderingStats() const { return stats; }
#if !defined(NDEBUG)
public:
virtual void visualizeStencilBuffer() = 0;
virtual void visualizeDepthBuffer(float depthRangeSize) = 0;
#endif
@@ -118,7 +103,9 @@ public:
virtual void setDirtyState() = 0;
#if MLN_DRAWABLE_RENDERER
public:
/// Create a new vertex attribute array
virtual gfx::VertexAttributeArrayPtr createVertexAttributeArray() const = 0;
/// Create a new drawable builder
virtual UniqueDrawableBuilder createDrawableBuilder(std::string name) = 0;
@@ -166,6 +153,10 @@ public:
#endif
protected:
virtual std::unique_ptr<TextureResource> createTextureResource(Size, TexturePixelType, TextureChannelDataType) = 0;
virtual std::unique_ptr<RenderbufferResource> createRenderbufferResource(RenderbufferPixelType, Size) = 0;
virtual std::unique_ptr<DrawScopeResource> createDrawScopeResource() = 0;
gfx::RenderingStats stats;
};

View File

@@ -33,10 +33,6 @@ void DrawableBuilder::setCullFaceMode(const gfx::CullFaceMode& value) {
impl->cullFaceMode = value;
}
const gfx::VertexAttributeArray& DrawableBuilder::getVertexAttributes() const {
return impl->vertexAttrs;
}
UniqueDrawable& DrawableBuilder::getCurrentDrawable(bool createIfNone) {
if (!currentDrawable && createIfNone) {
currentDrawable = createDrawable();
@@ -44,11 +40,11 @@ UniqueDrawable& DrawableBuilder::getCurrentDrawable(bool createIfNone) {
return currentDrawable;
}
void DrawableBuilder::flush() {
void DrawableBuilder::flush(gfx::Context& context) {
if (curVertexCount()) {
if (Impl::Mode::Polylines == impl->getMode()) {
// setup for polylines
impl->setupForPolylines(*this);
impl->setupForPolylines(context, *this);
}
const auto& draw = getCurrentDrawable(/*createIfNone=*/true);
@@ -68,9 +64,10 @@ void DrawableBuilder::flush() {
draw->setTextures(textures);
draw->setTweakers(tweakers);
const auto& builderAttrs = getVertexAttributes();
if (auto drawAttrs = builderAttrs.clone()) {
draw->setVertexAttributes(std::move(*drawAttrs));
if (vertexAttrs) {
draw->setVertexAttributes(vertexAttrs);
} else {
draw->setVertexAttributes(context.createVertexAttributeArray());
}
init();
@@ -151,14 +148,6 @@ void DrawableBuilder::addQuad(int16_t x0, int16_t y0, int16_t x1, int16_t y1) {
appendTriangle(x1, y1);
}
void DrawableBuilder::setVertexAttributes(const VertexAttributeArray& attrs) {
impl->vertexAttrs = attrs;
}
void DrawableBuilder::setVertexAttributes(VertexAttributeArray&& attrs) {
impl->vertexAttrs = std::move(attrs);
}
std::size_t DrawableBuilder::addVertices(const std::vector<std::array<int16_t, 2>>& vertices,
std::size_t vertexOffset,
std::size_t vertexLength) {

View File

@@ -59,7 +59,7 @@ void DrawableBuilder::Impl::addPolyline(gfx::DrawableBuilder& builder,
generator.generate(coordinates, options);
}
void DrawableBuilder::Impl::setupForPolylines(gfx::DrawableBuilder& builder) {
void DrawableBuilder::Impl::setupForPolylines(gfx::Context& context, gfx::DrawableBuilder& builder) {
// setup vertex attributes
static const StringIdentity idVertexAttribName = stringIndexer().get("a_pos_normal");
static const StringIdentity idDataAttribName = stringIndexer().get("a_data");
@@ -68,11 +68,11 @@ void DrawableBuilder::Impl::setupForPolylines(gfx::DrawableBuilder& builder) {
builder.setRawVertices({}, polylineVertices.elements(), gfx::AttributeDataType::Short2);
gfx::VertexAttributeArray attrs;
auto attrs = context.createVertexAttributeArray();
using VertexVector = gfx::VertexVector<LineLayoutVertex>;
std::shared_ptr<VertexVector> verts = std::make_shared<VertexVector>(std::move(polylineVertices));
if (const auto& attr = attrs.add(idVertexAttribName)) {
if (const auto& attr = attrs->add(idVertexAttribName)) {
attr->setSharedRawData(verts,
offsetof(LineLayoutVertex, a1),
/*vertexOffset=*/0,
@@ -80,7 +80,7 @@ void DrawableBuilder::Impl::setupForPolylines(gfx::DrawableBuilder& builder) {
gfx::AttributeDataType::Short2);
}
if (const auto& attr = attrs.add(idDataAttribName)) {
if (const auto& attr = attrs->add(idDataAttribName)) {
attr->setSharedRawData(verts,
offsetof(LineLayoutVertex, a2),
/*vertexOffset=*/0,

View File

@@ -47,13 +47,11 @@ public:
gfx::ColorMode colorMode = gfx::ColorMode::disabled();
gfx::CullFaceMode cullFaceMode = gfx::CullFaceMode::disabled();
VertexAttributeArray vertexAttrs;
void addPolyline(gfx::DrawableBuilder& builder,
const GeometryCoordinates& coordinates,
const gfx::PolylineGeneratorOptions& options);
void setupForPolylines(gfx::DrawableBuilder& builder);
void setupForPolylines(gfx::Context&, gfx::DrawableBuilder&);
bool checkAndSetMode(Mode);

View File

@@ -71,6 +71,9 @@ public:
void clear() {
dirty = true;
v.clear();
#if MLN_DRAWABLE_RENDERER
buffer.reset();
#endif // MLN_DRAWABLE_RENDERER
}
/// Indicate that this shared index vector will no longer be updated.

View File

@@ -93,16 +93,6 @@ VertexAttributeArray& VertexAttributeArray::operator=(VertexAttributeArray&& oth
return *this;
}
VertexAttributeArray& VertexAttributeArray::operator=(const VertexAttributeArray& other) {
attrs.clear();
for (const auto& kv : other.attrs) {
if (kv.second) {
add(kv.first, copy(*kv.second));
}
}
return *this;
}
const std::unique_ptr<VertexAttribute>& VertexAttributeArray::get(const StringIdentity id) const {
const auto result = attrs.find(id);
return (result != attrs.end()) ? result->second : nullref;

View File

@@ -532,6 +532,11 @@ Framebuffer Context::createFramebuffer(const gfx::Texture2D& color) {
checkFramebuffer();
return {color.getSize(), std::move(fbo)};
}
gfx::VertexAttributeArrayPtr Context::createVertexAttributeArray() const {
return std::make_shared<VertexAttributeArrayGL>();
}
#endif
void Context::clear(std::optional<mbgl::Color> color, std::optional<float> depth, std::optional<int32_t> stencil) {

View File

@@ -117,6 +117,8 @@ public:
Framebuffer createFramebuffer(const gfx::Texture2D& color);
gfx::VertexAttributeArrayPtr createVertexAttributeArray() const override;
void resetState(gfx::DepthMode depthMode, gfx::ColorMode colorMode) override;
bool emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr&,

View File

@@ -88,21 +88,6 @@ void DrawableGL::setVertices(std::vector<uint8_t>&& data, std::size_t count, gfx
impl->vertexType = type_;
}
const gfx::VertexAttributeArray& DrawableGL::getVertexAttributes() const {
return impl->vertexAttributes;
}
gfx::VertexAttributeArray& DrawableGL::mutableVertexAttributes() {
return impl->vertexAttributes;
}
void DrawableGL::setVertexAttributes(const gfx::VertexAttributeArray& value) {
impl->vertexAttributes = static_cast<const VertexAttributeArrayGL&>(value);
}
void DrawableGL::setVertexAttributes(gfx::VertexAttributeArray&& value) {
impl->vertexAttributes = std::move(static_cast<VertexAttributeArrayGL&&>(value));
}
const gfx::UniformBufferArray& DrawableGL::getUniformBuffers() const {
return impl->uniformBuffers;
}
@@ -157,10 +142,11 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
return;
}
const bool build = impl->vertexAttributes.isDirty() ||
std::any_of(impl->segments.begin(), impl->segments.end(), [](const auto& seg) {
return !static_cast<const DrawSegmentGL&>(*seg).getVertexArray().isValid();
});
const bool build = vertexAttributes &&
(vertexAttributes->isDirty() ||
std::any_of(impl->segments.begin(), impl->segments.end(), [](const auto& seg) {
return !static_cast<const DrawSegmentGL&>(*seg).getVertexArray().isValid();
}));
if (build) {
auto& context = uploadPass.getContext();
@@ -169,7 +155,7 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
// Apply drawable values to shader defaults
const auto& defaults = shader->getVertexAttributes();
const auto& overrides = impl->vertexAttributes;
const auto& overrides = *vertexAttributes;
const auto& indexAttribute = defaults.get(impl->idVertexAttrName);
const auto vertexAttributeIndex = static_cast<std::size_t>(indexAttribute ? indexAttribute->getIndex() : -1);

View File

@@ -39,8 +39,6 @@ public:
std::size_t vertexCount = 0;
gfx::AttributeDataType vertexType = static_cast<gfx::AttributeDataType>(-1);
VertexAttributeArrayGL vertexAttributes;
gfx::IndexBuffer indexBuffer = {0, nullptr};
std::vector<gfx::UniqueVertexBufferResource> attributeBuffers;

View File

@@ -444,6 +444,10 @@ std::unique_ptr<gfx::DrawScopeResource> Context::createDrawScopeResource() {
return nullptr;
}
gfx::VertexAttributeArrayPtr Context::createVertexAttributeArray() const {
return std::make_shared<VertexAttributeArray>();
}
#if !defined(NDEBUG)
void Context::visualizeStencilBuffer() {}

View File

@@ -306,7 +306,10 @@ void Drawable::setVertices(std::vector<uint8_t>&& data, std::size_t count, gfx::
impl->vertexType = type;
if (count && type != gfx::AttributeDataType::Invalid && !data.empty()) {
if (auto& attrib = impl->vertexAttributes.getOrAdd(impl->idVertexAttrName, /*index=*/-1, type)) {
if (!vertexAttributes) {
vertexAttributes = std::make_shared<VertexAttributeArray>();
}
if (auto& attrib = vertexAttributes->getOrAdd(impl->idVertexAttrName, /*index=*/-1, type)) {
attrib->setRawData(std::move(data));
attrib->setStride(VertexAttribute::getStrideOf(type));
} else {
@@ -319,21 +322,6 @@ void Drawable::setVertices(std::vector<uint8_t>&& data, std::size_t count, gfx::
}
}
const gfx::VertexAttributeArray& Drawable::getVertexAttributes() const {
return impl->vertexAttributes;
}
gfx::VertexAttributeArray& Drawable::mutableVertexAttributes() {
return impl->vertexAttributes;
}
void Drawable::setVertexAttributes(const gfx::VertexAttributeArray& value) {
impl->vertexAttributes = static_cast<const VertexAttributeArray&>(value);
}
void Drawable::setVertexAttributes(gfx::VertexAttributeArray&& value) {
impl->vertexAttributes = std::move(static_cast<VertexAttributeArray&&>(value));
}
const gfx::UniformBufferArray& Drawable::getUniformBuffers() const {
return impl->uniformBuffers;
}
@@ -513,13 +501,17 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
impl->indexes->setDirty(false);
}
const bool buildAttribs = impl->vertexAttributes.isDirty() || !impl->vertexDesc;
const bool buildAttribs = !vertexAttributes || vertexAttributes->isDirty() || !impl->vertexDesc;
if (buildAttribs) {
#if !defined(NDEBUG)
const auto debugGroup = uploadPass.createDebugGroup(debugLabel(*this));
#endif
if (!vertexAttributes) {
vertexAttributes = std::make_shared<VertexAttributeArray>();
}
// Apply drawable values to shader defaults
std::vector<std::unique_ptr<gfx::VertexBufferResource>> vertexBuffers;
auto attributeBindings_ = uploadPass.buildAttributeBindings(impl->vertexCount,
@@ -527,13 +519,12 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
/*vertexAttributeIndex=*/-1,
/*vertexData=*/{},
shader->getVertexAttributes(),
impl->vertexAttributes,
*vertexAttributes,
usage,
vertexBuffers);
impl->attributeBuffers = std::move(vertexBuffers);
impl->vertexAttributes.visitAttributes(
[](const auto&, gfx::VertexAttribute& attrib) { attrib.setDirty(false); });
vertexAttributes->visitAttributes([](const auto&, gfx::VertexAttribute& attrib) { attrib.setDirty(false); });
if (impl->attributeBindings != attributeBindings_) {
impl->attributeBindings = std::move(attributeBindings_);

View File

@@ -44,7 +44,6 @@ public:
gfx::IndexVectorBasePtr indexes;
std::size_t vertexCount = 0;
gfx::AttributeDataType vertexType = gfx::AttributeDataType::Invalid;
VertexAttributeArray vertexAttributes;
std::vector<gfx::UniqueVertexBufferResource> attributeBuffers;

View File

@@ -314,7 +314,7 @@ void RenderBackgroundLayer::update(gfx::ShaderRegistry& shaders,
auto verticesCopy = rawVertices;
builder->setRawVertices(std::move(verticesCopy), vertexCount, gfx::AttributeDataType::Short2);
builder->setSegments(gfx::Triangles(), indexes.vector(), segs.data(), segs.size());
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);

View File

@@ -380,14 +380,14 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
const auto interpBuffer = context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
propertiesAsUniforms.clear();
gfx::VertexAttributeArray circleVertexAttrs;
circleVertexAttrs.readDataDrivenPaintProperties<CircleColor,
CircleRadius,
CircleBlur,
CircleOpacity,
CircleStrokeColor,
CircleStrokeWidth,
CircleStrokeOpacity>(
auto circleVertexAttrs = context.createVertexAttributeArray();
circleVertexAttrs->readDataDrivenPaintProperties<CircleColor,
CircleRadius,
CircleBlur,
CircleOpacity,
CircleStrokeColor,
CircleStrokeWidth,
CircleStrokeOpacity>(
paintPropertyBinders, evaluated, propertiesAsUniforms);
if (!circleShaderGroup) {
@@ -402,7 +402,7 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
if (const auto& attr = circleVertexAttrs.add(idVertexAttribName)) {
if (const auto& attr = circleVertexAttrs->add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(CircleLayoutVertex, a1),
0,
@@ -423,7 +423,7 @@ void RenderCircleLayer::update(gfx::ShaderRegistry& shaders,
circleBuilder->setSegments(
gfx::Triangles(), bucket.sharedTriangles, bucket.segments.data(), bucket.segments.size());
circleBuilder->flush();
circleBuilder->flush(context);
for (auto& drawable : circleBuilder->clearDrawables()) {
drawable->setTileID(tileID);

View File

@@ -419,12 +419,13 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
gfx::VertexAttributeArray vertexAttrs;
propertiesAsUniforms.clear();
vertexAttrs.readDataDrivenPaintProperties<FillExtrusionBase,
FillExtrusionColor,
FillExtrusionHeight,
FillExtrusionPattern>(binders, evaluated, propertiesAsUniforms);
auto vertexAttrs = context.createVertexAttributeArray();
vertexAttrs->readDataDrivenPaintProperties<FillExtrusionBase,
FillExtrusionColor,
FillExtrusionHeight,
FillExtrusionPattern>(binders, evaluated, propertiesAsUniforms);
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
shaderGroup->getOrCreateShader(context, propertiesAsUniforms));
@@ -487,14 +488,14 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
}
}
if (const auto& attr = vertexAttrs.getOrAdd(idPosAttribName)) {
if (const auto& attr = vertexAttrs->add(idPosAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(FillExtrusionLayoutVertex, a1),
/*vertexOffset=*/0,
sizeof(FillExtrusionLayoutVertex),
gfx::AttributeDataType::Short2);
}
if (const auto& attr = vertexAttrs.getOrAdd(idNormAttribName)) {
if (const auto& attr = vertexAttrs->add(idNormAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(FillExtrusionLayoutVertex, a2),
/*vertexOffset=*/0,
@@ -502,16 +503,13 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
gfx::AttributeDataType::Short4);
}
colorBuilder->setEnableStencil(doDepthPass);
if (doDepthPass) {
depthBuilder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short2);
depthBuilder->setVertexAttributes(vertexAttrs);
}
colorBuilder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short2);
if (doDepthPass) {
auto copy = vertexAttrs.clone();
depthBuilder->setVertexAttributes(std::move(*copy));
}
colorBuilder->setEnableStencil(doDepthPass);
colorBuilder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short2);
colorBuilder->setVertexAttributes(std::move(vertexAttrs));
const auto finish = [&](gfx::DrawableBuilder& builder) {
@@ -523,7 +521,7 @@ void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
bucket.triangleSegments.data(),
bucket.triangleSegments.size());
builder.flush();
builder.flush(context);
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);

View File

@@ -620,10 +620,11 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
return atlasTweaker;
};
// `Fill*Program` all use `style::FillPaintProperties`
gfx::VertexAttributeArray vertexAttrs;
propertiesAsUniforms.clear();
vertexAttrs.readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(
// `Fill*Program` all use `style::FillPaintProperties`
auto vertexAttrs = context.createVertexAttributeArray();
vertexAttrs->readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(
binders, evaluated, propertiesAsUniforms);
if (layerTweaker) {
@@ -631,7 +632,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
}
const auto vertexCount = bucket.vertices.elements();
if (const auto& attr = vertexAttrs.add(idPosAttribName)) {
if (const auto& attr = vertexAttrs->add(idPosAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(FillLayoutVertex, a1),
/*vertexOffset=*/0,
@@ -715,15 +716,16 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
builder->setVertexAttrNameId(idVertexAttribName);
builder->setShader(outlineTriangulatedShader);
builder->setRawVertices({}, bucket.lineVertices.elements(), gfx::AttributeDataType::Short2);
gfx::VertexAttributeArray attrs;
if (const auto& attr = attrs.add(idVertexAttribName)) {
auto attrs = context.createVertexAttributeArray();
if (const auto& attr = attrs->add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedLineVertices,
offsetof(LineLayoutVertex, a1),
/*vertexOffset=*/0,
sizeof(LineLayoutVertex),
gfx::AttributeDataType::Short2);
}
if (const auto& attr = attrs.add(idDataAttribName)) {
if (const auto& attr = attrs->add(idDataAttribName)) {
attr->setSharedRawData(bucket.sharedLineVertices,
offsetof(LineLayoutVertex, a2),
/*vertexOffset=*/0,
@@ -731,6 +733,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
gfx::AttributeDataType::UByte4);
}
builder->setVertexAttributes(std::move(attrs));
builder->setSegments(gfx::Triangles(),
bucket.sharedLineIndexes,
bucket.lineSegments.data(),
@@ -739,7 +742,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
auto tweaker = std::make_shared<OutlineDrawableTweaker>(color, opacity);
// finish
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->addTweaker(tweaker);
@@ -785,7 +788,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
const auto& interpolateUBO,
FillVariant type) {
builder.setVertexAttrNameId(idPosAttribName);
builder.flush();
builder.flush(context);
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);
@@ -919,7 +922,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
const StringIdentity tileUBONameId,
const auto& tileUBO,
FillVariant type) {
builder.flush();
builder.flush(context);
for (auto& drawable : builder.clearDrawables()) {
drawable->setTileID(tileID);

View File

@@ -72,7 +72,6 @@ void RenderHeatmapLayer::evaluate(const PropertyEvaluationParameters& parameters
if (auto tileLayerGroup = renderTarget->getLayerGroup(0)) {
auto newTweaker = std::make_shared<HeatmapLayerTweaker>(getID(), evaluatedProperties);
// propertiesAsUniforms isn't recalculated every update, so carry it over
if (layerTweaker) {
newTweaker->setPropertiesAsUniforms(layerTweaker->getPropertiesAsUniforms());
}
@@ -352,7 +351,12 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
[&](gfx::Drawable& drawable) { return drawable.getTileID() && !hasRenderTile(*drawable.getTileID()); });
const auto& evaluated = static_cast<const HeatmapLayerProperties&>(*evaluatedProperties).evaluated;
mbgl::unordered_set<StringIdentity> propertiesAsUniforms;
std::optional<mbgl::unordered_set<StringIdentity>> propertiesAsUniforms;
#if !defined(NDEBUG)
std::optional<mbgl::unordered_set<StringIdentity>> previousPropertiesAsUniforms;
#endif
gfx::ShaderPtr heatmapShader;
for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();
@@ -388,15 +392,6 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
return interpolateBuffer;
};
gfx::VertexAttributeArray heatmapVertexAttrs;
propertiesAsUniforms.clear();
heatmapVertexAttrs.readDataDrivenPaintProperties<HeatmapWeight, HeatmapRadius>(
paintPropertyBinders, evaluated, propertiesAsUniforms);
if (layerTweaker) {
layerTweaker->setPropertiesAsUniforms(propertiesAsUniforms);
}
const auto updatedCount = tileLayerGroup->visitDrawables(renderPass, tileID, [&](gfx::Drawable& drawable) {
if (drawable.getLayerTweaker() != layerTweaker) {
// This drawable was produced on a previous style/bucket, and should not be updated.
@@ -417,12 +412,36 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
continue;
}
const auto heatmapShader = heatmapShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!propertiesAsUniforms) {
propertiesAsUniforms.emplace();
}
#if !defined(NDEBUG)
else {
propertiesAsUniforms->clear();
}
#endif
auto heatmapVertexAttrs = context.createVertexAttributeArray();
heatmapVertexAttrs->readDataDrivenPaintProperties<HeatmapWeight, HeatmapRadius>(
paintPropertyBinders, evaluated, *propertiesAsUniforms);
#if !defined(NDEBUG)
// We assume the properties are the same across tiles.
if (previousPropertiesAsUniforms) {
assert(*propertiesAsUniforms == previousPropertiesAsUniforms);
} else {
previousPropertiesAsUniforms = propertiesAsUniforms;
}
#endif
if (!heatmapShader) {
continue;
heatmapShader = heatmapShaderGroup->getOrCreateShader(context, *propertiesAsUniforms);
if (!heatmapShader) {
continue;
}
}
if (const auto& attr = heatmapVertexAttrs.add(idVertexAttribName)) {
if (const auto& attr = heatmapVertexAttrs->add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(HeatmapLayoutVertex, a1),
/*vertexOffset=*/0,
@@ -441,7 +460,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
heatmapBuilder->setSegments(
gfx::Triangles(), bucket.sharedTriangles, bucket.segments.data(), bucket.segments.size());
heatmapBuilder->flush();
heatmapBuilder->flush(context);
for (auto& drawable : heatmapBuilder->clearDrawables()) {
drawable->setTileID(tileID);
@@ -458,6 +477,10 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
}
}
if (layerTweaker && propertiesAsUniforms) {
layerTweaker->setPropertiesAsUniforms(*propertiesAsUniforms);
}
// Set up texture layer group
if (!layerGroup) {
if (auto layerGroup_ = context.createLayerGroup(layerIndex, /*initialCapacity=*/1, getID())) {
@@ -494,8 +517,8 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
}
const auto textureVertexCount = sharedTextureVertices->elements();
gfx::VertexAttributeArray textureVertexAttrs;
if (const auto& attr = textureVertexAttrs.add(idVertexAttribName)) {
auto textureVertexAttrs = context.createVertexAttributeArray();
if (const auto& attr = textureVertexAttrs->add(idVertexAttribName)) {
attr->setSharedRawData(sharedTextureVertices,
offsetof(HeatmapLayoutVertex, a1),
/*vertexOffset=*/0,
@@ -530,7 +553,7 @@ void RenderHeatmapLayer::update(gfx::ShaderRegistry& shaders,
heatmapTextureBuilder->setTexture(std::move(texture), colorRampLocation.value());
}
heatmapTextureBuilder->flush();
heatmapTextureBuilder->flush(context);
for (auto& drawable : heatmapTextureBuilder->clearDrawables()) {
drawable->setLayerTweaker(textureTweaker);

View File

@@ -365,6 +365,29 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
std::unique_ptr<gfx::DrawableBuilder> hillshadeBuilder;
std::unique_ptr<gfx::DrawableBuilder> hillshadePrepareBuilder;
gfx::VertexAttributeArrayPtr hillshadePrepareVertexAttrs;
const auto getPrepareVertexAttributes = [&] {
if (!hillshadePrepareVertexAttrs) {
hillshadePrepareVertexAttrs = context.createVertexAttributeArray();
if (const auto& attr = hillshadePrepareVertexAttrs->add(idPosAttribName)) {
attr->setSharedRawData(staticDataSharedVertices,
offsetof(HillshadeLayoutVertex, a1),
0,
sizeof(HillshadeLayoutVertex),
gfx::AttributeDataType::Short2);
}
if (const auto& attr = hillshadePrepareVertexAttrs->add(idTexturePosAttribName)) {
attr->setSharedRawData(staticDataSharedVertices,
offsetof(HillshadeLayoutVertex, a2),
0,
sizeof(HillshadeLayoutVertex),
gfx::AttributeDataType::Short2);
}
}
return hillshadePrepareVertexAttrs;
};
for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();
@@ -406,31 +429,13 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
}
singleTileLayerGroup->addLayerTweaker(prepareLayerTweaker);
gfx::VertexAttributeArray hillshadePrepareVertexAttrs;
if (const auto& attr = hillshadePrepareVertexAttrs.add(idPosAttribName)) {
attr->setSharedRawData(staticDataSharedVertices,
offsetof(HillshadeLayoutVertex, a1),
0,
sizeof(HillshadeLayoutVertex),
gfx::AttributeDataType::Short2);
}
if (const auto& attr = hillshadePrepareVertexAttrs.getOrAdd(idTexturePosAttribName)) {
attr->setSharedRawData(staticDataSharedVertices,
offsetof(HillshadeLayoutVertex, a2),
0,
sizeof(HillshadeLayoutVertex),
gfx::AttributeDataType::Short2);
}
hillshadePrepareBuilder = context.createDrawableBuilder("hillshadePrepare");
hillshadePrepareBuilder->setShader(hillshadePrepareShader);
hillshadePrepareBuilder->setDepthType(gfx::DepthMaskType::ReadOnly);
hillshadePrepareBuilder->setColorMode(gfx::ColorMode::unblended());
hillshadePrepareBuilder->setCullFaceMode(gfx::CullFaceMode::disabled());
hillshadePrepareBuilder->setRenderPass(renderPass);
hillshadePrepareBuilder->setVertexAttributes(std::move(hillshadePrepareVertexAttrs));
hillshadePrepareBuilder->setVertexAttributes(getPrepareVertexAttributes());
hillshadePrepareBuilder->setRawVertices(
{}, staticDataSharedVertices->elements(), gfx::AttributeDataType::Short2);
hillshadePrepareBuilder->setSegments(
@@ -445,7 +450,7 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
hillshadePrepareBuilder->setTexture(texture, imageLocation.value());
}
hillshadePrepareBuilder->flush();
hillshadePrepareBuilder->flush(context);
for (auto& drawable : hillshadePrepareBuilder->clearDrawables()) {
drawable->setTileID(tileID);
@@ -468,33 +473,39 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
segments = &bucket.segments;
}
gfx::VertexAttributeArray hillshadeVertexAttrs;
if (const auto& attr = hillshadeVertexAttrs.add(idPosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(HillshadeLayoutVertex, a1),
0,
sizeof(HillshadeLayoutVertex),
gfx::AttributeDataType::Short2);
}
if (const auto& attr = hillshadeVertexAttrs.getOrAdd(idTexturePosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(HillshadeLayoutVertex, a2),
0,
sizeof(HillshadeLayoutVertex),
gfx::AttributeDataType::Short2);
}
hillshadeBuilder = context.createDrawableBuilder("hillshade");
auto updateExisting = [&](gfx::Drawable& drawable) {
gfx::VertexAttributeArrayPtr hillshadeVertexAttrs;
auto buildVertexAttributes = [&] {
if (!hillshadeVertexAttrs) {
hillshadeVertexAttrs = context.createVertexAttributeArray();
if (const auto& attr = hillshadeVertexAttrs->add(idPosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(HillshadeLayoutVertex, a1),
0,
sizeof(HillshadeLayoutVertex),
gfx::AttributeDataType::Short2);
}
if (const auto& attr = hillshadeVertexAttrs->getOrAdd(idTexturePosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(HillshadeLayoutVertex, a2),
0,
sizeof(HillshadeLayoutVertex),
gfx::AttributeDataType::Short2);
}
}
return hillshadeVertexAttrs;
};
const auto updateExisting = [&](gfx::Drawable& drawable) {
// Only current drawables are updated, ones produced for
// a previous style retain the attribute values for that style.
if (drawable.getLayerTweaker() != layerTweaker) {
return false;
}
drawable.setVertexAttributes(std::move(hillshadeVertexAttrs));
drawable.setVertexAttributes(buildVertexAttributes());
drawable.setVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
// Rebuild segments, since they're not shared.
@@ -526,9 +537,8 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
hillshadeBuilder->setDepthType(gfx::DepthMaskType::ReadOnly);
hillshadeBuilder->setColorMode(gfx::ColorMode::alphaBlended());
hillshadeBuilder->setCullFaceMode(gfx::CullFaceMode::disabled());
hillshadeBuilder->setRenderPass(renderPass);
hillshadeBuilder->setVertexAttributes(std::move(hillshadeVertexAttrs));
hillshadeBuilder->setVertexAttributes(buildVertexAttributes());
hillshadeBuilder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
hillshadeBuilder->setSegments(gfx::Triangles(), indices->vector(), segments->data(), segments->size());
@@ -536,7 +546,7 @@ void RenderHillshadeLayer::update(gfx::ShaderRegistry& shaders,
hillshadeBuilder->setTexture(bucket.renderTarget->getTexture(), *hillshadeImageLocation);
}
hillshadeBuilder->flush();
hillshadeBuilder->flush(context);
for (auto& drawable : hillshadeBuilder->clearDrawables()) {
drawable->setTileID(tileID);

View File

@@ -434,11 +434,11 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
};
auto addAttributes =
[&](gfx::DrawableBuilder& builder, const LineBucket& bucket, gfx::VertexAttributeArray&& vertexAttrs) {
[&](gfx::DrawableBuilder& builder, const LineBucket& bucket, gfx::VertexAttributeArrayPtr&& vertexAttrs) {
const auto vertexCount = bucket.vertices.elements();
builder.setRawVertices({}, vertexCount, gfx::AttributeDataType::Short4);
if (const auto& attr = vertexAttrs.add(idVertexAttribName)) {
if (const auto& attr = vertexAttrs->add(idVertexAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(LineLayoutVertex, a1),
/*vertexOffset=*/0,
@@ -446,7 +446,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
gfx::AttributeDataType::Short2);
}
if (const auto& attr = vertexAttrs.add(idDataAttribName)) {
if (const auto& attr = vertexAttrs->add(idDataAttribName)) {
attr->setSharedRawData(bucket.sharedVertices,
offsetof(LineLayoutVertex, a2),
/*vertexOffset=*/0,
@@ -584,14 +584,14 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
// dash array line (SDF)
propertiesAsUniforms.clear();
gfx::VertexAttributeArray vertexAttrs;
vertexAttrs.readDataDrivenPaintProperties<LineColor,
LineBlur,
LineOpacity,
LineGapWidth,
LineOffset,
LineWidth,
LineFloorWidth>(
auto vertexAttrs = context.createVertexAttributeArray();
vertexAttrs->readDataDrivenPaintProperties<LineColor,
LineBlur,
LineOpacity,
LineGapWidth,
LineOffset,
LineWidth,
LineFloorWidth>(
paintPropertyBinders, evaluated, propertiesAsUniforms);
auto shader = lineSDFShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
@@ -610,7 +610,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
setSegments(builder, bucket);
// finish
builder->flush();
builder->flush(context);
const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round ? LinePatternCap::Round
: LinePatternCap::Square;
for (auto& drawable : builder->clearDrawables()) {
@@ -633,10 +633,14 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade);
propertiesAsUniforms.clear();
gfx::VertexAttributeArray vertexAttrs;
vertexAttrs
.readDataDrivenPaintProperties<LineBlur, LineOpacity, LineOffset, LineGapWidth, LineWidth, LinePattern>(
paintPropertyBinders, evaluated, propertiesAsUniforms);
auto vertexAttrs = context.createVertexAttributeArray();
vertexAttrs->readDataDrivenPaintProperties<LineBlur,
LineOpacity,
LineOffset,
LineGapWidth,
LineWidth,
LinePattern>(
paintPropertyBinders, evaluated, propertiesAsUniforms);
auto shader = linePatternShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
if (!shader) {
@@ -670,7 +674,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
setSegments(builder, bucket);
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Pattern));
drawable->setTileID(tileID);
@@ -691,8 +695,8 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
// gradient line
propertiesAsUniforms.clear();
gfx::VertexAttributeArray vertexAttrs;
vertexAttrs.readDataDrivenPaintProperties<LineBlur, LineOpacity, LineGapWidth, LineOffset, LineWidth>(
auto vertexAttrs = context.createVertexAttributeArray();
vertexAttrs->readDataDrivenPaintProperties<LineBlur, LineOpacity, LineGapWidth, LineOffset, LineWidth>(
paintPropertyBinders, evaluated, propertiesAsUniforms);
auto shader = lineGradientShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
@@ -726,7 +730,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
setSegments(builder, bucket);
// finish
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Gradient));
drawable->setTileID(tileID);
@@ -746,9 +750,9 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
// simple line
propertiesAsUniforms.clear();
gfx::VertexAttributeArray vertexAttrs;
auto vertexAttrs = context.createVertexAttributeArray();
vertexAttrs
.readDataDrivenPaintProperties<LineColor, LineBlur, LineOpacity, LineGapWidth, LineOffset, LineWidth>(
->readDataDrivenPaintProperties<LineColor, LineBlur, LineOpacity, LineGapWidth, LineOffset, LineWidth>(
paintPropertyBinders, evaluated, propertiesAsUniforms);
auto shader = lineShaderGroup->getOrCreateShader(context, propertiesAsUniforms);
@@ -767,7 +771,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
setSegments(builder, bucket);
// finish
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setType(mbgl::underlying_type(LineLayerTweaker::LineType::Simple));
drawable->setTileID(tileID);

View File

@@ -341,11 +341,19 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
}
};
gfx::VertexAttributeArrayPtr staticAttrs;
// Build vertex attributes and apply them to a drawable or a builder.
// Populates a drawable xor a drawable builder for creates and updates, respectively.
// Returns false if the drawable must be re-created.
const auto buildVertexData =
[this](const gfx::UniqueDrawableBuilder& builder, gfx::Drawable* drawable, const RasterBucket& bucket) {
[&](const gfx::UniqueDrawableBuilder& builder, gfx::Drawable* drawable, const RasterBucket& bucket) {
// The bucket may later add, remove, or change masking. In that case, the tile's
// shared data and segments are not updated, and it needs to be re-created.
if (drawable && (bucket.sharedVertices->getDirty() || bucket.sharedTriangles->getDirty())) {
return false;
}
// The bucket only fills in geometry for masked tiles,
// otherwise the standard tile extent geometry should be used.
const bool shared = (!bucket.sharedVertices->empty() && !bucket.sharedTriangles->empty() &&
@@ -354,34 +362,33 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
const auto& indices = shared ? bucket.sharedTriangles : staticDataIndices;
const auto* segments = shared ? &bucket.segments : staticDataSegments.get();
// The bucket may later add, remove, or change masking. In that case, the tile's
// shared data and segments are not updated, and it needs to be re-created.
if (drawable && (bucket.sharedVertices->getDirty() || bucket.sharedTriangles->getDirty())) {
return false;
}
gfx::VertexAttributeArrayPtr bucketAttrs;
auto& vertexAttrs = shared ? bucketAttrs : staticAttrs;
if (!vertexAttrs) {
vertexAttrs = context.createVertexAttributeArray();
gfx::VertexAttributeArray vertexAttrs;
if (auto& attr = vertexAttrs.add(idPosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(RasterLayoutVertex, a1),
/*vertexOffset=*/0,
sizeof(RasterLayoutVertex),
gfx::AttributeDataType::Short2);
}
if (auto& attr = vertexAttrs->add(idPosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(RasterLayoutVertex, a1),
/*vertexOffset=*/0,
sizeof(RasterLayoutVertex),
gfx::AttributeDataType::Short2);
}
if (auto& attr = vertexAttrs.add(idTexturePosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(RasterLayoutVertex, a2),
/*vertexOffset=*/0,
sizeof(RasterLayoutVertex),
gfx::AttributeDataType::Short2);
if (auto& attr = vertexAttrs->add(idTexturePosAttribName)) {
attr->setSharedRawData(vertices,
offsetof(RasterLayoutVertex, a2),
/*vertexOffset=*/0,
sizeof(RasterLayoutVertex),
gfx::AttributeDataType::Short2);
}
}
assert(!!drawable ^ !!builder);
if (drawable) {
drawable->setVertexAttributes(std::move(vertexAttrs));
drawable->setVertexAttributes(vertexAttrs);
} else if (builder) {
builder->setVertexAttributes(std::move(vertexAttrs));
builder->setVertexAttributes(vertexAttrs);
builder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Short2);
builder->setSegments(gfx::Triangles(), indices, segments->data(), segments->size());
}
@@ -412,7 +419,7 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
setTextures(builder, bucket);
// finish
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setData(std::make_unique<gfx::ImageDrawableData>(matrix_));
@@ -481,11 +488,11 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
}
return true;
};
if (updateTile(renderPass, tileID, std::move(updateExisting))) {
// If we modified drawables without removing them, we're done with this tile.
// If we update existing drawables, don't build new ones.
// But if the geometry has changed, we need to drop and re-build them anyway.
if (updateTile(renderPass, tileID, std::move(updateExisting)) && !geometryChanged) {
continue;
} else if (geometryChanged) {
// If the geometry has changed, the drawable needs to be re-built
removeTile(renderPass, tileID);
}
}
@@ -502,7 +509,7 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
buildVertexData(builder, /*drawable=*/nullptr, bucket);
// finish
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
drawable->setLayerTweaker(layerTweaker);

View File

@@ -867,9 +867,9 @@ void updateTileDrawable(gfx::Drawable& drawable,
// TODO: detect whether anything has actually changed
// See `Placement::updateBucketDynamicVertices`
gfx::VertexAttributeArray attribs;
updateTileAttributes(buffer, isText, paintProps, evaluated, attribs, propertiesAsUniforms);
drawable.setVertexAttributes(std::move(attribs));
if (auto& attribs = drawable.getVertexAttributes()) {
updateTileAttributes(buffer, isText, paintProps, evaluated, *attribs, propertiesAsUniforms);
}
}
const StringIdentity idCollisionPosAttribName = stringIndexer().get("a_pos");
@@ -878,25 +878,26 @@ const StringIdentity idCollisionExtrudeAttribName = stringIndexer().get("a_extru
const StringIdentity idCollisionPlacedAttribName = stringIndexer().get("a_placed");
const StringIdentity idCollisionShiftAttribName = stringIndexer().get("a_shift");
gfx::VertexAttributeArray getCollisionVertexAttributes(const SymbolBucket::CollisionBuffer& buffer) {
gfx::VertexAttributeArray vertexAttrs;
gfx::VertexAttributeArrayPtr getCollisionVertexAttributes(gfx::Context& context,
const SymbolBucket::CollisionBuffer& buffer) {
auto vertexAttrs = context.createVertexAttributeArray();
using LayoutVertex = gfx::Vertex<CollisionBoxLayoutAttributes>;
if (const auto& attr = vertexAttrs.getOrAdd(idCollisionPosAttribName)) {
if (const auto& attr = vertexAttrs->add(idCollisionPosAttribName)) {
attr->setSharedRawData(buffer.sharedVertices,
offsetof(LayoutVertex, a1),
/*vertexOffset=*/0,
sizeof(LayoutVertex),
gfx::AttributeDataType::Short2);
}
if (const auto& attr = vertexAttrs.getOrAdd(idCollisionAnchorPosAttribName)) {
if (const auto& attr = vertexAttrs->add(idCollisionAnchorPosAttribName)) {
attr->setSharedRawData(buffer.sharedVertices,
offsetof(LayoutVertex, a2),
/*vertexOffset=*/0,
sizeof(LayoutVertex),
gfx::AttributeDataType::Short2);
}
if (const auto& attr = vertexAttrs.getOrAdd(idCollisionExtrudeAttribName)) {
if (const auto& attr = vertexAttrs->add(idCollisionExtrudeAttribName)) {
attr->setSharedRawData(buffer.sharedVertices,
offsetof(LayoutVertex, a3),
/*vertexOffset=*/0,
@@ -906,14 +907,14 @@ gfx::VertexAttributeArray getCollisionVertexAttributes(const SymbolBucket::Colli
using DynamicVertex = gfx::Vertex<CollisionBoxDynamicAttributes>;
if (const auto& attr = vertexAttrs.getOrAdd(idCollisionPlacedAttribName)) {
if (const auto& attr = vertexAttrs->add(idCollisionPlacedAttribName)) {
attr->setSharedRawData(buffer.sharedDynamicVertices,
offsetof(DynamicVertex, a1),
/*vertexOffset=*/0,
sizeof(DynamicVertex),
gfx::AttributeDataType::UShort2);
}
if (const auto& attr = vertexAttrs.getOrAdd(idCollisionShiftAttribName)) {
if (const auto& attr = vertexAttrs->add(idCollisionShiftAttribName)) {
attr->setSharedRawData(buffer.sharedDynamicVertices,
offsetof(DynamicVertex, a2),
/*vertexOffset=*/0,
@@ -1109,12 +1110,12 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
collisionBuilder->setDrawableName(layerCollisionPrefix + suffix + "box");
collisionBuilder->setShader(shader);
addVertices(collisionBox->vertices().vector());
collisionBuilder->setVertexAttributes(getCollisionVertexAttributes(*collisionBox));
collisionBuilder->setVertexAttributes(getCollisionVertexAttributes(context, *collisionBox));
collisionBuilder->setSegments(gfx::Lines(1.0f),
collisionBox->sharedLines,
collisionBox->segments.data(),
collisionBox->segments.size());
collisionBuilder->flush();
collisionBuilder->flush(context);
}
}
@@ -1126,12 +1127,12 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
collisionBuilder->setDrawableName(layerCollisionPrefix + suffix + "circle");
collisionBuilder->setShader(shader);
addVertices(collisionCircle->vertices().vector());
collisionBuilder->setVertexAttributes(getCollisionVertexAttributes(*collisionCircle));
collisionBuilder->setVertexAttributes(getCollisionVertexAttributes(context, *collisionCircle));
collisionBuilder->setSegments(gfx::Triangles(),
collisionCircle->sharedTriangles,
collisionCircle->segments.data(),
collisionCircle->segments.size());
collisionBuilder->flush();
collisionBuilder->flush(context);
}
}
@@ -1258,8 +1259,8 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
const auto vertexCount = buffer.vertices().elements();
propertiesAsUniforms.clear();
gfx::VertexAttributeArray attribs;
updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, attribs, propertiesAsUniforms);
auto attribs = context.createVertexAttributeArray();
updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, *attribs, propertiesAsUniforms);
const auto textHalo = evaluated.get<style::TextHaloColor>().constantOr(Color::black()).a > 0.0f &&
evaluated.get<style::TextHaloWidth>().constantOr(1);
@@ -1342,7 +1343,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
builder->setSegments(gfx::Triangles(), buffer.sharedTriangles, &renderable.segment.get(), 1);
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);

View File

@@ -175,7 +175,7 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
debugBuilder->setTexture(texture, samplerLocation.value());
// finish
debugBuilder->flush();
debugBuilder->flush(context);
for (auto& drawable : debugBuilder->clearDrawables()) {
drawable->setTileID(tileID);
auto& uniforms = drawable->mutableUniformBuffers();
@@ -282,7 +282,7 @@ void TileSourceRenderItem::updateDebugDrawables(DebugLayerGroupMap& debugLayerGr
auto tweaker = std::make_shared<PolylineDrawableTweaker>(linePropertiesUBO);
// finish
polylineBuilder->flush();
polylineBuilder->flush(context);
for (auto& drawable : polylineBuilder->clearDrawables()) {
drawable->setTileID(tile.getOverscaledTileID());
drawable->addTweaker(tweaker);

View File

@@ -302,8 +302,9 @@ void CustomDrawableLayerHost::Interface::addFill(const GeometryCollection& geome
// add to builder
static const StringIdentity idVertexAttribName = stringIndexer().get("a_pos");
builder->setVertexAttrNameId(idVertexAttribName);
gfx::VertexAttributeArray attrs;
if (const auto& attr = attrs.add(idVertexAttribName)) {
auto attrs = context.createVertexAttributeArray();
if (const auto& attr = attrs->add(idVertexAttribName)) {
attr->setSharedRawData(sharedVertices,
offsetof(FillLayoutVertex, a1),
/*vertexOffset=*/0,
@@ -315,14 +316,14 @@ void CustomDrawableLayerHost::Interface::addFill(const GeometryCollection& geome
builder->setSegments(gfx::Triangles(), sharedTriangles, triangleSegments.data(), triangleSegments.size());
// flush current builder drawable
builder->flush();
builder->flush(context);
}
void CustomDrawableLayerHost::Interface::finish() {
if (builder && !builder->empty()) {
// finish
const auto finish_ = [this](auto& tweaker) {
builder->flush();
builder->flush(context);
for (auto& drawable : builder->clearDrawables()) {
assert(tileID.has_value());
drawable->setTileID(tileID.value());