From b85297334ee3b59a738eec4dd8560979b0591c37 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 2 Feb 2024 20:49:09 +0000 Subject: Map buffers RO if const operations, upgrade to RW as required --- lib/glContainer.h | 78 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 30 deletions(-) (limited to 'lib') diff --git a/lib/glContainer.h b/lib/glContainer.h index 1cdeee0..4960e3c 100644 --- a/lib/glContainer.h +++ b/lib/glContainer.h @@ -7,6 +7,9 @@ #include #include +static_assert(GL_READ_ONLY < GL_READ_WRITE); +static_assert(GL_WRITE_ONLY < GL_READ_WRITE); + template class glContainer { public: using span = std::span; @@ -49,84 +52,84 @@ public: [[nodiscard]] iterator begin() { - map(); + map(GL_READ_WRITE); return mkspan().begin(); } [[nodiscard]] iterator end() { - map(); + map(GL_READ_WRITE); return mkspan().end(); } [[nodiscard]] const_iterator begin() const { - map(); + map(GL_READ_ONLY); return mkcspan().begin(); } [[nodiscard]] const_iterator end() const { - map(); + map(GL_READ_ONLY); return mkcspan().end(); } [[nodiscard]] const_iterator cbegin() const { - map(); + map(GL_READ_ONLY); return mkcspan().begin(); } [[nodiscard]] const_iterator cend() const { - map(); + map(GL_READ_ONLY); return mkcspan().end(); } [[nodiscard]] reverse_iterator rbegin() { - map(); + map(GL_READ_WRITE); return mkspan().rbegin(); } [[nodiscard]] reverse_iterator rend() { - map(); + map(GL_READ_WRITE); return mkspan().rend(); } [[nodiscard]] const_reverse_iterator rbegin() const { - map(); + map(GL_READ_ONLY); return mkcspan().rbegin(); } [[nodiscard]] const_reverse_iterator rend() const { - map(); + map(GL_READ_ONLY); return mkcspan().rend(); } [[nodiscard]] const_reverse_iterator crbegin() const { - map(); + map(GL_READ_ONLY); return mkcspan().rbegin(); } [[nodiscard]] const_reverse_iterator crend() const { - map(); + map(GL_READ_ONLY); return mkcspan().rend(); } @@ -164,7 +167,7 @@ public: if (pos >= size()) { throw std::out_of_range {__FUNCTION__}; } - map(); + map(GL_READ_WRITE); return mkspan()[pos]; } @@ -174,63 +177,63 @@ public: if (pos >= size()) { throw std::out_of_range {__FUNCTION__}; } - map(); + map(GL_READ_ONLY); return mkcspan()[pos]; } [[nodiscard]] reference_type operator[](size_type pos) { - map(); + map(GL_READ_WRITE); return mkspan()[pos]; } [[nodiscard]] const_reference_type operator[](size_type pos) const { - map(); + map(GL_READ_ONLY); return mkcspan()[pos]; } [[nodiscard]] pointer_type data() { - map(); + map(GL_READ_WRITE); return data_; } [[nodiscard]] const_pointer_type data() const { - map(); + map(GL_READ_ONLY); return data_; } [[nodiscard]] reference_type front() { - map(); + map(GL_READ_WRITE); return mkspan().front(); } [[nodiscard]] reference_type back() { - map(); + map(GL_READ_WRITE); return mkspan().back(); } [[nodiscard]] const_reference_type front() const { - map(); + map(GL_READ_ONLY); return mkcspan().front(); } [[nodiscard]] const_reference_type back() const { - map(); + map(GL_READ_ONLY); return mkcspan().back(); } @@ -252,6 +255,7 @@ public: if (data_) { glUnmapNamedBuffer(buffer_); data_ = {}; + access_ = {}; } } @@ -308,10 +312,10 @@ public: std::vector existing; existing.reserve(size_); - map(); + map(is_trivial_dest ? GL_READ_ONLY : GL_READ_WRITE); std::move(begin(), end(), std::back_inserter(existing)); allocBuffer(size_); - map(); + map(GL_READ_WRITE); std::move(existing.begin(), existing.end(), begin()); } @@ -319,7 +323,7 @@ public: clear() noexcept(is_trivial_dest) { if constexpr (!is_trivial_dest) { - map(); + map(GL_READ_WRITE); std::for_each(begin(), end(), [](auto && v) { v.~T(); }); @@ -389,7 +393,7 @@ public: pop_back() { if constexpr (!is_trivial_dest) { - map(); + map(GL_READ_WRITE); back().~T(); } --size_; @@ -405,7 +409,7 @@ public: erase(iterator pos, iterator to) { const auto eraseSize = to - pos; - map(); + map(GL_READ_WRITE); std::move(to, end(), pos); if constexpr (!is_trivial_dest) { std::for_each(end() - eraseSize, end(), [](auto && v) { @@ -433,13 +437,14 @@ protected: glBindBuffer(GL_ARRAY_BUFFER, 0); capacity_ = newCapacity; data_ = {}; + access_ = {}; } void - map() const + map(GLenum access) const { if (size_ > 0) { - mapForAdd(); + mapMode(access); } } @@ -447,8 +452,20 @@ protected: mapForAdd() const { if (!data_) { - data_ = static_cast(glMapNamedBuffer(buffer_, GL_READ_WRITE)); + mapMode(GL_READ_WRITE); + } + } + + void + mapMode(GLenum access) const + { + if (data_ && access_ < access) { + unmap(); + } + if (!data_) { + data_ = static_cast(glMapNamedBuffer(buffer_, access)); assert(data_); + access_ = access; } } @@ -470,4 +487,5 @@ protected: std::size_t capacity_ {}; std::size_t size_ {}; mutable T * data_; + mutable GLenum access_ {}; }; -- cgit v1.2.3