/src/ogre/OgreMain/include/OgreHardwareBufferManager.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ----------------------------------------------------------------------------- |
3 | | This source file is part of OGRE |
4 | | (Object-oriented Graphics Rendering Engine) |
5 | | For the latest info, see http://www.ogre3d.org/ |
6 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #ifndef __HardwareBufferManager__ |
29 | | #define __HardwareBufferManager__ |
30 | | |
31 | | // Precompiler options |
32 | | #include "OgrePrerequisites.h" |
33 | | |
34 | | #include "OgreSingleton.h" |
35 | | #include "OgreHardwareIndexBuffer.h" |
36 | | #include "OgreHardwareVertexBuffer.h" |
37 | | #include "Threading/OgreThreadHeaders.h" |
38 | | #include "OgreHeaderPrefix.h" |
39 | | |
40 | | namespace Ogre { |
41 | | /** \addtogroup Core |
42 | | * @{ |
43 | | */ |
44 | | /** \addtogroup RenderSystem |
45 | | * @{ |
46 | | */ |
47 | | |
48 | | /** Abstract interface representing a 'licensee' of a hardware buffer copy. |
49 | | |
50 | | Often it's useful to have temporary buffers which are used for working |
51 | | but are not necessarily needed permanently. However, creating and |
52 | | destroying buffers is expensive, so we need a way to share these |
53 | | working areas, especially those based on existing fixed buffers. |
54 | | This class represents a licensee of one of those temporary buffers, |
55 | | and must be implemented by any user of a temporary buffer if they |
56 | | wish to be notified when the license is expired. |
57 | | */ |
58 | | class _OgreExport HardwareBufferLicensee |
59 | | { |
60 | | public: |
61 | 0 | virtual ~HardwareBufferLicensee() { } |
62 | | /** This method is called when the buffer license is expired and is about |
63 | | to be returned to the shared pool. |
64 | | */ |
65 | | virtual void licenseExpired(HardwareBuffer* buffer) = 0; |
66 | | }; |
67 | | |
68 | | /** Base definition of a hardware buffer manager. |
69 | | |
70 | | This class is deliberately not a Singleton, so that multiple types can |
71 | | exist at once (notably DefaultHardwareBufferManagerBase). |
72 | | The Singleton is add via the inheritance in HardwareBufferManager below. |
73 | | */ |
74 | | class _OgreExport HardwareBufferManagerBase : public BufferAlloc |
75 | | { |
76 | | protected: |
77 | | /** WARNING: The following member should place before all other members. |
78 | | Members destruct order is very important here, because destructing other |
79 | | members will cause notify back to this class, and then will access to this |
80 | | two members. |
81 | | */ |
82 | | typedef std::set<HardwareVertexBuffer*> VertexBufferList; |
83 | | typedef std::set<HardwareIndexBuffer*> IndexBufferList; |
84 | | VertexBufferList mVertexBuffers; |
85 | | |
86 | | |
87 | | typedef std::set<VertexDeclaration*> VertexDeclarationList; |
88 | | typedef std::set<VertexBufferBinding*> VertexBufferBindingList; |
89 | | VertexDeclarationList mVertexDeclarations; |
90 | | VertexBufferBindingList mVertexBufferBindings; |
91 | | |
92 | | // Mutexes |
93 | | OGRE_MUTEX(mVertexBuffersMutex); |
94 | | OGRE_MUTEX(mVertexDeclarationsMutex); |
95 | | OGRE_MUTEX(mVertexBufferBindingsMutex); |
96 | | |
97 | | /// Internal method for destroys all vertex declarations. |
98 | | void destroyAllDeclarations(void); |
99 | | /// Internal method for destroys all vertex buffer bindings. |
100 | | void destroyAllBindings(void); |
101 | | |
102 | | private: |
103 | | /// Internal method for creates a new vertex declaration, may be overridden by certain rendering APIs. |
104 | | virtual VertexDeclaration* createVertexDeclarationImpl(void); |
105 | | /// Internal method for destroys a vertex declaration, may be overridden by certain rendering APIs. |
106 | | void destroyVertexDeclarationImpl(VertexDeclaration* decl); |
107 | | |
108 | | /// Internal method for creates a new VertexBufferBinding, may be overridden by certain rendering APIs. |
109 | | virtual VertexBufferBinding* createVertexBufferBindingImpl(void); |
110 | | /// Internal method for destroys a VertexBufferBinding, may be overridden by certain rendering APIs. |
111 | | void destroyVertexBufferBindingImpl(VertexBufferBinding* binding); |
112 | | |
113 | | /** Struct holding details of a license to use a temporary shared buffer. */ |
114 | | class _OgrePrivate VertexBufferLicense |
115 | | { |
116 | | public: |
117 | | HardwareVertexBuffer* originalBufferPtr; |
118 | | size_t expiredDelay; |
119 | | HardwareVertexBufferSharedPtr buffer; |
120 | | HardwareBufferLicensee* licensee; |
121 | | VertexBufferLicense( |
122 | | HardwareVertexBuffer* orig, |
123 | | size_t delay, |
124 | | const HardwareVertexBufferSharedPtr& buf, |
125 | | HardwareBufferLicensee* lic) |
126 | | : originalBufferPtr(orig) |
127 | | , expiredDelay(delay) |
128 | | , buffer(buf) |
129 | | , licensee(lic) |
130 | 0 | {} |
131 | | |
132 | | }; |
133 | | |
134 | | /// Map from original buffer to temporary buffers. |
135 | | typedef std::multimap<HardwareVertexBuffer*, HardwareVertexBufferSharedPtr> FreeTemporaryVertexBufferMap; |
136 | | /// Map of current available temp buffers. |
137 | | FreeTemporaryVertexBufferMap mFreeTempVertexBufferMap; |
138 | | /// Map from temporary buffer to details of a license. |
139 | | typedef std::map<HardwareVertexBuffer*, VertexBufferLicense> TemporaryVertexBufferLicenseMap; |
140 | | /// Map of currently licensed temporary buffers. |
141 | | TemporaryVertexBufferLicenseMap mTempVertexBufferLicenses; |
142 | | /// Number of frames elapsed since temporary buffers utilization was above half the available. |
143 | | size_t mUnderUsedFrameCount; |
144 | | /// Number of frames to wait before free unused temporary buffers. |
145 | | static const size_t UNDER_USED_FRAME_THRESHOLD; |
146 | | /// Frame delay for temporary buffers. |
147 | | static const size_t EXPIRED_DELAY_FRAME_THRESHOLD; |
148 | | // Mutexes |
149 | | OGRE_MUTEX(mTempBuffersMutex); |
150 | | |
151 | | void _forceReleaseBufferCopies(HardwareVertexBuffer* sourceBuffer); |
152 | | public: |
153 | | HardwareBufferManagerBase(); |
154 | | virtual ~HardwareBufferManagerBase(); |
155 | | /** Create a hardware vertex buffer. |
156 | | |
157 | | This method creates a new vertex buffer; this will act as a source of geometry |
158 | | data for rendering objects. Note that because the meaning of the contents of |
159 | | the vertex buffer depends on the usage, this method does not specify a |
160 | | vertex format; the user of this buffer can actually insert whatever data |
161 | | they wish, in any format. However, in order to use this with a RenderOperation, |
162 | | the data in this vertex buffer will have to be associated with a semantic element |
163 | | of the rendering pipeline, e.g. a position, or texture coordinates. This is done |
164 | | using the VertexDeclaration class, which itself contains VertexElement structures |
165 | | referring to the source data. |
166 | | Note that because vertex buffers can be shared, they are reference |
167 | | counted so you do not need to worry about destroying them this will be done |
168 | | automatically. |
169 | | @param vertexSize |
170 | | The size in bytes of each vertex in this buffer; you must calculate |
171 | | this based on the kind of data you expect to populate this buffer with. |
172 | | @param numVerts |
173 | | The number of vertices in this buffer. |
174 | | @param usage |
175 | | One or more members of the #HardwareBufferUsage enumeration; you are |
176 | | strongly advised to use #HBU_GPU_ONLY wherever possible, if you need to |
177 | | update regularly, consider #HBU_CPU_TO_GPU or useShadowBuffer=true. |
178 | | @param useShadowBuffer |
179 | | If set to @c true, this buffer will be 'shadowed' by one stored in |
180 | | system memory rather than GPU memory. See @ref Shadow-Buffers. |
181 | | */ |
182 | | virtual HardwareVertexBufferSharedPtr |
183 | | createVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, |
184 | | bool useShadowBuffer = false) = 0; |
185 | | /** Create a hardware index buffer. |
186 | | @remarks Note that because buffers can be shared, they are reference |
187 | | counted so you do not need to worry about destroying them this will be done |
188 | | automatically. |
189 | | @param itype |
190 | | The type in index, either 16- or 32-bit, depending on how many vertices |
191 | | you need to be able to address |
192 | | @param numIndexes |
193 | | The number of indexes in the buffer |
194 | | @param usage |
195 | | One or more members of the #HardwareBufferUsage enumeration. |
196 | | @param useShadowBuffer |
197 | | If set to @c true, this buffer will be 'shadowed' by one stored in |
198 | | system memory rather than GPU memory. See @ref Shadow-Buffers. |
199 | | */ |
200 | | virtual HardwareIndexBufferSharedPtr |
201 | | createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, |
202 | | HardwareBuffer::Usage usage, bool useShadowBuffer = false) = 0; |
203 | | |
204 | | /** Create a render to vertex buffer. |
205 | | @remarks The parameters (such as vertex size etc) are determined later |
206 | | and are allocated when needed. |
207 | | */ |
208 | | virtual RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); |
209 | | |
210 | | /** |
211 | | * Create uniform buffer. This type of buffer allows the upload of shader constants once, |
212 | | * and sharing between shader stages or even shaders from another materials. |
213 | | * The update shall be triggered by GpuProgramParameters, if is dirty |
214 | | */ |
215 | | virtual HardwareBufferPtr createUniformBuffer(size_t sizeBytes, |
216 | | HardwareBufferUsage usage = HBU_CPU_TO_GPU, |
217 | | bool useShadowBuffer = false); |
218 | | |
219 | | /** Creates a new vertex declaration. */ |
220 | | VertexDeclaration* createVertexDeclaration(void); |
221 | | /** Destroys a vertex declaration. */ |
222 | | void destroyVertexDeclaration(VertexDeclaration* decl); |
223 | | |
224 | | /** Creates a new VertexBufferBinding. */ |
225 | | VertexBufferBinding* createVertexBufferBinding(void); |
226 | | /** Destroys a VertexBufferBinding. */ |
227 | | void destroyVertexBufferBinding(VertexBufferBinding* binding); |
228 | | |
229 | | /** Allocates a copy of a given vertex buffer. |
230 | | |
231 | | This method allocates a temporary copy of an existing vertex buffer. |
232 | | This buffer is subsequently stored and can be made available for |
233 | | other purposes later without incurring the cost of construction / |
234 | | destruction. |
235 | | @param sourceBuffer |
236 | | The source buffer to use as a copy. |
237 | | @param licensee |
238 | | Pointer back to the class requesting the copy, which must |
239 | | implement HardwareBufferLicense in order to be notified when the license |
240 | | expires. |
241 | | @param copyData |
242 | | If @c true, the current data is copied as well as the |
243 | | structure of the buffer/ |
244 | | */ |
245 | | HardwareVertexBufferSharedPtr allocateVertexBufferCopy( |
246 | | const HardwareVertexBufferSharedPtr& sourceBuffer, |
247 | | HardwareBufferLicensee* licensee, |
248 | | bool copyData = false); |
249 | | |
250 | | /** Manually release a vertex buffer copy for others to subsequently use. |
251 | | |
252 | | @param bufferCopy |
253 | | The buffer copy. The caller is expected to delete |
254 | | or at least no longer use this reference, since another user may |
255 | | well begin to modify the contents of the buffer. |
256 | | */ |
257 | | void releaseVertexBufferCopy(const HardwareVertexBufferSharedPtr& bufferCopy); |
258 | | |
259 | | /** Tell engine that the vertex buffer copy intent to reuse. |
260 | | |
261 | | Ogre internal keep an expired delay counter. |
262 | | When the counter count down to zero, it'll release for other |
263 | | purposes later. But you can use this function to reset the counter to |
264 | | the internal configured value, keep the buffer not get released for |
265 | | some frames. |
266 | | @param bufferCopy |
267 | | The buffer copy. The caller is expected to keep this |
268 | | buffer copy for use. |
269 | | */ |
270 | | void touchVertexBufferCopy(const HardwareVertexBufferSharedPtr& bufferCopy); |
271 | | |
272 | | /** Free all unused vertex buffer copies. |
273 | | |
274 | | This method free all temporary vertex buffers that not in used. |
275 | | In normally, temporary vertex buffers are subsequently stored and can |
276 | | be made available for other purposes later without incurring the cost |
277 | | of construction / destruction. But in some cases you want to free them |
278 | | to save hardware memory (e.g. application was runs in a long time, you |
279 | | might free temporary buffers periodically to avoid memory overload). |
280 | | */ |
281 | | void _freeUnusedBufferCopies(void); |
282 | | |
283 | | /** Internal method for releasing all temporary buffers; is called by OGRE. |
284 | | @param forceFreeUnused |
285 | | If @c true, free all unused temporary buffers. |
286 | | If @c false, auto detect and free all unused temporary buffers based on |
287 | | temporary buffers utilization. |
288 | | */ |
289 | | void _releaseBufferCopies(bool forceFreeUnused = false); |
290 | | |
291 | | /** Internal method that forces the release of copies of a given buffer. |
292 | | |
293 | | This usually means that the buffer which the copies are based on has |
294 | | been changed in some fundamental way, and the owner of the original |
295 | | wishes to make that known so that new copies will reflect the |
296 | | changes. |
297 | | @param sourceBuffer |
298 | | The source buffer as a shared pointer. Any buffer copies created |
299 | | from the source buffer are deleted. |
300 | | */ |
301 | | void _forceReleaseBufferCopies(const HardwareVertexBufferSharedPtr& sourceBuffer); |
302 | | |
303 | | /// Notification that a hardware vertex buffer has been destroyed. |
304 | | void _notifyVertexBufferDestroyed(HardwareVertexBuffer* buf); |
305 | | }; |
306 | | |
307 | | /** Singleton wrapper for hardware buffer manager. */ |
308 | | class _OgreExport HardwareBufferManager : public HardwareBufferManagerBase, public Singleton<HardwareBufferManager> |
309 | | { |
310 | | public: |
311 | | HardwareBufferManager(); |
312 | | ~HardwareBufferManager(); |
313 | | |
314 | | /// @copydoc Singleton::getSingleton() |
315 | | static HardwareBufferManager& getSingleton(void); |
316 | | /// @copydoc Singleton::getSingleton() |
317 | | static HardwareBufferManager* getSingletonPtr(void); |
318 | | |
319 | | }; |
320 | | |
321 | | /** @} */ |
322 | | /** @} */ |
323 | | } // namespace Ogre |
324 | | |
325 | | #include "OgreHeaderSuffix.h" |
326 | | |
327 | | #endif // __HardwareBufferManager__ |
328 | | |