]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/buffer.cpp
Check the flat qualifier from the correct member
[libs/gl.git] / source / core / buffer.cpp
index 240fcd72754b67babe7a28b9ee2fe42a80f1fe4b..36ac440a54426c186c16ae238c51a337312445e8 100644 (file)
@@ -8,7 +8,7 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-void Buffer::storage(size_t sz)
+void Buffer::storage(size_t sz, BufferUsage u)
 {
        if(size>0)
        {
@@ -20,6 +20,7 @@ void Buffer::storage(size_t sz)
                throw invalid_argument("Buffer::storage");
 
        size = sz;
+       usage = u;
 
        allocate();
 }
@@ -31,19 +32,87 @@ void Buffer::data(const void *d)
 
 void Buffer::sub_data(size_t off, size_t sz, const void *d)
 {
-       if(size==0)
-               throw invalid_operation("Buffer::sub_data");
-       if(off>size || off+sz>size)
-               throw out_of_range("Buffer::sub_data");
-
+       check_sub_data(off, sz, "Buffer::sub_data");
        BufferBackend::sub_data(off, sz, d);
 }
 
+Buffer::AsyncTransfer Buffer::sub_data_async(size_t off, size_t sz)
+{
+       check_sub_data(off, sz, "Buffer::sub_data_async");
+       return AsyncTransfer(*this, off, sz);
+}
+
+void Buffer::check_sub_data(size_t off, size_t sz, const char *func)
+{
+       if(size==0)
+               throw invalid_operation(func);
+       if(off>get_total_size() || off%size+sz>size)
+               throw out_of_range(func);
+}
+
 void Buffer::require_size(size_t req_sz) const
 {
        if(size<req_sz)
                throw buffer_too_small(format("buffer has %d bytes; %d required", size, req_sz));
 }
 
+void *Buffer::map()
+{
+       if(size==0 || !can_map() || mapped)
+               throw invalid_operation("Buffer::map");
+       void *result = BufferBackend::map();
+       mapped = true;
+       return result;
+}
+
+bool Buffer::unmap()
+{
+       if(size==0 || !can_map() || !mapped)
+               throw invalid_operation("Buffer::unmap");
+       bool result = BufferBackend::unmap();
+       mapped = false;
+       return result;
+}
+
+
+Buffer::AsyncTransfer::AsyncTransfer(Buffer &b, size_t o, size_t s):
+       buffer(&b),
+       offset(o),
+       size(s),
+       dest_addr(0)
+{
+       allocate();
+}
+
+Buffer::AsyncTransfer::AsyncTransfer(AsyncTransfer &&other):
+       buffer(other.buffer),
+       offset(other.offset),
+       size(other.size),
+       dest_addr(other.dest_addr)
+{
+       other.dest_addr = 0;
+}
+
+Buffer::AsyncTransfer &Buffer::AsyncTransfer::operator=(AsyncTransfer &&other)
+{
+       if(dest_addr)
+               finalize();
+
+       buffer = other.buffer;
+       offset = other.offset;
+       size = other.size;
+       dest_addr = other.dest_addr;
+
+       other.dest_addr = 0;
+
+       return *this;
+}
+
+Buffer::AsyncTransfer::~AsyncTransfer()
+{
+       if(dest_addr)
+               finalize();
+}
+
 } // namespace GL
 } // namespace Msp