X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcore%2Fbufferable.h;h=25d29fd8f393021c6d6af4f86e624d77ec79705b;hb=5003bcfeb0832ec2d0f74f4149bc97888a70a900;hp=47e2770c58675fd128d16afa6b50446e7f53a62f;hpb=9b3bce7ae76ff8c0c81315d2505ea96bf422a318;p=libs%2Fgl.git diff --git a/source/core/bufferable.h b/source/core/bufferable.h index 47e2770c..25d29fd8 100644 --- a/source/core/bufferable.h +++ b/source/core/bufferable.h @@ -1,20 +1,27 @@ #ifndef MSP_GL_BUFFERABLE_H_ #define MSP_GL_BUFFERABLE_H_ +#include + 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. +Base class for things that can store data in buffers. Multiple Bufferables +may be put in the same buffer. + +Derived classes should call mark_dirty() when the stored data has changed. */ -class Bufferable +class Bufferable: public NonCopyable { public: + /** + Uploads data to the buffer asynchronously, through a memory mapping. API + calls are done in the constructor and desctructor, so upload_data may be + called from a different thread. + */ class AsyncUpdater { private: @@ -29,35 +36,38 @@ public: }; private: - Buffer *buffer; - unsigned offset; - Bufferable *next_in_buffer; - Bufferable *prev_in_buffer; - mutable bool location_dirty; -protected: - mutable bool dirty; + Buffer *buffer = 0; + std::size_t offset = 0; + Bufferable *next_in_buffer = 0; + Bufferable *prev_in_buffer = 0; + mutable bool location_dirty = false; + mutable uint8_t dirty = 0; - Bufferable(); +protected: + Bufferable() = default; + Bufferable(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); + buffer, and this object is inserted after it. + + Data is not uploaded immediately, but only when refresh() is called. */ + void use_buffer(Buffer *, 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; + in the same chain, including any padding required by object alignment. */ + std::size_t get_required_buffer_size(bool = false) const; /** Uploads new data into the buffer if necessary. */ - void refresh() const { if(buffer && dirty) upload_data(0); } + void refresh(unsigned f) const { if(dirty&(1<