#include <stdexcept>
#include <string>
-#include <vector>
-#include "gl.h"
+#include "buffer_backend.h"
namespace Msp {
namespace GL {
virtual ~buffer_too_small() throw() { }
};
-class BufferRange;
+enum BufferUsage
+{
+ STATIC,
+ STREAMING
+};
/**
-A buffer for storing data in GL memory. Putting vertex and index data in
-buffers can improve rendering performance. The VertexArray, Mesh and
-UniformBlock classes contain built-in support for buffers.
+Stores data in GPU memory.
+
+Memory must be allocated for the buffer by calling storage(). Contents can
+then be modified either synchronously with the data() and sub_data() functions,
+or asynchronously by memory-mapping the buffer.
+
+Buffers can have a static or streaming usage pattern. Streaming buffers can be
+memory mapped for less update overhead, but memory space is more limited. If
+the buffer is updated only rarely, static is recommended.
+
+Applications normally don't need to deal with Buffers directly. They're
+managed by other classes such as Mesh and ProgramData.
*/
-class Buffer
+class Buffer: public BufferBackend
{
- friend class PipelineState;
- friend class Texture2D;
- friend class VertexSetup;
+ friend BufferBackend;
private:
- unsigned id;
- unsigned size;
-
- static Buffer *scratch_binding;
+ std::size_t size = 0;
+ BufferUsage usage = STATIC;
+ bool mapped = false;
public:
- Buffer();
- ~Buffer();
-
- /** Defines the storage size of the buffer. Must be called before data can
- be uploaded. Storage cannot be changed once set. */
- void storage(unsigned);
+ /** Sets storage size and usage pattern and allocates memory for the buffer.
+ Size and usage cannot be changed once set. */
+ void storage(std::size_t, BufferUsage);
- /** Uploads data into the buffer, completely replacing any previous
- contents. Storage must be defined beforehand. The data must have size
- matching the defined storage. */
+ /** Replaces contents of the entire buffer. Allocated storage must exist.
+ The data must have size matching the defined storage. */
void data(const void *);
- /** Overwrites part of the buffer data with new data. Storage must be
- defined beforehand. */
- void sub_data(unsigned, unsigned, const void *);
+ /** Replaces a range of bytes in the buffer. Allocated storage must exist.
+ The range must be fully inside the buffer. */
+ void sub_data(std::size_t, std::size_t, const void *);
- unsigned get_size() const { return size; }
+ std::size_t get_size() const { return size; }
+ using BufferBackend::get_multiplicity;
+ std::size_t get_total_size() const { return size*get_multiplicity(); }
+ BufferUsage get_usage() const { return usage; }
- void require_size(unsigned) const;
+ void require_size(std::size_t) const;
void *map();
bool unmap();
- void set_debug_name(const std::string &);
-
-private:
- void bind_scratch();
-public:
- static void unbind_scratch();
+ using BufferBackend::set_debug_name;
};
} // namespace GL