]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/bufferable.h
Rearrange soucre files into subdirectories
[libs/gl.git] / source / core / bufferable.h
diff --git a/source/core/bufferable.h b/source/core/bufferable.h
new file mode 100644 (file)
index 0000000..cbbde4e
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef MSP_GL_BUFFERABLE_H_
+#define MSP_GL_BUFFERABLE_H_
+
+namespace Msp {
+namespace GL {
+
+class Buffer;
+
+/**
+Base class for things that can store data in buffers.  Supports buffer sharing.
+A dirty flag is provided for derived classes.  It should be set when the data
+in the buffer is considered out of date, and is cleared by Bufferable after
+uploading fresh data to the buffer.
+*/
+class Bufferable
+{
+public:
+       class AsyncUpdater
+       {
+       private:
+               const Bufferable &bufferable;
+               char *mapped_address;
+
+       public:
+               AsyncUpdater(const Bufferable &);
+               ~AsyncUpdater();
+
+               void upload_data();
+       };
+
+private:
+       Buffer *buffer;
+       unsigned offset;
+       Bufferable *next_in_buffer;
+       Bufferable *prev_in_buffer;
+       mutable bool location_dirty;
+protected:
+       mutable bool dirty;
+
+       Bufferable();
+public:
+       virtual ~Bufferable();
+
+       /** Sets the buffer to use.  If prev is not null, it must use the same
+       buffer, and this object is inserted after it. */
+       void use_buffer(Buffer *buf, Bufferable *prev = 0);
+
+       /** Sets the buffer for the entire chain of objects. */
+       void change_buffer(Buffer *);
+
+       /** Returns the total amount of storage required by this object and others
+       in the same chain, including any alignment between objects. */
+       unsigned get_required_buffer_size() const;
+
+       /** Uploads new data into the buffer if necessary. */
+       void refresh() const { if(buffer && dirty) upload_data(0); }
+
+       /** Returns an object which can be used to upload data to the buffer using
+       mapped memory. */
+       AsyncUpdater *refresh_async() const;
+
+private:
+       void unlink_from_buffer();
+
+public:
+       /** Returns the buffer in which the data is stored. */
+       const Buffer *get_buffer() const { return buffer; }
+
+protected:
+       /** Returns the amount of data to be stored in the buffer, in bytes. */
+       virtual unsigned get_data_size() const = 0;
+
+       /** Returns a pointer to the start of data in client memory. */
+       virtual const void *get_data_pointer() const = 0;
+
+       /** Returns the alignment required for the data, in bytes.  The offset is
+       guaranteed to be a multiple of this. */
+       virtual unsigned get_alignment() const { return 1; }
+
+       /** Updates the offsets for the chain so that data from different objects
+       does not overlap.  Should be called if either data size or alignment
+       changes. */
+       void update_offset();
+
+       /** Returns the offset where the data should be uploaded. */
+       unsigned get_offset() const { return offset; }
+
+       /** Called when the target buffer or offset within it has changed. */
+       virtual void location_changed(Buffer *, unsigned, unsigned) const { }
+
+private:
+       /** Uploads data to the buffer.  Receives pointer to mapped buffer memory as
+       parameter, or null to use the buffer upload interface. */
+       void upload_data(char *) const;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif