]> git.tdb.fi Git - libs/gl.git/blob - source/core/bufferable.h
Use size_t to store sizes of buffers and such
[libs/gl.git] / source / core / bufferable.h
1 #ifndef MSP_GL_BUFFERABLE_H_
2 #define MSP_GL_BUFFERABLE_H_
3
4 namespace Msp {
5 namespace GL {
6
7 class Buffer;
8
9 /**
10 Base class for things that can store data in buffers.  Supports buffer sharing.
11 A dirty flag is provided for derived classes.  It should be set when the data
12 in the buffer is considered out of date, and is cleared by Bufferable after
13 uploading fresh data to the buffer.
14 */
15 class Bufferable
16 {
17 public:
18         class AsyncUpdater
19         {
20         private:
21                 const Bufferable &bufferable;
22                 char *mapped_address;
23
24         public:
25                 AsyncUpdater(const Bufferable &);
26                 ~AsyncUpdater();
27
28                 void upload_data();
29         };
30
31 private:
32         Buffer *buffer = 0;
33         std::size_t offset = 0;
34         Bufferable *next_in_buffer = 0;
35         Bufferable *prev_in_buffer = 0;
36         mutable bool location_dirty = false;
37 protected:
38         mutable bool dirty = false;
39
40         Bufferable() = default;
41 public:
42         virtual ~Bufferable();
43
44         /** Sets the buffer to use.  If prev is not null, it must use the same
45         buffer, and this object is inserted after it. */
46         void use_buffer(Buffer *buf, Bufferable *prev = 0);
47
48         /** Sets the buffer for the entire chain of objects. */
49         void change_buffer(Buffer *);
50
51         /** Returns the total amount of storage required by this object and others
52         in the same chain, including any alignment between objects. */
53         std::size_t get_required_buffer_size() const;
54
55         /** Uploads new data into the buffer if necessary. */
56         void refresh() const { if(dirty) upload_data(0); }
57
58         /** Returns an object which can be used to upload data to the buffer using
59         mapped memory. */
60         AsyncUpdater *refresh_async() const { return dirty ? new AsyncUpdater(*this) : 0; }
61
62 private:
63         void unlink_from_buffer();
64
65 public:
66         /** Returns the buffer in which the data is stored. */
67         const Buffer *get_buffer() const { return buffer; }
68
69         /** Returns the size of the data, in bytes. */
70         virtual std::size_t get_data_size() const = 0;
71
72 protected:
73         /** Returns a pointer to the start of data in client memory. */
74         virtual const void *get_data_pointer() const = 0;
75
76         /** Returns the alignment required for the data, in bytes.  The offset is
77         guaranteed to be a multiple of this. */
78         virtual std::size_t get_alignment() const { return 1; }
79
80         /** Updates the offsets for the chain so that data from different objects
81         does not overlap.  Should be called if either data size or alignment
82         changes. */
83         void update_offset();
84
85 public:
86         /** Returns the offset of the data from the beginning of the buffer. */
87         std::size_t get_offset() const { return offset; }
88
89 private:
90         /** Uploads data to the buffer.  Receives pointer to mapped buffer memory as
91         parameter, or null to use the buffer upload interface. */
92         void upload_data(char *) const;
93 };
94
95 } // namespace GL
96 } // namespace Msp
97
98 #endif