]> git.tdb.fi Git - libs/gl.git/blob - source/core/bufferable.h
Check the flat qualifier from the correct member
[libs/gl.git] / source / core / bufferable.h
1 #ifndef MSP_GL_BUFFERABLE_H_
2 #define MSP_GL_BUFFERABLE_H_
3
4 #include <cstddef>
5 #include <msp/core/noncopyable.h>
6 #include "buffer.h"
7
8 namespace Msp {
9 namespace GL {
10
11 /**
12 Base class for things that can store data in buffers.  Multiple Bufferables
13 may be put in the same buffer.
14
15 Derived classes should call mark_dirty() when the stored data has changed.
16 */
17 class Bufferable: public NonCopyable
18 {
19 public:
20         /**
21         Uploads data to the buffer asynchronously, through a memory mapping.  API
22         calls are done in the constructor and desctructor, so upload_data may be
23         called from a different thread.
24         */
25         class AsyncUpdater
26         {
27         private:
28                 const Bufferable &bufferable;
29                 Buffer::AsyncTransfer transfer;
30
31         public:
32                 AsyncUpdater(const Bufferable &);
33
34                 void upload_data();
35         };
36
37 private:
38         Buffer *buffer = 0;
39         std::size_t offset = 0;
40         Bufferable *next_in_buffer = 0;
41         Bufferable *prev_in_buffer = 0;
42         mutable bool location_dirty = false;
43         mutable uint8_t dirty = 0;
44
45 protected:
46         Bufferable() = default;
47         Bufferable(Bufferable &&);
48 public:
49         virtual ~Bufferable();
50
51         /** Sets the buffer to use.  If prev is not null, it must use the same
52         buffer, and this object is inserted after it.
53
54         Data is not uploaded immediately, but only when refresh() is called. */
55         void use_buffer(Buffer *, Bufferable *prev = 0);
56
57         /** Sets the buffer for the entire chain of objects. */
58         void change_buffer(Buffer *);
59
60         /** Returns the total amount of storage required by this object and others
61         in the same chain, including any padding required by object alignment. */
62         std::size_t get_required_buffer_size(bool = false) const;
63
64         /** Uploads new data into the buffer if necessary. */
65         void refresh(unsigned f) const { if(dirty) upload_data(f, 0); }
66
67         /** Returns an object which can be used to upload data to the buffer using
68         mapped memory.  If data is not dirty, returns null. */
69         AsyncUpdater *refresh_async() const { return dirty ? create_async_updater() : 0; }
70
71 private:
72         void unlink_from_buffer();
73
74 public:
75         /** Returns the buffer in which the data is stored. */
76         const Buffer *get_buffer() const { return buffer; }
77
78         /** Returns the size of the data, in bytes. */
79         virtual std::size_t get_data_size() const = 0;
80
81 protected:
82         /** Returns a pointer to the start of the data in client memory. */
83         virtual const void *get_data_pointer() const = 0;
84
85         /** Returns the alignment required for the data, in bytes.  The offset
86         within the buffer is guaranteed to be a multiple of the alignment. */
87         virtual std::size_t get_alignment() const { return 1; }
88
89         /** Updates the offsets for the chain so that data from different objects
90         does not overlap.  Should be called if either data size or alignment
91         changes. */
92         void update_offset();
93
94         /* Indicates that the data of the bufferable has changed and should be
95         uploaded to the buffer again. */
96         void mark_dirty();
97
98 public:
99         /** Returns the offset of the data from the beginning of the buffer. */
100         std::size_t get_offset() const { return offset; }
101
102 private:
103         /** Uploads data to the buffer.  Receives pointer to mapped buffer memory as
104         parameter, or null to use the buffer upload interface. */
105         void upload_data(unsigned, char *) const;
106
107         AsyncUpdater *create_async_updater() const;
108 };
109
110 } // namespace GL
111 } // namespace Msp
112
113 #endif