Skip to content

Commit

Permalink
Use timestamps for attribute updates (maplibre#2629)
Browse files Browse the repository at this point in the history
  • Loading branch information
TimSylvester authored Aug 20, 2024
1 parent c3a2fa2 commit fceaa18
Show file tree
Hide file tree
Showing 43 changed files with 438 additions and 162 deletions.
6 changes: 5 additions & 1 deletion include/mbgl/gfx/drawable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
#include <mbgl/gfx/uniform_buffer.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/util/color.hpp>
#include <mbgl/util/containers.hpp>
#include <mbgl/util/identity.hpp>
#include <mbgl/util/monotonic_timer.hpp>
#include <mbgl/util/traits.hpp>
#include <mbgl/util/containers.hpp>

#include <cstdint>
#include <cstddef>
Expand Down Expand Up @@ -244,6 +245,8 @@ class Drawable {
/// 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;
Expand All @@ -264,6 +267,7 @@ class Drawable {
UniqueDrawableData drawableData{};
gfx::VertexAttributeArrayPtr vertexAttributes;
gfx::VertexAttributeArrayPtr instanceAttributes;
std::chrono::duration<double> attributeUpdateTime = util::MonotonicTimer::now();

struct Impl;
std::unique_ptr<Impl> impl;
Expand Down
32 changes: 23 additions & 9 deletions include/mbgl/gfx/vertex_attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class VertexAttribute {
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
Expand Down Expand Up @@ -180,12 +180,16 @@ class VertexAttribute {
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) {}

Expand Down Expand Up @@ -255,6 +259,9 @@ class VertexAttribute {
}

protected:
friend class VertexAttributeArray;
bool isDirty() const { return dirty; }

int index;
std::size_t stride;

Expand Down Expand Up @@ -310,8 +317,9 @@ class VertexAttributeArray {
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
Expand All @@ -328,11 +336,17 @@ class VertexAttributeArray {
}

/// 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);
}
}
}
Expand Down
9 changes: 4 additions & 5 deletions include/mbgl/gl/vertex_attribute_gl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ class VertexAttributeGL final : public gfx::VertexAttribute {
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);
Expand All @@ -58,9 +60,6 @@ class VertexAttributeArrayGL final : public gfx::VertexAttributeArray {
}
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,
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/mtl/upload_pass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class UploadPass final : public gfx::UploadPass {
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,
Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/mtl/vertex_attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class VertexAttributeArray final : public gfx::VertexAttributeArray {
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 {
Expand Down
5 changes: 5 additions & 0 deletions include/mbgl/mtl/vertex_buffer_resource.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <mbgl/mtl/buffer_resource.hpp>
#include <mbgl/util/monotonic_timer.hpp>

#include <memory>

Expand All @@ -21,8 +22,12 @@ class VertexBufferResource : public gfx::VertexBufferResource {
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>;
Expand Down
12 changes: 6 additions & 6 deletions include/mbgl/util/instrumentation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions include/mbgl/vulkan/upload_pass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class UploadPass final : public gfx::UploadPass {
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,
Expand Down
3 changes: 0 additions & 3 deletions include/mbgl/vulkan/vertex_attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ class VertexAttributeArray final : public gfx::VertexAttributeArray {
}
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);
Expand Down
4 changes: 4 additions & 0 deletions include/mbgl/vulkan/vertex_buffer_resource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ class VertexBufferResource : public gfx::VertexBufferResource {
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>;
Expand Down
14 changes: 12 additions & 2 deletions src/mbgl/gfx/index_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -40,8 +41,15 @@ class IndexVectorBase {
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; }

Expand Down Expand Up @@ -99,6 +107,8 @@ class IndexVectorBase {
#endif // MLN_DRAWABLE_RENDERER
bool dirty = true;
bool released = false;

std::chrono::duration<double> lastModified = util::MonotonicTimer::now();
};

using IndexVectorBasePtr = std::shared_ptr<IndexVectorBase>;
Expand Down
1 change: 1 addition & 0 deletions src/mbgl/gfx/upload_pass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class UploadPass {
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

Expand Down
15 changes: 13 additions & 2 deletions src/mbgl/gfx/vertex_vector.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <mbgl/util/ignore.hpp>
#include <mbgl/util/monotonic_timer.hpp>

#include <memory>
#include <vector>
Expand Down Expand Up @@ -35,9 +36,17 @@ class VertexVectorBase {
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:
Expand All @@ -46,6 +55,8 @@ class VertexVectorBase {
#endif // MLN_DRAWABLE_RENDERER
bool dirty = true;
bool released = false;

std::chrono::duration<double> lastModified = util::MonotonicTimer::now();
};
using VertexVectorBasePtr = std::shared_ptr<VertexVectorBase>;

Expand Down
28 changes: 24 additions & 4 deletions src/mbgl/gl/drawable_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -22,6 +23,8 @@ DrawableGL::~DrawableGL() {
}

void DrawableGL::draw(PaintParameters& parameters) const {
MLN_TRACE_FUNC();

if (isCustom) {
return;
}
Expand Down Expand Up @@ -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;
Expand All @@ -173,23 +185,28 @@ 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(),
std::move(indexBufferResource));
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();

Expand All @@ -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(
Expand All @@ -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();
Expand Down
3 changes: 3 additions & 0 deletions src/mbgl/gl/layer_group_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading

0 comments on commit fceaa18

Please sign in to comment.