X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcore%2Fbufferable.h;fp=source%2Fcore%2Fbufferable.h;h=cbbde4e1b93f1e07266c097c150774f2b5621d3c;hb=7aaec9a70b8d7733429bec043f8e33e02956f266;hp=0000000000000000000000000000000000000000;hpb=bec07999d95b76f4b47cffcc564d0cd0afc0435e;p=libs%2Fgl.git diff --git a/source/core/bufferable.h b/source/core/bufferable.h new file mode 100644 index 00000000..cbbde4e1 --- /dev/null +++ b/source/core/bufferable.h @@ -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