133 lines
3.5 KiB
C++
133 lines
3.5 KiB
C++
#pragma once
|
|
|
|
#include <mbgl/gfx/draw_mode.hpp>
|
|
#include <mbgl/util/ignore.hpp>
|
|
#include <mbgl/util/monotonic_timer.hpp>
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
namespace mbgl {
|
|
namespace gfx {
|
|
|
|
struct IndexBufferBase {
|
|
virtual ~IndexBufferBase() = default;
|
|
};
|
|
|
|
class IndexVectorBase {
|
|
protected:
|
|
std::vector<uint16_t> v;
|
|
|
|
public:
|
|
using value_type = decltype(v)::value_type;
|
|
|
|
IndexVectorBase() = default;
|
|
IndexVectorBase(std::vector<uint16_t>&& indexes)
|
|
: v(std::move(indexes)) {}
|
|
IndexVectorBase(const IndexVectorBase& other)
|
|
: v(other.v) {} // buffer is not copied
|
|
IndexVectorBase(IndexVectorBase&& other)
|
|
: v(std::move(other.v)),
|
|
#if MLN_DRAWABLE_RENDERER
|
|
buffer(std::move(other.buffer)),
|
|
#endif // MLN_DRAWABLE_RENDERER
|
|
dirty(other.dirty),
|
|
released(other.released) {
|
|
}
|
|
virtual ~IndexVectorBase() = default;
|
|
|
|
#if MLN_DRAWABLE_RENDERER
|
|
IndexBufferBase* getBuffer() const { return buffer.get(); }
|
|
void setBuffer(std::unique_ptr<IndexBufferBase>&& value) { buffer = std::move(value); }
|
|
#endif // MLN_DRAWABLE_RENDERER
|
|
|
|
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; }
|
|
|
|
void reserve(std::size_t count) { v.reserve(count); }
|
|
|
|
void extend(std::size_t n, const uint16_t val) {
|
|
assert(!released);
|
|
v.resize(v.size() + n, val);
|
|
dirty = true;
|
|
}
|
|
|
|
uint16_t& at(std::size_t n) {
|
|
assert(n < v.size());
|
|
assert(!released);
|
|
dirty = true;
|
|
return v.at(n);
|
|
}
|
|
const uint16_t& at(std::size_t n) const {
|
|
assert(n < v.size());
|
|
return v.at(n);
|
|
}
|
|
|
|
std::size_t elements() const { return v.size(); }
|
|
|
|
std::size_t bytes() const { return v.size() * sizeof(uint16_t); }
|
|
|
|
bool empty() const { return v.empty(); }
|
|
|
|
void clear() {
|
|
dirty = true;
|
|
v.clear();
|
|
#if MLN_DRAWABLE_RENDERER
|
|
buffer.reset();
|
|
#endif // MLN_DRAWABLE_RENDERER
|
|
}
|
|
|
|
/// Indicate that this shared index vector will no longer be updated.
|
|
void release() {
|
|
#if MLN_DRAWABLE_RENDERER
|
|
// If we've already created a buffer, we don't need the raw data any more.
|
|
if (buffer) {
|
|
v.clear();
|
|
}
|
|
#endif // MLN_DRAWABLE_RENDERER
|
|
released = true;
|
|
}
|
|
|
|
const uint16_t* data() const { return v.data(); }
|
|
|
|
const std::vector<uint16_t>& vector() const { return v; }
|
|
|
|
protected:
|
|
#if MLN_DRAWABLE_RENDERER
|
|
std::unique_ptr<IndexBufferBase> buffer;
|
|
#endif // MLN_DRAWABLE_RENDERER
|
|
bool dirty = true;
|
|
bool released = false;
|
|
|
|
std::chrono::duration<double> lastModified = util::MonotonicTimer::now();
|
|
};
|
|
|
|
using IndexVectorBasePtr = std::shared_ptr<IndexVectorBase>;
|
|
|
|
template <class DrawMode>
|
|
class IndexVector final : public IndexVectorBase {
|
|
public:
|
|
static constexpr std::size_t groupSize = BufferGroupSizeOf<DrawMode>::value;
|
|
|
|
template <class... Args>
|
|
void emplace_back(Args&&... args) {
|
|
static_assert(sizeof...(args) % groupSize == 0, "wrong buffer element count");
|
|
assert(!released);
|
|
util::ignore({(v.emplace_back(std::forward<Args>(args)), 0)...});
|
|
}
|
|
};
|
|
|
|
using IndexVectorBasePtr = std::shared_ptr<IndexVectorBase>;
|
|
|
|
} // namespace gfx
|
|
} // namespace mbgl
|