]> 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 ecf7b49a15e35d29493c83f1a6ea2f8013065483..36ac440a54426c186c16ae238c51a337312445e8 100644 (file)
@@ -1,38 +1,14 @@
 #include <stdexcept>
-#include <msp/gl/extensions/arb_buffer_storage.h>
-#include <msp/gl/extensions/arb_direct_state_access.h>
-#include <msp/gl/extensions/arb_map_buffer_range.h>
-#include <msp/gl/extensions/khr_debug.h>
 #include <msp/strings/format.h>
 #include "buffer.h"
-#include "deviceinfo.h"
 #include "error.h"
-#include "misc.h"
-#include "vertexsetup.h"
 
 using namespace std;
 
 namespace Msp {
 namespace GL {
 
-Buffer::Buffer():
-       size(0),
-       allocated(false)
-{
-       static Require _req(ARB_vertex_buffer_object);
-
-       if(ARB_direct_state_access)
-               glCreateBuffers(1, &id);
-       else
-               glGenBuffers(1, &id);
-}
-
-Buffer::~Buffer()
-{
-       glDeleteBuffers(1, &id);
-}
-
-void Buffer::storage(unsigned sz)
+void Buffer::storage(size_t sz, BufferUsage u)
 {
        if(size>0)
        {
@@ -44,85 +20,37 @@ void Buffer::storage(unsigned sz)
                throw invalid_argument("Buffer::storage");
 
        size = sz;
-}
-
-void Buffer::allocate()
-{
-       if(size==0)
-               throw invalid_operation("Buffer::allocate");
-       if(allocated)
-               return;
+       usage = u;
 
-       if(ARB_buffer_storage)
-       {
-               static const int flags = GL_MAP_READ_BIT|GL_MAP_WRITE_BIT|GL_DYNAMIC_STORAGE_BIT;
-               if(ARB_direct_state_access)
-                       glNamedBufferStorage(id, size, 0, flags);
-               else
-               {
-                       glBindBuffer(GL_ARRAY_BUFFER, id);
-                       glBufferStorage(GL_ARRAY_BUFFER, size, 0, flags);
-                       glBindBuffer(GL_ARRAY_BUFFER, 0);
-               }
-
-               allocated = true;
-       }
-       else
-               data(0);
+       allocate();
 }
 
-void Buffer::set_usage(BufferUsage)
+void Buffer::data(const void *d)
 {
+       return sub_data(0, size, d);
 }
 
-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::data");
-
-       if(ARB_buffer_storage)
-               return sub_data(0, size, d);
-
-       if(ARB_direct_state_access)
-               glNamedBufferData(id, size, d, STATIC_DRAW);
-       else
-       {
-               glBindBuffer(GL_ARRAY_BUFFER, id);
-               glBufferData(GL_ARRAY_BUFFER, size, d, STATIC_DRAW);
-               glBindBuffer(GL_ARRAY_BUFFER, 0);
-       }
-
-       allocated = true;
+       check_sub_data(off, sz, "Buffer::sub_data");
+       BufferBackend::sub_data(off, sz, d);
 }
 
-void Buffer::data(unsigned sz, const void *d)
+Buffer::AsyncTransfer Buffer::sub_data_async(size_t off, size_t sz)
 {
-       if(size==0)
-               storage(sz);
-       else if(sz!=size)
-               throw incompatible_data("Buffer::data");
-
-       data(d);
+       check_sub_data(off, sz, "Buffer::sub_data_async");
+       return AsyncTransfer(*this, off, sz);
 }
 
-void Buffer::sub_data(unsigned off, unsigned sz, const void *d)
+void Buffer::check_sub_data(size_t off, size_t sz, const char *func)
 {
        if(size==0)
-               throw invalid_operation("Buffer::sub_data");
-
-       allocate();
-
-       if(ARB_direct_state_access)
-               glNamedBufferSubData(id, off, sz, d);
-       else
-       {
-               glBindBuffer(GL_ARRAY_BUFFER, id);
-               glBufferSubData(GL_ARRAY_BUFFER, off, sz, d);
-               glBindBuffer(GL_ARRAY_BUFFER, 0);
-       }
+               throw invalid_operation(func);
+       if(off>get_total_size() || off%size+sz>size)
+               throw out_of_range(func);
 }
 
-void Buffer::require_size(unsigned req_sz) const
+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));
@@ -130,44 +58,60 @@ void Buffer::require_size(unsigned req_sz) const
 
 void *Buffer::map()
 {
-       static Require _req(ARB_map_buffer_range);
+       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();
-       if(ARB_direct_state_access)
-               return glMapNamedBufferRange(id, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
-       else
-       {
-               glBindBuffer(GL_ARRAY_BUFFER, id);
-               void *result = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
-               glBindBuffer(GL_ARRAY_BUFFER, 0);
-               return result;
-       }
 }
 
-bool Buffer::unmap()
+Buffer::AsyncTransfer::AsyncTransfer(AsyncTransfer &&other):
+       buffer(other.buffer),
+       offset(other.offset),
+       size(other.size),
+       dest_addr(other.dest_addr)
 {
-       // TODO check if it's mapped
-       if(ARB_direct_state_access)
-               return glUnmapNamedBuffer(id);
-       else if(OES_mapbuffer)
-       {
-               glBindBuffer(GL_ARRAY_BUFFER, id);
-               bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
-               glBindBuffer(GL_ARRAY_BUFFER, 0);
-               return result;
-       }
-       else
-               return true;
+       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;
 }
 
-void Buffer::set_debug_name(const string &name)
+Buffer::AsyncTransfer::~AsyncTransfer()
 {
-#ifdef DEBUG
-       if(KHR_debug)
-               glObjectLabel(GL_BUFFER, id, name.size(), name.c_str());
-#else
-       (void)name;
-#endif
+       if(dest_addr)
+               finalize();
 }
 
 } // namespace GL