Use timestamps for attribute updates (#2629)
This commit is contained in:
@@ -5,9 +5,10 @@
|
||||
#include <mbgl/gfx/uniform_buffer.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/identity.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
#include <mbgl/util/containers.hpp>
|
||||
#include <mbgl/util/identity.hpp>
|
||||
#include <mbgl/util/monotonic_timer.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
@@ -244,6 +245,8 @@ public:
|
||||
/// Set origin point
|
||||
void setOrigin(std::optional<Point<double>> p) { origin = std::move(p); }
|
||||
|
||||
const std::chrono::duration<double> createTime = util::MonotonicTimer::now();
|
||||
|
||||
protected:
|
||||
bool enabled = true;
|
||||
bool enableColor = true;
|
||||
@@ -264,6 +267,7 @@ protected:
|
||||
UniqueDrawableData drawableData{};
|
||||
gfx::VertexAttributeArrayPtr vertexAttributes;
|
||||
gfx::VertexAttributeArrayPtr instanceAttributes;
|
||||
std::chrono::duration<double> attributeUpdateTime = util::MonotonicTimer::now();
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
void setIndex(int value) { index = value; }
|
||||
|
||||
/// @brief Get the stride of the vertex attribute
|
||||
std::size_t getStride() const { return stride; }
|
||||
virtual std::size_t getStride() const { return stride; }
|
||||
void setStride(std::size_t value) { stride = value; }
|
||||
|
||||
/// @brief Get the count of vertex attribute items
|
||||
@@ -180,12 +180,16 @@ public:
|
||||
items.clear();
|
||||
}
|
||||
|
||||
/// @brief Get dirty state
|
||||
bool isDirty() const { return dirty; }
|
||||
|
||||
/// @brief Set dirty state
|
||||
void setDirty(bool value = true) { dirty = value; }
|
||||
|
||||
bool isModifiedAfter(std::chrono::duration<double> time) const {
|
||||
if (sharedRawData) {
|
||||
return sharedRawData->isModifiedAfter(time);
|
||||
}
|
||||
return dirty;
|
||||
}
|
||||
|
||||
template <std::size_t I = 0, typename... Tp>
|
||||
inline typename std::enable_if<I == sizeof...(Tp), void>::type set(std::size_t, std::tuple<Tp...>, std::size_t) {}
|
||||
|
||||
@@ -255,6 +259,9 @@ protected:
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class VertexAttributeArray;
|
||||
bool isDirty() const { return dirty; }
|
||||
|
||||
int index;
|
||||
std::size_t stride;
|
||||
|
||||
@@ -310,8 +317,9 @@ public:
|
||||
std::size_t count = 0);
|
||||
|
||||
/// Indicates whether any values have changed
|
||||
virtual bool isDirty() const {
|
||||
return std::any_of(attrs.begin(), attrs.end(), [](const auto& attr) { return attr && attr->isDirty(); });
|
||||
bool isModifiedAfter(std::chrono::duration<double> time) const {
|
||||
return std::any_of(
|
||||
attrs.begin(), attrs.end(), [&](const auto& attr) { return attr && attr->isModifiedAfter(time); });
|
||||
}
|
||||
|
||||
/// Clear the collection
|
||||
@@ -328,11 +336,17 @@ public:
|
||||
}
|
||||
|
||||
/// Call the provided delegate with each value, providing the override if one exists.
|
||||
template <typename Func /* void(const size_t, VertexAttribute&, const std::unique_ptr<VertexAttribute>&) */>
|
||||
void resolve(const VertexAttributeArray& overrides, Func delegate) const {
|
||||
/// @param foundDelegate Called for each attribute in `default`, with the corresponding override, if present
|
||||
/// @param missingDelegate Called for any overrides with no corresponding default
|
||||
template <typename ResolveFunc /* void(const size_t, VertexAttribute&, const std::unique_ptr<VertexAttribute>&) */,
|
||||
typename MissingFunc /* void(const size_t, const std::unique_ptr<VertexAttribute>&) */>
|
||||
void resolve(const VertexAttributeArray& overrides, ResolveFunc foundDelegate, MissingFunc missingDelegate) const {
|
||||
for (size_t id = 0; id < attrs.size(); id++) {
|
||||
const auto& override = overrides.get(id);
|
||||
if (const auto& attr = attrs[id]) {
|
||||
delegate(id, *attr, overrides.get(id));
|
||||
foundDelegate(id, *attr, override);
|
||||
} else if (override) {
|
||||
missingDelegate(id, override);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +31,11 @@ public:
|
||||
bool getNormalized() const { return normalized; }
|
||||
void setNormalized(bool value) { normalized = value; }
|
||||
|
||||
std::size_t getStride() const;
|
||||
std::size_t getStride() const override;
|
||||
|
||||
static const std::vector<std::uint8_t>& getRaw(gfx::VertexAttribute& attr, platform::GLenum);
|
||||
static const std::vector<std::uint8_t>& getRaw(gfx::VertexAttribute& attr,
|
||||
platform::GLenum,
|
||||
std::chrono::duration<double> lastUpdate);
|
||||
|
||||
private:
|
||||
static int getSize(platform::GLenum glType);
|
||||
@@ -58,9 +60,6 @@ public:
|
||||
}
|
||||
VertexAttributeArrayGL& operator=(const VertexAttributeArrayGL&) = delete;
|
||||
|
||||
/// Indicates whether any values have changed
|
||||
bool isDirty() const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<gfx::VertexAttribute> create(int index,
|
||||
gfx::AttributeDataType dataType,
|
||||
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
const gfx::VertexAttributeArray& defaults,
|
||||
const gfx::VertexAttributeArray& overrides,
|
||||
gfx::BufferUsageType,
|
||||
const std::chrono::duration<double> lastUpdate,
|
||||
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>& outBuffers) override;
|
||||
|
||||
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
VertexAttributeArray& operator=(const VertexAttributeArray& other) = delete;
|
||||
|
||||
/// Indicates whether any values have changed
|
||||
bool isDirty() const override;
|
||||
bool isModifiedAfter(std::chrono::duration<double> time) const;
|
||||
|
||||
private:
|
||||
gfx::UniqueVertexAttribute create(int index, gfx::AttributeDataType dataType, std::size_t count) const override {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/mtl/buffer_resource.hpp>
|
||||
#include <mbgl/util/monotonic_timer.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -21,8 +22,12 @@ public:
|
||||
BufferResource& get() noexcept { return buffer; }
|
||||
const BufferResource& get() const noexcept { return buffer; }
|
||||
|
||||
std::chrono::duration<double> getLastUpdated() const { return lastUpdated; }
|
||||
void setLastUpdated(std::chrono::duration<double> time) { lastUpdated = time; }
|
||||
|
||||
protected:
|
||||
BufferResource buffer;
|
||||
std::chrono::duration<double> lastUpdated;
|
||||
};
|
||||
|
||||
using UniqueVertexBufferResource = std::unique_ptr<VertexBufferResource>;
|
||||
|
||||
@@ -25,12 +25,12 @@ const void* castGpuIdToTracyPtr(GpuId id) {
|
||||
"MLN_RENDER_BACKEND_OPENGL is not defined. MLN_RENDER_BACKEND_OPENGL is expected to be defined in CMake and Bazel"
|
||||
#endif
|
||||
|
||||
#define MLN_TRACE_FUNC() ZoneScoped;
|
||||
#define MLN_TRACE_ZONE(label) ZoneScopedN(#label);
|
||||
#define MLN_TRACE_FUNC() ZoneScoped
|
||||
#define MLN_TRACE_ZONE(label) ZoneScopedN(#label)
|
||||
|
||||
#define MLN_ZONE_TEXT(label) ZoneText(#label, strlen(#label));
|
||||
#define MLN_ZONE_STR(str) ZoneText(str.c_str(), str.size());
|
||||
#define MLN_ZONE_VALUE(val) ZoneValue(static_cast<uint64_t>(val));
|
||||
#define MLN_ZONE_TEXT(text, size) ZoneText(text, size)
|
||||
#define MLN_ZONE_STR(str) ZoneText(str.c_str(), str.size())
|
||||
#define MLN_ZONE_VALUE(n) ZoneValue(n)
|
||||
|
||||
constexpr const char* tracyTextureMemoryLabel = "Texture Memory";
|
||||
#define MLN_TRACE_ALLOC_TEXTURE(id, size) TracyAllocN(castGpuIdToTracyPtr(id), size, tracyTextureMemoryLabel);
|
||||
@@ -119,4 +119,4 @@ constexpr const char* tracyConstMemoryLabel = "Constant Buffer Memory";
|
||||
#define MLN_TRACE_FUNC()
|
||||
#define MLN_TRACE_ZONE(label)
|
||||
|
||||
#endif // MLN_TRACY_ENABLE
|
||||
#endif // MLN_TRACY_ENABLE
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
const gfx::VertexAttributeArray& defaults,
|
||||
const gfx::VertexAttributeArray& overrides,
|
||||
gfx::BufferUsageType,
|
||||
const std::chrono::duration<double> lastUpdate,
|
||||
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>& outBuffers) override;
|
||||
|
||||
std::unique_ptr<gfx::TextureResource> createTextureResource(Size,
|
||||
|
||||
@@ -39,9 +39,6 @@ public:
|
||||
}
|
||||
VertexAttributeArray& operator=(const VertexAttributeArray& other) = delete;
|
||||
|
||||
/// Indicates whether any values have changed
|
||||
bool isDirty() const override;
|
||||
|
||||
private:
|
||||
gfx::UniqueVertexAttribute create(int index, gfx::AttributeDataType dataType, std::size_t count) const override {
|
||||
return std::make_unique<VertexAttribute>(index, dataType, count);
|
||||
|
||||
@@ -22,8 +22,12 @@ public:
|
||||
BufferResource& get() noexcept { return buffer; }
|
||||
const BufferResource& get() const noexcept { return buffer; }
|
||||
|
||||
std::chrono::duration<double> getLastUpdated() const { return lastUpdated; }
|
||||
void setLastUpdated(std::chrono::duration<double> time) { lastUpdated = time; }
|
||||
|
||||
protected:
|
||||
BufferResource buffer;
|
||||
std::chrono::duration<double> lastUpdated;
|
||||
};
|
||||
|
||||
using UniqueVertexBufferResource = std::unique_ptr<VertexBufferResource>;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/gfx/draw_mode.hpp>
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
#include <mbgl/util/monotonic_timer.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -40,8 +41,15 @@ public:
|
||||
void setBuffer(std::unique_ptr<IndexBufferBase>&& value) { buffer = std::move(value); }
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
bool getDirty() const { return dirty; }
|
||||
void setDirty(bool value = true) { dirty = value; }
|
||||
std::chrono::duration<double> getLastModified() const { return lastModified; }
|
||||
bool isModifiedAfter(std::chrono::duration<double> t) const { return t < lastModified; }
|
||||
|
||||
void updateModified() {
|
||||
if (dirty) {
|
||||
lastModified = util::MonotonicTimer::now();
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isReleased() const { return released; }
|
||||
|
||||
@@ -99,6 +107,8 @@ protected:
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
bool dirty = true;
|
||||
bool released = false;
|
||||
|
||||
std::chrono::duration<double> lastModified = util::MonotonicTimer::now();
|
||||
};
|
||||
|
||||
using IndexVectorBasePtr = std::shared_ptr<IndexVectorBase>;
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
const gfx::VertexAttributeArray& defaults,
|
||||
const gfx::VertexAttributeArray& overrides,
|
||||
gfx::BufferUsageType,
|
||||
const std::chrono::duration<double> lastUpdate,
|
||||
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>& outBuffers) = 0;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
#include <mbgl/util/monotonic_timer.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -35,9 +36,17 @@ public:
|
||||
void setBuffer(std::unique_ptr<VertexBufferBase>&& value) { buffer = std::move(value); }
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
bool getDirty() const { return dirty; }
|
||||
void setDirty(bool value = true) { dirty = value; }
|
||||
std::chrono::duration<double> getLastModified() const { return lastModified; }
|
||||
bool isModifiedAfter(std::chrono::duration<double> t) const { return t < lastModified; }
|
||||
|
||||
void updateModified() {
|
||||
if (dirty) {
|
||||
lastModified = util::MonotonicTimer::now();
|
||||
dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Indicates that the owner/producer will not modify this again
|
||||
bool isReleased() const { return released; }
|
||||
|
||||
protected:
|
||||
@@ -46,6 +55,8 @@ protected:
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
bool dirty = true;
|
||||
bool released = false;
|
||||
|
||||
std::chrono::duration<double> lastModified = util::MonotonicTimer::now();
|
||||
};
|
||||
using VertexVectorBasePtr = std::shared_ptr<VertexVectorBase>;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <mbgl/gl/vertex_buffer_resource.hpp>
|
||||
#include <mbgl/programs/segment.hpp>
|
||||
#include <mbgl/shaders/gl/shader_program_gl.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -22,6 +23,8 @@ DrawableGL::~DrawableGL() {
|
||||
}
|
||||
|
||||
void DrawableGL::draw(PaintParameters& parameters) const {
|
||||
MLN_TRACE_FUNC();
|
||||
|
||||
if (isCustom) {
|
||||
return;
|
||||
}
|
||||
@@ -147,13 +150,22 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
|
||||
return;
|
||||
}
|
||||
|
||||
MLN_TRACE_FUNC();
|
||||
#ifdef MLN_TRACY_ENABLE
|
||||
{
|
||||
auto str = name + "/" + (tileID ? util::toString(*tileID) : std::string());
|
||||
MLN_ZONE_STR(str);
|
||||
}
|
||||
#endif
|
||||
|
||||
const bool build = vertexAttributes &&
|
||||
(vertexAttributes->isDirty() ||
|
||||
(vertexAttributes->isModifiedAfter(attributeUpdateTime) ||
|
||||
std::any_of(impl->segments.begin(), impl->segments.end(), [](const auto& seg) {
|
||||
return !static_cast<const DrawSegmentGL&>(*seg).getVertexArray().isValid();
|
||||
}));
|
||||
|
||||
if (build) {
|
||||
MLN_TRACE_ZONE(build attributes);
|
||||
auto& context = uploadPass.getContext();
|
||||
auto& glContext = static_cast<gl::Context&>(context);
|
||||
constexpr auto usage = gfx::BufferUsageType::StaticDraw;
|
||||
@@ -173,11 +185,16 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
|
||||
defaults,
|
||||
overrides,
|
||||
usage,
|
||||
attributeUpdateTime,
|
||||
vertexBuffers);
|
||||
|
||||
impl->attributeBuffers = std::move(vertexBuffers);
|
||||
|
||||
if (impl->indexes->getDirty()) {
|
||||
if (impl->indexes) {
|
||||
impl->indexes->updateModified();
|
||||
}
|
||||
if (!impl->indexes->getBuffer() || impl->indexes->isModifiedAfter(attributeUpdateTime)) {
|
||||
MLN_TRACE_ZONE(build indexes);
|
||||
auto indexBufferResource{
|
||||
uploadPass.createIndexBufferResource(impl->indexes->data(), impl->indexes->bytes(), usage)};
|
||||
auto indexBuffer = std::make_unique<gfx::IndexBuffer>(impl->indexes->elements(),
|
||||
@@ -185,11 +202,11 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
|
||||
auto buffer = std::make_unique<IndexBufferGL>(std::move(indexBuffer));
|
||||
|
||||
impl->indexes->setBuffer(std::move(buffer));
|
||||
impl->indexes->setDirty(false);
|
||||
}
|
||||
|
||||
// Create a VAO for each group of vertexes described by a segment
|
||||
for (const auto& seg : impl->segments) {
|
||||
MLN_TRACE_ZONE(segment);
|
||||
auto& glSeg = static_cast<DrawSegmentGL&>(*seg);
|
||||
const auto& mlSeg = glSeg.getSegment();
|
||||
|
||||
@@ -212,7 +229,9 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
|
||||
glSeg.setVertexArray(std::move(vertexArray));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
attributeUpdateTime = util::MonotonicTimer::now();
|
||||
}
|
||||
|
||||
const bool texturesNeedUpload = std::any_of(
|
||||
@@ -238,6 +257,7 @@ gfx::StencilMode DrawableGL::makeStencilMode(PaintParameters& parameters) const
|
||||
}
|
||||
|
||||
void DrawableGL::uploadTextures() const {
|
||||
MLN_TRACE_FUNC();
|
||||
for (const auto& texture : textures) {
|
||||
if (texture) {
|
||||
texture->upload();
|
||||
|
||||
@@ -21,6 +21,9 @@ TileLayerGroupGL::TileLayerGroupGL(int32_t layerIndex_, std::size_t initialCapac
|
||||
: TileLayerGroup(layerIndex_, initialCapacity, std::move(name_)) {}
|
||||
|
||||
void TileLayerGroupGL::upload(gfx::UploadPass& uploadPass) {
|
||||
MLN_TRACE_FUNC();
|
||||
MLN_ZONE_STR(name);
|
||||
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <mbgl/gl/vertex_buffer_resource.hpp>
|
||||
#include <mbgl/gl/index_buffer_resource.hpp>
|
||||
#include <mbgl/gl/texture_resource.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
@@ -43,7 +44,7 @@ std::unique_ptr<gfx::VertexBufferResource> UploadPass::createVertexBufferResourc
|
||||
}
|
||||
|
||||
void UploadPass::updateVertexBufferResource(gfx::VertexBufferResource& resource, const void* data, std::size_t size) {
|
||||
commandEncoder.context.vertexBuffer = static_cast<gl::VertexBufferResource&>(resource).buffer;
|
||||
commandEncoder.context.vertexBuffer = static_cast<gl::VertexBufferResource&>(resource).getBuffer();
|
||||
MBGL_CHECK_ERROR(glBufferSubData(GL_ARRAY_BUFFER, 0, size, data));
|
||||
}
|
||||
|
||||
@@ -151,11 +152,12 @@ const gfx::UniqueVertexBufferResource& UploadPass::getBuffer(const gfx::VertexVe
|
||||
if (auto* rawData = static_cast<VertexBufferGL*>(vec->getBuffer()); rawData && rawData->resource) {
|
||||
auto& resource = static_cast<gl::VertexBufferResource&>(*rawData->resource);
|
||||
|
||||
// If it's changed, update it
|
||||
if (rawBufSize <= resource.byteSize) {
|
||||
if (vec->getDirty()) {
|
||||
// If the already-allocated buffer is large enough, we can re-use it
|
||||
if (rawBufSize <= resource.getByteSize()) {
|
||||
// If the source changed, update the buffer contents
|
||||
if (vec->isModifiedAfter(resource.getLastUpdated())) {
|
||||
updateVertexBufferResource(resource, rawBufPtr, rawBufSize);
|
||||
vec->setDirty(false);
|
||||
resource.setLastUpdated(vec->getLastModified());
|
||||
}
|
||||
return rawData->resource;
|
||||
}
|
||||
@@ -165,7 +167,6 @@ const gfx::UniqueVertexBufferResource& UploadPass::getBuffer(const gfx::VertexVe
|
||||
auto buffer = std::make_unique<VertexBufferGL>();
|
||||
buffer->resource = createVertexBufferResource(rawBufPtr, rawBufSize, usage, /*persistent=*/false);
|
||||
vec->setBuffer(std::move(buffer));
|
||||
vec->setDirty(false);
|
||||
return static_cast<VertexBufferGL*>(vec->getBuffer())->resource;
|
||||
}
|
||||
}
|
||||
@@ -190,7 +191,9 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
const gfx::VertexAttributeArray& defaults,
|
||||
const gfx::VertexAttributeArray& overrides,
|
||||
const gfx::BufferUsageType usage,
|
||||
const std::chrono::duration<double> lastUpdate,
|
||||
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>& outBuffers) {
|
||||
MLN_TRACE_FUNC();
|
||||
AttributeBindingArray bindings;
|
||||
bindings.resize(defaults.allocatedSize());
|
||||
|
||||
@@ -217,6 +220,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
|
||||
// For each attribute in the program, with the corresponding default and optional override...
|
||||
const auto resolveAttr = [&](const size_t id, auto& defaultAttr, auto& overrideAttr) -> void {
|
||||
MLN_TRACE_ZONE(binding);
|
||||
auto& effectiveAttr = overrideAttr ? *overrideAttr : defaultAttr;
|
||||
const auto& defaultGL = static_cast<const VertexAttributeGL&>(defaultAttr);
|
||||
const auto stride = defaultAttr.getStride();
|
||||
@@ -245,10 +249,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
}
|
||||
|
||||
// Get the raw data for the values in the desired format
|
||||
const auto& rawData = VertexAttributeGL::getRaw(effectiveAttr, defaultGL.getGLType());
|
||||
if (rawData.empty()) {
|
||||
VertexAttributeGL::getRaw(effectiveAttr, defaultGL.getGLType());
|
||||
}
|
||||
const auto& rawData = VertexAttributeGL::getRaw(effectiveAttr, defaultGL.getGLType(), lastUpdate);
|
||||
|
||||
if (rawData.size() == stride * vertexCount) {
|
||||
// The override provided a value for each vertex, append it as-is
|
||||
@@ -268,6 +269,8 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
return;
|
||||
}
|
||||
|
||||
overrideAttr->setDirty(false);
|
||||
|
||||
bindings[index] = {
|
||||
/*.attribute = */ {defaultAttr.getDataType(), offset},
|
||||
/* vertexStride = */ static_cast<uint32_t>(stride),
|
||||
@@ -280,7 +283,11 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
// The vertex stride is the sum of the attribute strides
|
||||
vertexStride += static_cast<uint32_t>(stride);
|
||||
};
|
||||
defaults.resolve(overrides, resolveAttr);
|
||||
// This version is called when the attribute is available, but isn't being used by the shader
|
||||
const auto missingAttr = [&](const size_t, auto& missingAttr) -> void {
|
||||
missingAttr->setDirty(false);
|
||||
};
|
||||
defaults.resolve(overrides, resolveAttr, missingAttr);
|
||||
|
||||
assert(vertexStride * vertexCount <= allData.size());
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
const gfx::VertexAttributeArray& defaults,
|
||||
const gfx::VertexAttributeArray& overrides,
|
||||
gfx::BufferUsageType,
|
||||
const std::chrono::duration<double> lastUpdate,
|
||||
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>& outBuffers) override;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mbgl/gl/vertex_buffer_resource.hpp>
|
||||
#include <mbgl/gl/defines.hpp>
|
||||
#include <mbgl/gl/enum.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
@@ -13,10 +14,14 @@ using namespace platform;
|
||||
const constexpr ClearDepth::Type ClearDepth::Default;
|
||||
|
||||
void ClearDepth::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(ClearDepth::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glClearDepthf(value));
|
||||
}
|
||||
|
||||
ClearDepth::Type ClearDepth::Get() {
|
||||
MLN_TRACE_ZONE(ClearDepth::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLfloat clearDepth;
|
||||
MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth));
|
||||
return clearDepth;
|
||||
@@ -25,10 +30,14 @@ ClearDepth::Type ClearDepth::Get() {
|
||||
const ClearColor::Type ClearColor::Default{0, 0, 0, 0};
|
||||
|
||||
void ClearColor::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(ClearColor::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glClearColor(value.r, value.g, value.b, value.a));
|
||||
}
|
||||
|
||||
ClearColor::Type ClearColor::Get() {
|
||||
MLN_TRACE_ZONE(ClearColor::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLfloat clearColor[4];
|
||||
MBGL_CHECK_ERROR(glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor));
|
||||
return {clearColor[0], clearColor[1], clearColor[2], clearColor[3]};
|
||||
@@ -37,10 +46,14 @@ ClearColor::Type ClearColor::Get() {
|
||||
const constexpr ClearStencil::Type ClearStencil::Default;
|
||||
|
||||
void ClearStencil::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(ClearStencil::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glClearStencil(value));
|
||||
}
|
||||
|
||||
ClearStencil::Type ClearStencil::Get() {
|
||||
MLN_TRACE_ZONE(ClearStencil::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint clearStencil;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil));
|
||||
return clearStencil;
|
||||
@@ -49,10 +62,14 @@ ClearStencil::Type ClearStencil::Get() {
|
||||
const constexpr StencilMask::Type StencilMask::Default;
|
||||
|
||||
void StencilMask::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(StencilMask::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glStencilMask(value));
|
||||
}
|
||||
|
||||
StencilMask::Type StencilMask::Get() {
|
||||
MLN_TRACE_ZONE(StencilMask::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint stencilMask;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_WRITEMASK, &stencilMask));
|
||||
return stencilMask;
|
||||
@@ -61,10 +78,14 @@ StencilMask::Type StencilMask::Get() {
|
||||
const constexpr DepthMask::Type DepthMask::Default;
|
||||
|
||||
void DepthMask::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(DepthMask::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glDepthMask(Enum<gfx::DepthMaskType>::to(value)));
|
||||
}
|
||||
|
||||
DepthMask::Type DepthMask::Get() {
|
||||
MLN_TRACE_ZONE(DepthMask::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLboolean depthMask;
|
||||
MBGL_CHECK_ERROR(glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask));
|
||||
return Enum<gfx::DepthMaskType>::from(depthMask);
|
||||
@@ -73,10 +94,14 @@ DepthMask::Type DepthMask::Get() {
|
||||
const constexpr ColorMask::Type ColorMask::Default;
|
||||
|
||||
void ColorMask::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(ColorMask::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glColorMask(value.r, value.g, value.b, value.a));
|
||||
}
|
||||
|
||||
ColorMask::Type ColorMask::Get() {
|
||||
MLN_TRACE_ZONE(ColorMask::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLboolean bools[4];
|
||||
MBGL_CHECK_ERROR(glGetBooleanv(GL_COLOR_WRITEMASK, bools));
|
||||
return {static_cast<bool>(bools[0]),
|
||||
@@ -88,10 +113,14 @@ ColorMask::Type ColorMask::Get() {
|
||||
const constexpr StencilFunc::Type StencilFunc::Default;
|
||||
|
||||
void StencilFunc::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(StencilFunc::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glStencilFunc(Enum<gfx::StencilFunctionType>::to(value.func), value.ref, value.mask));
|
||||
}
|
||||
|
||||
StencilFunc::Type StencilFunc::Get() {
|
||||
MLN_TRACE_ZONE(StencilFunc::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint func;
|
||||
GLint ref;
|
||||
GLint mask;
|
||||
@@ -104,10 +133,14 @@ StencilFunc::Type StencilFunc::Get() {
|
||||
const constexpr StencilTest::Type StencilTest::Default;
|
||||
|
||||
void StencilTest::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(StencilTest::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(value ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST));
|
||||
}
|
||||
|
||||
StencilTest::Type StencilTest::Get() {
|
||||
MLN_TRACE_ZONE(StencilTest::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
Type stencilTest;
|
||||
MBGL_CHECK_ERROR(stencilTest = glIsEnabled(GL_STENCIL_TEST));
|
||||
return stencilTest;
|
||||
@@ -116,12 +149,16 @@ StencilTest::Type StencilTest::Get() {
|
||||
const constexpr StencilOp::Type StencilOp::Default;
|
||||
|
||||
void StencilOp::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(StencilOp::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glStencilOp(Enum<gfx::StencilOpType>::to(value.sfail),
|
||||
Enum<gfx::StencilOpType>::to(value.dpfail),
|
||||
Enum<gfx::StencilOpType>::to(value.dppass)));
|
||||
}
|
||||
|
||||
StencilOp::Type StencilOp::Get() {
|
||||
MLN_TRACE_ZONE(StencilOp::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint sfail;
|
||||
GLint dpfail;
|
||||
GLint dppass;
|
||||
@@ -137,10 +174,14 @@ StencilOp::Type StencilOp::Get() {
|
||||
const constexpr DepthRange::Type DepthRange::Default;
|
||||
|
||||
void DepthRange::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(DepthRange::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glDepthRangef(value.min, value.max));
|
||||
}
|
||||
|
||||
DepthRange::Type DepthRange::Get() {
|
||||
MLN_TRACE_ZONE(DepthRange::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLfloat floats[2];
|
||||
MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_RANGE, floats));
|
||||
return {floats[0], floats[1]};
|
||||
@@ -150,10 +191,14 @@ DepthRange::Type DepthRange::Get() {
|
||||
const constexpr DepthTest::Type DepthTest::Default;
|
||||
|
||||
void DepthTest::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(DepthTest::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(value ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST));
|
||||
}
|
||||
|
||||
DepthTest::Type DepthTest::Get() {
|
||||
MLN_TRACE_ZONE(DepthTest::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
Type depthTest;
|
||||
MBGL_CHECK_ERROR(depthTest = glIsEnabled(GL_DEPTH_TEST));
|
||||
return depthTest;
|
||||
@@ -162,10 +207,14 @@ DepthTest::Type DepthTest::Get() {
|
||||
const constexpr DepthFunc::Type DepthFunc::Default;
|
||||
|
||||
void DepthFunc::Set(const DepthFunc::Type& value) {
|
||||
MLN_TRACE_ZONE(DepthFunc::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glDepthFunc(Enum<gfx::DepthFunctionType>::to(value)));
|
||||
}
|
||||
|
||||
DepthFunc::Type DepthFunc::Get() {
|
||||
MLN_TRACE_ZONE(DepthFunc::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint depthFunc;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_DEPTH_FUNC, &depthFunc));
|
||||
return Enum<gfx::DepthFunctionType>::from(depthFunc);
|
||||
@@ -174,10 +223,14 @@ DepthFunc::Type DepthFunc::Get() {
|
||||
const constexpr Blend::Type Blend::Default;
|
||||
|
||||
void Blend::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(Blend::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(value ? glEnable(GL_BLEND) : glDisable(GL_BLEND));
|
||||
}
|
||||
|
||||
Blend::Type Blend::Get() {
|
||||
MLN_TRACE_ZONE(Blend::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
Type blend;
|
||||
MBGL_CHECK_ERROR(blend = glIsEnabled(GL_BLEND));
|
||||
return blend;
|
||||
@@ -186,10 +239,14 @@ Blend::Type Blend::Get() {
|
||||
const constexpr BlendEquation::Type BlendEquation::Default;
|
||||
|
||||
void BlendEquation::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BlendEquation::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBlendEquation(Enum<gfx::ColorBlendEquationType>::to(value)));
|
||||
}
|
||||
|
||||
BlendEquation::Type BlendEquation::Get() {
|
||||
MLN_TRACE_ZONE(BlendEquation::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint blend;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_EQUATION_RGB, &blend));
|
||||
return Enum<gfx::ColorBlendEquationType>::from(blend);
|
||||
@@ -198,11 +255,15 @@ BlendEquation::Type BlendEquation::Get() {
|
||||
const constexpr BlendFunc::Type BlendFunc::Default;
|
||||
|
||||
void BlendFunc::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BlendFunc::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBlendFunc(Enum<gfx::ColorBlendFactorType>::to(value.sfactor),
|
||||
Enum<gfx::ColorBlendFactorType>::to(value.dfactor)));
|
||||
}
|
||||
|
||||
BlendFunc::Type BlendFunc::Get() {
|
||||
MLN_TRACE_ZONE(BlendFunc::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint sfactor;
|
||||
GLint dfactor;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_SRC_ALPHA, &sfactor));
|
||||
@@ -213,10 +274,14 @@ BlendFunc::Type BlendFunc::Get() {
|
||||
const BlendColor::Type BlendColor::Default{0, 0, 0, 0};
|
||||
|
||||
void BlendColor::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BlendColor::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBlendColor(value.r, value.g, value.b, value.a));
|
||||
}
|
||||
|
||||
BlendColor::Type BlendColor::Get() {
|
||||
MLN_TRACE_ZONE(BlendColor::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLfloat floats[4];
|
||||
MBGL_CHECK_ERROR(glGetFloatv(GL_BLEND_COLOR, floats));
|
||||
return {floats[0], floats[1], floats[2], floats[3]};
|
||||
@@ -225,10 +290,14 @@ BlendColor::Type BlendColor::Get() {
|
||||
const constexpr Program::Type Program::Default;
|
||||
|
||||
void Program::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(Program::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glUseProgram(value));
|
||||
}
|
||||
|
||||
Program::Type Program::Get() {
|
||||
MLN_TRACE_ZONE(Program::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint program;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_CURRENT_PROGRAM, &program));
|
||||
return program;
|
||||
@@ -237,10 +306,14 @@ Program::Type Program::Get() {
|
||||
const constexpr LineWidth::Type LineWidth::Default;
|
||||
|
||||
void LineWidth::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(LineWidth::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glLineWidth(value));
|
||||
}
|
||||
|
||||
LineWidth::Type LineWidth::Get() {
|
||||
MLN_TRACE_ZONE(LineWidth::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLfloat lineWidth;
|
||||
MBGL_CHECK_ERROR(glGetFloatv(GL_LINE_WIDTH, &lineWidth));
|
||||
return lineWidth;
|
||||
@@ -249,10 +322,14 @@ LineWidth::Type LineWidth::Get() {
|
||||
const constexpr ActiveTextureUnit::Type ActiveTextureUnit::Default;
|
||||
|
||||
void ActiveTextureUnit::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(ActiveTextureUnit::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0 + value));
|
||||
}
|
||||
|
||||
ActiveTextureUnit::Type ActiveTextureUnit::Get() {
|
||||
MLN_TRACE_ZONE(ActiveTextureUnit::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint activeTexture;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture));
|
||||
return static_cast<Type>(activeTexture - GL_TEXTURE0);
|
||||
@@ -261,10 +338,14 @@ ActiveTextureUnit::Type ActiveTextureUnit::Get() {
|
||||
const constexpr Viewport::Type Viewport::Default;
|
||||
|
||||
void Viewport::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(Viewport::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glViewport(value.x, value.y, value.size.width, value.size.height));
|
||||
}
|
||||
|
||||
Viewport::Type Viewport::Get() {
|
||||
MLN_TRACE_ZONE(Viewport::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint viewport[4];
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_VIEWPORT, viewport));
|
||||
return {static_cast<int32_t>(viewport[0]),
|
||||
@@ -275,10 +356,14 @@ Viewport::Type Viewport::Get() {
|
||||
const constexpr ScissorTest::Type ScissorTest::Default;
|
||||
|
||||
void ScissorTest::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(ScissorTest::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(value ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST));
|
||||
}
|
||||
|
||||
ScissorTest::Type ScissorTest::Get() {
|
||||
MLN_TRACE_ZONE(ScissorTest::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
Type scissorTest;
|
||||
MBGL_CHECK_ERROR(scissorTest = glIsEnabled(GL_SCISSOR_TEST));
|
||||
return scissorTest;
|
||||
@@ -287,10 +372,14 @@ ScissorTest::Type ScissorTest::Get() {
|
||||
const constexpr BindFramebuffer::Type BindFramebuffer::Default;
|
||||
|
||||
void BindFramebuffer::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BindFramebuffer::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, value));
|
||||
}
|
||||
|
||||
BindFramebuffer::Type BindFramebuffer::Get() {
|
||||
MLN_TRACE_ZONE(BindFramebuffer::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint binding;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &binding));
|
||||
return binding;
|
||||
@@ -299,10 +388,14 @@ BindFramebuffer::Type BindFramebuffer::Get() {
|
||||
const constexpr BindRenderbuffer::Type BindRenderbuffer::Default;
|
||||
|
||||
void BindRenderbuffer::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BindRenderbuffer::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBindRenderbuffer(GL_RENDERBUFFER, value));
|
||||
}
|
||||
|
||||
BindRenderbuffer::Type BindRenderbuffer::Get() {
|
||||
MLN_TRACE_ZONE(BindRenderbuffer::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint binding;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_RENDERBUFFER_BINDING, &binding));
|
||||
return binding;
|
||||
@@ -311,10 +404,14 @@ BindRenderbuffer::Type BindRenderbuffer::Get() {
|
||||
const constexpr CullFace::Type CullFace::Default;
|
||||
|
||||
void CullFace::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(CullFace::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(value ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE));
|
||||
}
|
||||
|
||||
CullFace::Type CullFace::Get() {
|
||||
MLN_TRACE_ZONE(CullFace::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLboolean cullFace;
|
||||
MBGL_CHECK_ERROR(cullFace = glIsEnabled(GL_CULL_FACE));
|
||||
return cullFace;
|
||||
@@ -323,10 +420,14 @@ CullFace::Type CullFace::Get() {
|
||||
const constexpr CullFaceSide::Type CullFaceSide::Default;
|
||||
|
||||
void CullFaceSide::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(CullFaceSide::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glCullFace(Enum<gfx::CullFaceSideType>::to(value)));
|
||||
}
|
||||
|
||||
CullFaceSide::Type CullFaceSide::Get() {
|
||||
MLN_TRACE_ZONE(CullFaceSide::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint cullFaceMode;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_CULL_FACE_MODE, &cullFaceMode));
|
||||
return Enum<gfx::CullFaceSideType>::from(cullFaceMode);
|
||||
@@ -335,10 +436,14 @@ CullFaceSide::Type CullFaceSide::Get() {
|
||||
const constexpr CullFaceWinding::Type CullFaceWinding::Default;
|
||||
|
||||
void CullFaceWinding::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(CullFaceWinding::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glFrontFace(Enum<gfx::CullFaceWindingType>::to(value)));
|
||||
}
|
||||
|
||||
CullFaceWinding::Type CullFaceWinding::Get() {
|
||||
MLN_TRACE_ZONE(CullFaceWinding::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint frontFace;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_FRONT_FACE, &frontFace));
|
||||
return Enum<gfx::CullFaceWindingType>::from(frontFace);
|
||||
@@ -347,10 +452,14 @@ CullFaceWinding::Type CullFaceWinding::Get() {
|
||||
const constexpr BindTexture::Type BindTexture::Default;
|
||||
|
||||
void BindTexture::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BindTexture::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, value));
|
||||
}
|
||||
|
||||
BindTexture::Type BindTexture::Get() {
|
||||
MLN_TRACE_ZONE(BindTexture::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint binding;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_TEXTURE_BINDING_2D, &binding));
|
||||
return binding;
|
||||
@@ -359,10 +468,14 @@ BindTexture::Type BindTexture::Get() {
|
||||
const constexpr BindVertexBuffer::Type BindVertexBuffer::Default;
|
||||
|
||||
void BindVertexBuffer::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BindVertexBuffer::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, value));
|
||||
}
|
||||
|
||||
BindVertexBuffer::Type BindVertexBuffer::Get() {
|
||||
MLN_TRACE_ZONE(BindVertexBuffer::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint binding;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &binding));
|
||||
return binding;
|
||||
@@ -371,10 +484,14 @@ BindVertexBuffer::Type BindVertexBuffer::Get() {
|
||||
const constexpr BindElementBuffer::Type BindElementBuffer::Default;
|
||||
|
||||
void BindElementBuffer::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BindElementBuffer::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, value));
|
||||
}
|
||||
|
||||
BindElementBuffer::Type BindElementBuffer::Get() {
|
||||
MLN_TRACE_ZONE(BindElementBuffer::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint binding;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &binding));
|
||||
return binding;
|
||||
@@ -383,10 +500,14 @@ BindElementBuffer::Type BindElementBuffer::Get() {
|
||||
const constexpr BindVertexArray::Type BindVertexArray::Default;
|
||||
|
||||
void BindVertexArray::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(BindVertexArray::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
MBGL_CHECK_ERROR(glBindVertexArray(value));
|
||||
}
|
||||
|
||||
BindVertexArray::Type BindVertexArray::Get() {
|
||||
MLN_TRACE_ZONE(BindVertexArray::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
GLint binding = 0;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &binding));
|
||||
return binding;
|
||||
@@ -485,8 +606,11 @@ GLint components(const gfx::AttributeDataType type) {
|
||||
#endif
|
||||
|
||||
void VertexAttribute::Set(const Type& binding, Context& context, AttributeLocation location) {
|
||||
MLN_TRACE_ZONE(VertexAttribute::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
if (binding && binding->vertexBufferResource) {
|
||||
context.vertexBuffer = reinterpret_cast<const gl::VertexBufferResource&>(*binding->vertexBufferResource).buffer;
|
||||
context.vertexBuffer =
|
||||
reinterpret_cast<const gl::VertexBufferResource&>(*binding->vertexBufferResource).getBuffer();
|
||||
MBGL_CHECK_ERROR(glEnableVertexAttribArray(location));
|
||||
MBGL_CHECK_ERROR(glVertexAttribPointer(
|
||||
location,
|
||||
@@ -507,11 +631,15 @@ void VertexAttribute::Set(const Type& binding, Context& context, AttributeLocati
|
||||
const constexpr PixelStorePack::Type PixelStorePack::Default;
|
||||
|
||||
void PixelStorePack::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(PixelStorePack::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
assert(value.alignment == 1 || value.alignment == 2 || value.alignment == 4 || value.alignment == 8);
|
||||
MBGL_CHECK_ERROR(glPixelStorei(GL_PACK_ALIGNMENT, value.alignment));
|
||||
}
|
||||
|
||||
PixelStorePack::Type PixelStorePack::Get() {
|
||||
MLN_TRACE_ZONE(PixelStorePack::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
Type value;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_PACK_ALIGNMENT, &value.alignment));
|
||||
return value;
|
||||
@@ -520,11 +648,15 @@ PixelStorePack::Type PixelStorePack::Get() {
|
||||
const constexpr PixelStoreUnpack::Type PixelStoreUnpack::Default;
|
||||
|
||||
void PixelStoreUnpack::Set(const Type& value) {
|
||||
MLN_TRACE_ZONE(PixelStoreUnpack::Set);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
assert(value.alignment == 1 || value.alignment == 2 || value.alignment == 4 || value.alignment == 8);
|
||||
MBGL_CHECK_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, value.alignment));
|
||||
}
|
||||
|
||||
PixelStoreUnpack::Type PixelStoreUnpack::Get() {
|
||||
MLN_TRACE_ZONE(PixelStoreUnpack::Get);
|
||||
MLN_TRACE_FUNC_GL();
|
||||
Type value;
|
||||
MBGL_CHECK_ERROR(glGetIntegerv(GL_UNPACK_ALIGNMENT, &value.alignment));
|
||||
return value;
|
||||
|
||||
@@ -153,11 +153,13 @@ std::size_t VertexAttributeGL::getStride() const {
|
||||
return getStride(getGLType());
|
||||
}
|
||||
|
||||
const std::vector<std::uint8_t>& VertexAttributeGL::getRaw(gfx::VertexAttribute& attr, platform::GLenum type) {
|
||||
const std::vector<std::uint8_t>& VertexAttributeGL::getRaw(gfx::VertexAttribute& attr,
|
||||
platform::GLenum type,
|
||||
std::chrono::duration<double> lastUpdate) {
|
||||
const auto count = attr.getCount();
|
||||
const auto stride_ = getStride(type);
|
||||
auto& rawData = attr.getRawData();
|
||||
if (attr.isDirty() || rawData.size() != count * stride_) {
|
||||
if (attr.isModifiedAfter(lastUpdate) || rawData.size() != count * stride_) {
|
||||
rawData.resize(stride_ * count);
|
||||
|
||||
if (!rawData.empty()) {
|
||||
@@ -177,18 +179,5 @@ const std::vector<std::uint8_t>& VertexAttributeGL::getRaw(gfx::VertexAttribute&
|
||||
return rawData;
|
||||
}
|
||||
|
||||
bool VertexAttributeArrayGL::isDirty() const {
|
||||
return std::any_of(attrs.begin(), attrs.end(), [](const auto& attr) {
|
||||
if (attr) {
|
||||
// If we have shared data, the dirty flag from that overrides ours
|
||||
const auto& glAttrib = static_cast<const VertexAttributeGL&>(*attr);
|
||||
if (const auto& shared = glAttrib.getSharedRawData()) {
|
||||
return shared->getDirty();
|
||||
}
|
||||
}
|
||||
return attr && attr->isDirty();
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/gfx/vertex_buffer.hpp>
|
||||
#include <mbgl/gl/object.hpp>
|
||||
#include <mbgl/util/monotonic_timer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
@@ -11,8 +12,17 @@ public:
|
||||
VertexBufferResource(UniqueBuffer&& buffer_, int byteSize_);
|
||||
~VertexBufferResource() noexcept override;
|
||||
|
||||
int getByteSize() const { return byteSize; }
|
||||
|
||||
const UniqueBuffer& getBuffer() const { return buffer; }
|
||||
|
||||
std::chrono::duration<double> getLastUpdated() const { return lastUpdated; }
|
||||
void setLastUpdated(std::chrono::duration<double> time) { lastUpdated = time; }
|
||||
|
||||
protected:
|
||||
UniqueBuffer buffer;
|
||||
int byteSize;
|
||||
std::chrono::duration<double> lastUpdated = util::MonotonicTimer::now();
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
||||
@@ -191,13 +191,13 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
bindUniformBuffers(renderPass);
|
||||
bindTextures(renderPass);
|
||||
|
||||
if (!impl->indexes->getBuffer() || impl->indexes->getDirty()) {
|
||||
if (!impl->indexes->getBuffer() || impl->indexes->isModifiedAfter(attributeUpdateTime)) {
|
||||
assert(!"Index buffer not uploaded");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto* indexBuffer = getMetalBuffer(impl->indexes);
|
||||
if (!indexBuffer || impl->indexes->getDirty()) {
|
||||
if (!indexBuffer || impl->indexes->isModifiedAfter(attributeUpdateTime)) {
|
||||
assert(!"Index buffer not uploaded");
|
||||
return;
|
||||
}
|
||||
@@ -526,14 +526,19 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
auto& context = static_cast<Context&>(contextBase);
|
||||
constexpr auto usage = gfx::BufferUsageType::StaticDraw;
|
||||
|
||||
if (impl->indexes) {
|
||||
impl->indexes->updateModified();
|
||||
}
|
||||
|
||||
// We need either raw index data or a buffer already created from them.
|
||||
// We can have a buffer and no indexes, but only if it's not marked dirty.
|
||||
if (!impl->indexes || (impl->indexes->empty() && (!impl->indexes->getBuffer() || impl->indexes->getDirty()))) {
|
||||
if (!impl->indexes || (impl->indexes->empty() &&
|
||||
(!impl->indexes->getBuffer() || impl->indexes->isModifiedAfter(attributeUpdateTime)))) {
|
||||
assert(!"Missing index data");
|
||||
return;
|
||||
}
|
||||
|
||||
if (impl->indexes->getDirty()) {
|
||||
if (!impl->indexes->getBuffer() || impl->indexes->isModifiedAfter(attributeUpdateTime)) {
|
||||
// Create or update a buffer for the index data. We don't update any
|
||||
// existing buffer because it may still be in use by the previous frame.
|
||||
auto indexBufferResource{uploadPass.createIndexBufferResource(
|
||||
@@ -543,10 +548,10 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
auto buffer = std::make_unique<IndexBuffer>(std::move(indexBuffer));
|
||||
|
||||
impl->indexes->setBuffer(std::move(buffer));
|
||||
impl->indexes->setDirty(false);
|
||||
}
|
||||
|
||||
const bool buildAttribs = !vertexAttributes || vertexAttributes->isDirty() || !impl->vertexDesc;
|
||||
const bool buildAttribs = !vertexAttributes || vertexAttributes->isModifiedAfter(attributeUpdateTime) ||
|
||||
!impl->vertexDesc;
|
||||
|
||||
if (buildAttribs) {
|
||||
#if !defined(NDEBUG)
|
||||
@@ -566,6 +571,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
shader->getVertexAttributes(),
|
||||
*vertexAttributes,
|
||||
usage,
|
||||
attributeUpdateTime,
|
||||
vertexBuffers);
|
||||
impl->attributeBuffers = std::move(vertexBuffers);
|
||||
|
||||
@@ -626,7 +632,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
}
|
||||
|
||||
// build instance buffer
|
||||
const bool buildInstanceBuffer = (instanceAttributes && instanceAttributes->isDirty());
|
||||
const bool buildInstanceBuffer = (instanceAttributes && instanceAttributes->isModifiedAfter(attributeUpdateTime));
|
||||
|
||||
if (buildInstanceBuffer) {
|
||||
// Build instance attribute buffers
|
||||
@@ -638,6 +644,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
shader->getInstanceAttributes(),
|
||||
*instanceAttributes,
|
||||
usage,
|
||||
attributeUpdateTime,
|
||||
instanceBuffers);
|
||||
impl->instanceBuffers = std::move(instanceBuffers);
|
||||
|
||||
@@ -655,6 +662,10 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
if (texturesNeedUpload) {
|
||||
uploadTextures(uploadPass);
|
||||
}
|
||||
|
||||
if (buildAttribs || buildInstanceBuffer) {
|
||||
attributeUpdateTime = util::MonotonicTimer::now();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mtl
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mbgl/mtl/renderable_resource.hpp>
|
||||
#include <mbgl/mtl/vertex_attribute.hpp>
|
||||
#include <mbgl/mtl/vertex_buffer_resource.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <Metal/Metal.hpp>
|
||||
@@ -127,21 +128,21 @@ const gfx::UniqueVertexBufferResource& UploadPass::getBuffer(const gfx::VertexVe
|
||||
if (auto* rawData = static_cast<VertexBuffer*>(vec->getBuffer()); rawData && rawData->resource) {
|
||||
auto& resource = static_cast<VertexBufferResource&>(*rawData->resource);
|
||||
|
||||
// If it's changed, update it
|
||||
// If the already-allocated buffer is large enough, we can re-use it
|
||||
if (rawBufSize <= resource.getSizeInBytes()) {
|
||||
if (vec->getDirty()) {
|
||||
// If the source changed, update the buffer contents
|
||||
if (vec->isModifiedAfter(resource.getLastUpdated())) {
|
||||
updateVertexBufferResource(resource, rawBufPtr, rawBufSize);
|
||||
vec->setDirty(false);
|
||||
resource.setLastUpdated(vec->getLastModified());
|
||||
}
|
||||
return rawData->resource;
|
||||
}
|
||||
}
|
||||
// Otherwise, create a new one
|
||||
if (rawBufSize > 0) {
|
||||
auto buffer = std::make_unique<VertexBuffer>();
|
||||
buffer->resource = createVertexBufferResource(rawBufPtr, rawBufSize, usage, /*persistent=*/false);
|
||||
vec->setBuffer(std::move(buffer));
|
||||
vec->setDirty(false);
|
||||
auto buffer_ = std::make_unique<VertexBuffer>();
|
||||
buffer_->resource = createVertexBufferResource(rawBufPtr, rawBufSize, usage, /*persistent=*/false);
|
||||
vec->setBuffer(std::move(buffer_));
|
||||
return static_cast<VertexBuffer*>(vec->getBuffer())->resource;
|
||||
}
|
||||
}
|
||||
@@ -156,7 +157,10 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
const gfx::VertexAttributeArray& defaults,
|
||||
const gfx::VertexAttributeArray& overrides,
|
||||
const gfx::BufferUsageType usage,
|
||||
const std::chrono::duration<double> /*lastUpdate*/,
|
||||
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>& outBuffers) {
|
||||
MLN_TRACE_FUNC();
|
||||
|
||||
gfx::AttributeBindingArray bindings;
|
||||
bindings.resize(defaults.allocatedSize());
|
||||
|
||||
@@ -187,14 +191,14 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
}
|
||||
|
||||
// If the attribute references data shared with a bucket, get the corresponding buffer.
|
||||
if (const auto& buffer = getBuffer(effectiveAttr.getSharedRawData(), usage)) {
|
||||
if (const auto& buffer_ = getBuffer(effectiveAttr.getSharedRawData(), usage)) {
|
||||
assert(effectiveAttr.getSharedStride() * effectiveAttr.getSharedVertexOffset() <
|
||||
effectiveAttr.getSharedRawData()->getRawSize() * effectiveAttr.getSharedRawData()->getRawCount());
|
||||
|
||||
bindings[index] = {
|
||||
/*.attribute = */ {effectiveAttr.getSharedType(), effectiveAttr.getSharedOffset()},
|
||||
/*.vertexStride = */ effectiveAttr.getSharedStride(),
|
||||
/*.vertexBufferResource = */ buffer.get(),
|
||||
/*.vertexBufferResource = */ buffer_.get(),
|
||||
/*.vertexOffset = */ effectiveAttr.getSharedVertexOffset(),
|
||||
};
|
||||
return;
|
||||
@@ -203,11 +207,11 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
assert(effectiveAttr.getStride() > 0);
|
||||
|
||||
// Otherwise, turn the data managed by the attribute into a buffer.
|
||||
if (const auto& buffer = VertexAttribute::getBuffer(effectiveAttr, *this, gfx::BufferUsageType::StaticDraw)) {
|
||||
if (const auto& buffer_ = VertexAttribute::getBuffer(effectiveAttr, *this, gfx::BufferUsageType::StaticDraw)) {
|
||||
bindings[index] = {
|
||||
/*.attribute = */ {effectiveAttr.getDataType(), /*offset=*/0},
|
||||
/*.vertexStride = */ static_cast<uint32_t>(effectiveAttr.getStride()),
|
||||
/*.vertexBufferResource = */ buffer.get(),
|
||||
/*.vertexBufferResource = */ buffer_.get(),
|
||||
/*.vertexOffset = */ 0,
|
||||
};
|
||||
return;
|
||||
@@ -215,7 +219,11 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
|
||||
assert(false);
|
||||
};
|
||||
defaults.resolve(overrides, resolveAttr);
|
||||
// This version is called when the attribute is available, but isn't being used by the shader
|
||||
const auto missingAttr = [&](const size_t, auto& missingAttr) -> void {
|
||||
missingAttr->setDirty(false);
|
||||
};
|
||||
defaults.resolve(overrides, resolveAttr, missingAttr);
|
||||
|
||||
return bindings;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ const gfx::UniqueVertexBufferResource& VertexAttribute::getBuffer(gfx::VertexAtt
|
||||
attrib.rawData.data(), attrib.rawData.size(), usage, false);
|
||||
attrib.setBuffer(std::move(buffer));
|
||||
attrib.setRawData({});
|
||||
attrib_.setDirty(false);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
@@ -33,18 +34,5 @@ const gfx::UniqueVertexBufferResource& VertexAttribute::getBuffer(gfx::VertexAtt
|
||||
return attrib_.getBuffer();
|
||||
}
|
||||
|
||||
bool VertexAttributeArray::isDirty() const {
|
||||
return std::any_of(attrs.begin(), attrs.end(), [](const auto& attr) {
|
||||
if (attr) {
|
||||
// If we have shared data, the dirty flag from that overrides ours
|
||||
const auto& attrib = static_cast<const VertexAttribute&>(*attr);
|
||||
if (const auto& shared = attrib.getSharedRawData()) {
|
||||
return shared->getDirty();
|
||||
}
|
||||
}
|
||||
return attr && attr->isDirty();
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace mtl
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -72,6 +72,9 @@ void CircleBucket::update(const FeatureStates& states,
|
||||
if (it != paintPropertyBinders.end()) {
|
||||
it->second.updateVertexVectors(states, layer, imagePositions);
|
||||
uploaded = false;
|
||||
|
||||
sharedVertices->updateModified();
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +111,10 @@ void FillBucket::update(const FeatureStates& states,
|
||||
if (it != paintPropertyBinders.end()) {
|
||||
it->second.updateVertexVectors(states, layer, imagePositions);
|
||||
uploaded = false;
|
||||
|
||||
sharedVertices->updateModified();
|
||||
sharedBasicLineIndexes->updateModified();
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -204,6 +204,9 @@ void FillExtrusionBucket::update(const FeatureStates& states,
|
||||
if (it != paintPropertyBinders.end()) {
|
||||
it->second.updateVertexVectors(states, layer, imagePositions);
|
||||
uploaded = false;
|
||||
|
||||
sharedVertices->updateModified();
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +166,9 @@ void LineBucket::update(const FeatureStates& states,
|
||||
if (it != paintPropertyBinders.end()) {
|
||||
it->second.updateVertexVectors(states, layer, imagePositions);
|
||||
uploaded = false;
|
||||
|
||||
sharedVertices->updateModified();
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -352,6 +352,12 @@ void SymbolBucket::updateVertices(const Placement& placement,
|
||||
dynamicUploaded = false;
|
||||
uploaded = false;
|
||||
}
|
||||
|
||||
if (!uploaded) {
|
||||
text.updateModified();
|
||||
icon.updateModified();
|
||||
sdfIcon.updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -146,6 +146,22 @@ public:
|
||||
sharedDynamicVertices->release();
|
||||
sharedOpacityVertices->release();
|
||||
}
|
||||
|
||||
void updateModified() {
|
||||
if (sharedVertices) {
|
||||
sharedVertices->updateModified();
|
||||
}
|
||||
if (sharedDynamicVertices) {
|
||||
sharedDynamicVertices->updateModified();
|
||||
}
|
||||
if (sharedOpacityVertices) {
|
||||
sharedOpacityVertices->updateModified();
|
||||
}
|
||||
if (sharedTriangles) {
|
||||
sharedTriangles->updateModified();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<VertexVector> sharedVertices = std::make_shared<VertexVector>();
|
||||
VertexVector& vertices() { return *sharedVertices; }
|
||||
const VertexVector& vertices() const { return *sharedVertices; }
|
||||
|
||||
@@ -340,7 +340,8 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
|
||||
[&](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())) {
|
||||
if (drawable && (bucket.sharedVertices->isModifiedAfter(drawable->createTime) ||
|
||||
bucket.sharedTriangles->isModifiedAfter(drawable->createTime))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -447,19 +448,27 @@ void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
|
||||
bool cleared = false;
|
||||
auto& bucket = static_cast<RasterBucket&>(*bucket_);
|
||||
|
||||
// If the bucket data has changed, rebuild the drawables.
|
||||
const bool bucketSharedData = (!bucket.vertices.empty() && !bucket.indices.empty() &&
|
||||
!bucket.segments.empty());
|
||||
const bool bucketDirty = bucketSharedData && (bucket.vertices.getDirty() || bucket.indices.getDirty());
|
||||
if (bucketDirty) {
|
||||
// Note, vertex/index dirty flags will be reset when those buffers are uploaded.
|
||||
removeTile(renderPass, tileID);
|
||||
cleared = true;
|
||||
} else if (setRenderTileBucketID(tileID, bucket.getID())) {
|
||||
if (setRenderTileBucketID(tileID, bucket.getID())) {
|
||||
// Bucket ID changed, we need to rebuild the drawables
|
||||
removeTile(renderPass, tileID);
|
||||
cleared = true;
|
||||
}
|
||||
// If the bucket data has changed, rebuild the drawables.
|
||||
else if (!bucket.vertices.empty() && !bucket.indices.empty() && !bucket.segments.empty()) {
|
||||
// Find the earliest time on existing drawables
|
||||
std::optional<std::chrono::duration<double>> tileUpdateTime;
|
||||
tileLayerGroup->visitDrawables(renderPass, tileID, [&](const auto& drawable) {
|
||||
if (!tileUpdateTime || drawable.createTime < *tileUpdateTime) {
|
||||
tileUpdateTime = drawable.createTime;
|
||||
}
|
||||
});
|
||||
|
||||
if (tileUpdateTime && (bucket.vertices.isModifiedAfter(*tileUpdateTime) ||
|
||||
bucket.indices.isModifiedAfter(*tileUpdateTime))) {
|
||||
removeTile(renderPass, tileID);
|
||||
cleared = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cleared) {
|
||||
// Update existing drawables
|
||||
|
||||
@@ -1344,7 +1344,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
auto drawData = std::make_unique<gfx::SymbolDrawableData>(
|
||||
/*.isHalo=*/isHalo,
|
||||
/*.bucketVaraiblePlacement=*/bucket.hasVariablePlacement,
|
||||
/*.bucketVariablePlacement=*/bucket.hasVariablePlacement,
|
||||
/*.symbolType=*/renderable.type,
|
||||
/*.pitchAlignment=*/values.pitchAlignment,
|
||||
/*.rotationAlignment=*/values.rotationAlignment,
|
||||
|
||||
@@ -320,12 +320,15 @@ public:
|
||||
const FeatureState& state) override {
|
||||
using style::expression::EvaluationContext;
|
||||
|
||||
auto evaluated = expression.evaluate(EvaluationContext(&feature).withFeatureState(&state), defaultValue);
|
||||
const auto evaluated = expression.evaluate(EvaluationContext(&feature).withFeatureState(&state), defaultValue);
|
||||
this->statistics.add(evaluated);
|
||||
auto value = attributeValue(evaluated);
|
||||
|
||||
const auto value = BaseVertex{attributeValue(evaluated)};
|
||||
for (std::size_t i = start; i < end; ++i) {
|
||||
vertexVector.at(i) = BaseVertex{value};
|
||||
vertexVector.at(i) = value;
|
||||
}
|
||||
|
||||
vertexVector.updateModified();
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
@@ -449,17 +452,21 @@ public:
|
||||
const GeometryTileFeature& feature,
|
||||
const FeatureState& state) override {
|
||||
using style::expression::EvaluationContext;
|
||||
Range<T> range = {
|
||||
const Range<T> range = {
|
||||
expression.evaluate(EvaluationContext(zoomRange.min, &feature, &state), defaultValue),
|
||||
expression.evaluate(EvaluationContext(zoomRange.max, &feature, &state), defaultValue),
|
||||
};
|
||||
this->statistics.add(range.min);
|
||||
this->statistics.add(range.max);
|
||||
AttributeValue value = zoomInterpolatedAttributeValue(attributeValue(range.min), attributeValue(range.max));
|
||||
|
||||
const Vertex value = Vertex{
|
||||
zoomInterpolatedAttributeValue(attributeValue(range.min), attributeValue(range.max))};
|
||||
|
||||
for (std::size_t i = start; i < end; ++i) {
|
||||
vertexVector.at(i) = Vertex{value};
|
||||
vertexVector.at(i) = value;
|
||||
}
|
||||
|
||||
vertexVector.updateModified();
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
|
||||
@@ -252,6 +252,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
|
||||
// Remove render layers for removed layers.
|
||||
for (const auto& entry : layerDiff.removed) {
|
||||
MLN_TRACE_ZONE(remove layer);
|
||||
const auto hit = renderLayers.find(entry.first);
|
||||
if (hit != renderLayers.end()) {
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
@@ -263,6 +264,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
|
||||
// Create render layers for newly added layers.
|
||||
for (const auto& entry : layerDiff.added) {
|
||||
MLN_TRACE_ZONE(add layer);
|
||||
auto renderLayer = LayerManager::get()->createRenderLayer(entry.second);
|
||||
renderLayer->transition(transitionParameters);
|
||||
renderLayers.emplace(entry.first, std::move(renderLayer));
|
||||
@@ -270,6 +272,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
|
||||
// Update render layers for changed layers.
|
||||
for (const auto& entry : layerDiff.changed) {
|
||||
MLN_TRACE_ZONE(change layer);
|
||||
if (const auto& renderLayer = renderLayers.at(entry.first)) {
|
||||
const auto& newLayer = entry.second.after;
|
||||
|
||||
@@ -305,6 +308,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
// Update layers for class and zoom changes.
|
||||
std::unordered_set<std::string> constantsMaskChanged;
|
||||
for (RenderLayer& layer : orderedLayers) {
|
||||
MLN_TRACE_ZONE(update layer);
|
||||
const std::string& id = layer.getID();
|
||||
const bool layerAddedOrChanged = layerDiff.added.contains(id) || layerDiff.changed.contains(id);
|
||||
evaluationParameters.layerChanged = layerAddedOrChanged;
|
||||
@@ -335,6 +339,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
|
||||
// Create render sources for newly added sources.
|
||||
for (const auto& entry : sourceDiff.added) {
|
||||
MLN_TRACE_ZONE(create source);
|
||||
std::unique_ptr<RenderSource> renderSource = RenderSource::create(entry.second, threadPool);
|
||||
renderSource->setObserver(this);
|
||||
renderSource->enableCache(tileCacheEnabled);
|
||||
@@ -439,6 +444,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
|
||||
// Prepare. Update all matrices and generate data that we should upload to the GPU.
|
||||
for (const auto& entry : renderSources) {
|
||||
MLN_TRACE_ZONE(prepare source);
|
||||
if (entry.second->isEnabled()) {
|
||||
entry.second->prepare(
|
||||
{renderTreeParameters->transformParams, updateParameters->debugOptions, *imageManager});
|
||||
@@ -447,9 +453,8 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
|
||||
auto opaquePassCutOffEstimation = layerRenderItems.size();
|
||||
for (auto& renderItem : layerRenderItems) {
|
||||
MLN_TRACE_ZONE(prepare layer)
|
||||
|
||||
RenderLayer& renderLayer = renderItem.layer;
|
||||
MLN_TRACE_ZONE(prepare layer)
|
||||
MLN_ZONE_STR(renderLayer.getID())
|
||||
|
||||
renderLayer.prepare(
|
||||
@@ -472,6 +477,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
std::set<std::string> usedSymbolLayers;
|
||||
const auto longitude = static_cast<float>(updateParameters->transformState.getLatLng().longitude());
|
||||
for (auto it = layersNeedPlacement.crbegin(); it != layersNeedPlacement.crend(); ++it) {
|
||||
MLN_TRACE_ZONE(placement layer);
|
||||
RenderLayer& layer = *it;
|
||||
auto result = crossTileSymbolIndex.addLayer(layer, longitude);
|
||||
if (isMapModeContinuous) {
|
||||
@@ -482,7 +488,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
}
|
||||
|
||||
if (isMapModeContinuous) {
|
||||
MLN_TRACE_ZONE(placement)
|
||||
MLN_TRACE_ZONE(placement);
|
||||
|
||||
std::optional<Duration> placementUpdatePeriodOverride;
|
||||
if (symbolBucketsAdded && !tiltedView) {
|
||||
@@ -518,7 +524,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
updateParameters->timePoint);
|
||||
renderTreeParameters->needsRepaint = hasTransitions(updateParameters->timePoint);
|
||||
} else {
|
||||
MLN_TRACE_ZONE(placement)
|
||||
MLN_TRACE_ZONE(placement);
|
||||
|
||||
renderTreeParameters->placementChanged = symbolBucketsChanged = !layersNeedPlacement.empty();
|
||||
if (renderTreeParameters->placementChanged) {
|
||||
@@ -533,6 +539,7 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(
|
||||
}
|
||||
|
||||
if (!renderTreeParameters->needsRepaint && renderTreeParameters->loaded) {
|
||||
MLN_TRACE_ZONE(reduce);
|
||||
// Notify observer about unused images when map is fully loaded
|
||||
// and there are no ongoing transitions.
|
||||
imageManager->reduceMemoryUseIfCacheSizeExceedsLimit();
|
||||
|
||||
@@ -43,7 +43,8 @@ void SourceFeatureState::getState(FeatureState& result,
|
||||
}
|
||||
|
||||
void SourceFeatureState::coalesceChanges(std::vector<RenderTile>& tiles) {
|
||||
MLN_TRACE_FUNC()
|
||||
MLN_TRACE_FUNC();
|
||||
|
||||
LayerFeatureStates changes;
|
||||
for (const auto& layerStatesEntry : stateChanges) {
|
||||
const auto& sourceLayer = layerStatesEntry.first;
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/util/tile_coordinate.hpp>
|
||||
#include <mbgl/util/tile_cover.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -89,6 +90,7 @@ std::unique_ptr<RenderItem> RenderImageSource::createRenderItem() {
|
||||
}
|
||||
|
||||
void RenderImageSource::prepare(const SourcePrepareParameters& parameters) {
|
||||
MLN_TRACE_FUNC();
|
||||
assert(!renderData);
|
||||
if (!isLoaded()) {
|
||||
renderData = std::make_unique<ImageSourceRenderData>(bucket, std::vector<mat4>{}, baseImpl->id);
|
||||
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
std::optional<CollisionBoundaries> avoidEdges;
|
||||
};
|
||||
|
||||
// PlacementController implemenation
|
||||
// PlacementController implementation
|
||||
|
||||
PlacementController::PlacementController()
|
||||
: placement(makeMutable<Placement>()) {}
|
||||
@@ -754,12 +754,12 @@ Point<float> calculateVariableRenderShift(style::SymbolAnchorType anchor,
|
||||
std::array<float, 2> textOffset,
|
||||
float textBoxScale,
|
||||
float renderTextSize) {
|
||||
AnchorAlignment alignment = AnchorAlignment::getAnchorAlignment(anchor);
|
||||
float shiftX = -(alignment.horizontalAlign - 0.5f) * width;
|
||||
float shiftY = -(alignment.verticalAlign - 0.5f) * height;
|
||||
auto variablOffset = SymbolLayout::evaluateVariableOffset(anchor, textOffset);
|
||||
return {(shiftX / textBoxScale + variablOffset[0]) * renderTextSize,
|
||||
(shiftY / textBoxScale + variablOffset[1]) * renderTextSize};
|
||||
const AnchorAlignment alignment = AnchorAlignment::getAnchorAlignment(anchor);
|
||||
const float shiftX = -(alignment.horizontalAlign - 0.5f) * width;
|
||||
const float shiftY = -(alignment.verticalAlign - 0.5f) * height;
|
||||
const auto variableOffset = SymbolLayout::evaluateVariableOffset(anchor, textOffset);
|
||||
return {(shiftX / textBoxScale + variableOffset[0]) * renderTextSize,
|
||||
(shiftY / textBoxScale + variableOffset[1]) * renderTextSize};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ protected:
|
||||
const std::vector<ProjectedCollisionBox>& /*textBoxes*/,
|
||||
const std::vector<ProjectedCollisionBox>& /*iconBoxes*/
|
||||
) {}
|
||||
// Implentation specific hooks, which get called during a symbol bucket placement.
|
||||
// Implementation specific hooks, which get called during a symbol bucket placement.
|
||||
virtual std::optional<CollisionBoundaries> getAvoidEdges(const SymbolBucket&, const mat4& /*posMatrix*/) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <mbgl/util/thread_local.hpp>
|
||||
#include <mbgl/util/containers.hpp>
|
||||
#include <mbgl/util/identity.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <condition_variable>
|
||||
@@ -107,6 +108,7 @@ public:
|
||||
}
|
||||
|
||||
void runRenderJobs(const util::SimpleIdentity tag, bool closeQueue = false) override {
|
||||
MLN_TRACE_FUNC();
|
||||
std::shared_ptr<RenderQueue> queue;
|
||||
std::unique_lock<std::mutex> lock(taggedRenderQueueLock);
|
||||
|
||||
@@ -130,6 +132,7 @@ public:
|
||||
auto fn = std::move(queue->queue.front());
|
||||
queue->queue.pop();
|
||||
if (fn) {
|
||||
MLN_TRACE_ZONE(render job);
|
||||
fn();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ BufferResource& BufferResource::operator=(BufferResource&& other) noexcept {
|
||||
}
|
||||
|
||||
void BufferResource::update(const void* newData, std::size_t updateSize, std::size_t offset) noexcept {
|
||||
assert(size >= 0 && updateSize + offset <= size);
|
||||
assert(updateSize + offset <= size);
|
||||
updateSize = std::min(updateSize, size - offset);
|
||||
if (updateSize <= 0) {
|
||||
return;
|
||||
|
||||
@@ -116,13 +116,14 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
|
||||
// We need either raw index data or a buffer already created from them.
|
||||
// We can have a buffer and no indexes, but only if it's not marked dirty.
|
||||
if (!impl->indexes || (impl->indexes->empty() && (!impl->indexes->getBuffer() || impl->indexes->getDirty()))) {
|
||||
if (!impl->indexes || (impl->indexes->empty() &&
|
||||
(!impl->indexes->getBuffer() || impl->indexes->isModifiedAfter(attributeUpdateTime)))) {
|
||||
assert(!"Missing index data");
|
||||
return;
|
||||
}
|
||||
|
||||
if (impl->indexes->getDirty()) {
|
||||
// Create or update a buffer for the index data. We don't update any
|
||||
if (!impl->indexes->getBuffer() || impl->indexes->isModifiedAfter(attributeUpdateTime)) {
|
||||
// Create a buffer for the index data. We don't update any
|
||||
// existing buffer because it may still be in use by the previous frame.
|
||||
auto indexBufferResource{uploadPass.createIndexBufferResource(
|
||||
impl->indexes->data(), impl->indexes->bytes(), usage, /*persistent=*/false)};
|
||||
@@ -131,10 +132,9 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
auto buffer = std::make_unique<IndexBuffer>(std::move(indexBuffer));
|
||||
|
||||
impl->indexes->setBuffer(std::move(buffer));
|
||||
impl->indexes->setDirty(false);
|
||||
}
|
||||
|
||||
const bool buildAttribs = !vertexAttributes || vertexAttributes->isDirty() ||
|
||||
const bool buildAttribs = !vertexAttributes || vertexAttributes->isModifiedAfter(attributeUpdateTime) ||
|
||||
impl->pipelineInfo.inputAttributes.empty();
|
||||
|
||||
if (buildAttribs) {
|
||||
@@ -155,6 +155,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
shader->getVertexAttributes(),
|
||||
*vertexAttributes,
|
||||
usage,
|
||||
attributeUpdateTime,
|
||||
vertexBuffers);
|
||||
|
||||
vertexAttributes->visitAttributes([](gfx::VertexAttribute& attrib) { attrib.setDirty(false); });
|
||||
@@ -165,7 +166,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
}
|
||||
|
||||
// build instance buffer
|
||||
const bool buildInstanceBuffer = (instanceAttributes && instanceAttributes->isDirty());
|
||||
const bool buildInstanceBuffer = (instanceAttributes && instanceAttributes->isModifiedAfter(attributeUpdateTime));
|
||||
|
||||
if (buildInstanceBuffer) {
|
||||
// Build instance attribute buffers
|
||||
@@ -177,6 +178,7 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
shader->getInstanceAttributes(),
|
||||
*instanceAttributes,
|
||||
usage,
|
||||
attributeUpdateTime,
|
||||
instanceBuffers);
|
||||
|
||||
// clear dirty flag
|
||||
@@ -185,6 +187,8 @@ void Drawable::upload(gfx::UploadPass& uploadPass_) {
|
||||
if (impl->instanceBindings != instanceBindings_) {
|
||||
impl->instanceBindings = std::move(instanceBindings_);
|
||||
}
|
||||
|
||||
attributeUpdateTime = util::MonotonicTimer::now();
|
||||
}
|
||||
|
||||
if (buildAttribs || buildInstanceBuffer) {
|
||||
@@ -205,8 +209,8 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
}
|
||||
|
||||
auto& context = static_cast<Context&>(parameters.context);
|
||||
auto& renderPass = static_cast<RenderPass&>(*parameters.renderPass);
|
||||
auto& encoder = renderPass.getEncoder();
|
||||
auto& renderPass_ = static_cast<RenderPass&>(*parameters.renderPass);
|
||||
auto& encoder = renderPass_.getEncoder();
|
||||
auto& commandBuffer = encoder.getCommandBuffer();
|
||||
|
||||
auto& shaderImpl = static_cast<mbgl::vulkan::ShaderProgram&>(*shader);
|
||||
@@ -233,7 +237,7 @@ void Drawable::draw(PaintParameters& parameters) const {
|
||||
}
|
||||
}
|
||||
|
||||
impl->pipelineInfo.setRenderable(renderPass.getDescriptor().renderable);
|
||||
impl->pipelineInfo.setRenderable(renderPass_.getDescriptor().renderable);
|
||||
|
||||
const uint32_t instances = instanceAttributes ? instanceAttributes->getMaxCount() : 1;
|
||||
|
||||
@@ -264,17 +268,17 @@ void Drawable::setIndexData(gfx::IndexVectorBasePtr indexes, std::vector<UniqueD
|
||||
impl->segments = std::move(segments);
|
||||
}
|
||||
|
||||
void Drawable::setVertices(std::vector<uint8_t>&& data, std::size_t count, gfx::AttributeDataType type) {
|
||||
void Drawable::setVertices(std::vector<uint8_t>&& data, std::size_t count, gfx::AttributeDataType type_) {
|
||||
impl->vertexCount = count;
|
||||
impl->vertexType = type;
|
||||
impl->vertexType = type_;
|
||||
|
||||
if (count && type != gfx::AttributeDataType::Invalid && !data.empty()) {
|
||||
if (count && type_ != gfx::AttributeDataType::Invalid && !data.empty()) {
|
||||
if (!vertexAttributes) {
|
||||
vertexAttributes = std::make_shared<VertexAttributeArray>();
|
||||
}
|
||||
if (auto& attrib = vertexAttributes->set(impl->vertexAttrId, /*index=*/-1, type)) {
|
||||
if (auto& attrib = vertexAttributes->set(impl->vertexAttrId, /*index=*/-1, type_)) {
|
||||
attrib->setRawData(std::move(data));
|
||||
attrib->setStride(VertexAttribute::getStrideOf(type));
|
||||
attrib->setStride(VertexAttribute::getStrideOf(type_));
|
||||
} else {
|
||||
using namespace std::string_literals;
|
||||
Log::Warning(Event::General,
|
||||
@@ -352,9 +356,10 @@ bool Drawable::bindAttributes(CommandEncoder& encoder) const noexcept {
|
||||
commandBuffer->bindVertexBuffers(0, impl->vulkanVertexBuffers, impl->vulkanVertexOffsets);
|
||||
|
||||
if (impl->indexes) {
|
||||
const auto* indexBuffer = static_cast<const IndexBuffer*>(impl->indexes->getBuffer());
|
||||
const auto& indexBufferResource = indexBuffer->buffer->getResource<IndexBufferResource>().get();
|
||||
commandBuffer->bindIndexBuffer(indexBufferResource.getVulkanBuffer(), 0, vk::IndexType::eUint16);
|
||||
if (const auto* indexBuffer = static_cast<const IndexBuffer*>(impl->indexes->getBuffer())) {
|
||||
const auto& indexBufferResource = indexBuffer->buffer->getResource<IndexBufferResource>().get();
|
||||
commandBuffer->bindIndexBuffer(indexBufferResource.getVulkanBuffer(), 0, vk::IndexType::eUint16);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
namespace mbgl {
|
||||
namespace vulkan {
|
||||
|
||||
RenderPass::RenderPass(CommandEncoder& commandEncoder_, const char* name, const gfx::RenderPassDescriptor& descriptor)
|
||||
: descriptor(descriptor),
|
||||
RenderPass::RenderPass(CommandEncoder& commandEncoder_, const char* name, const gfx::RenderPassDescriptor& descriptor_)
|
||||
: descriptor(descriptor_),
|
||||
commandEncoder(commandEncoder_) {
|
||||
auto& resource = descriptor.renderable.getResource<RenderableResource>();
|
||||
|
||||
|
||||
@@ -95,9 +95,9 @@ const gfx::UniqueVertexBufferResource& UploadPass::getBuffer(const gfx::VertexVe
|
||||
|
||||
// If it's changed, update it
|
||||
if (rawBufSize <= resource.getSizeInBytes()) {
|
||||
if (vec->getDirty()) {
|
||||
if (vec->isModifiedAfter(resource.getLastUpdated())) {
|
||||
updateVertexBufferResource(resource, rawBufPtr, rawBufSize);
|
||||
vec->setDirty(false);
|
||||
resource.setLastUpdated(vec->getLastModified());
|
||||
}
|
||||
return rawData->resource;
|
||||
}
|
||||
@@ -107,7 +107,6 @@ const gfx::UniqueVertexBufferResource& UploadPass::getBuffer(const gfx::VertexVe
|
||||
auto buffer = std::make_unique<VertexBuffer>();
|
||||
buffer->resource = createVertexBufferResource(rawBufPtr, rawBufSize, usage, /*persistent=*/false);
|
||||
vec->setBuffer(std::move(buffer));
|
||||
vec->setDirty(false);
|
||||
return static_cast<VertexBuffer*>(vec->getBuffer())->resource;
|
||||
}
|
||||
}
|
||||
@@ -122,6 +121,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
const gfx::VertexAttributeArray& defaults,
|
||||
const gfx::VertexAttributeArray& overrides,
|
||||
const gfx::BufferUsageType usage,
|
||||
const std::chrono::duration<double> /*lastUpdate*/,
|
||||
/*out*/ std::vector<std::unique_ptr<gfx::VertexBufferResource>>&) {
|
||||
gfx::AttributeBindingArray bindings;
|
||||
|
||||
@@ -175,8 +175,11 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
|
||||
|
||||
assert(false);
|
||||
};
|
||||
|
||||
defaults.resolve(overrides, resolveAttr);
|
||||
// This version is called when the attribute is available, but isn't being used by the shader
|
||||
const auto missingAttr = [&](const size_t, auto& attr_) -> void {
|
||||
attr_->setDirty(false);
|
||||
};
|
||||
defaults.resolve(overrides, resolveAttr, missingAttr);
|
||||
|
||||
return bindings;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ const gfx::UniqueVertexBufferResource& VertexAttribute::getBuffer(gfx::VertexAtt
|
||||
attrib.rawData.data(), attrib.rawData.size(), usage, false);
|
||||
attrib.setBuffer(std::move(buffer));
|
||||
attrib.setRawData({});
|
||||
attrib_.setDirty(false);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
@@ -33,18 +34,5 @@ const gfx::UniqueVertexBufferResource& VertexAttribute::getBuffer(gfx::VertexAtt
|
||||
return attrib_.getBuffer();
|
||||
}
|
||||
|
||||
bool VertexAttributeArray::isDirty() const {
|
||||
return std::any_of(attrs.begin(), attrs.end(), [](const auto& attr) {
|
||||
if (attr) {
|
||||
// If we have shared data, the dirty flag from that overrides ours
|
||||
const auto& attrib = static_cast<const VertexAttribute&>(*attr);
|
||||
if (const auto& shared = attrib.getSharedRawData()) {
|
||||
return shared->getDirty();
|
||||
}
|
||||
}
|
||||
return attr && attr->isDirty();
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace vulkan
|
||||
} // namespace mbgl
|
||||
|
||||
Reference in New Issue
Block a user