Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VertexBufferManager.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2011 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * Allocate and destroy CVertexBuffers
20  */
21 
22 #include "precompiled.h"
23 
24 #include "VertexBufferManager.h"
25 
26 #include "lib/ogl.h"
27 #include "ps/CLogger.h"
28 
29 #define DUMP_VB_STATS 0 // for debugging
30 
32 
33 ///////////////////////////////////////////////////////////////////////////////
34 // Explicit shutdown of the vertex buffer subsystem.
35 // This avoids the ordering issues that arise when using destructors of
36 // global instances.
38 {
39  typedef std::list<CVertexBuffer*>::iterator Iter;
40  for (Iter iter = m_Buffers.begin(); iter != m_Buffers.end(); ++iter)
41  delete *iter;
42  m_Buffers.clear();
43 }
44 
45 
46 ///////////////////////////////////////////////////////////////////////////////
47 // Allocate: try to allocate a buffer of given number of vertices (each of
48 // given size), with the given type, and using the given texture - return null
49 // if no free chunks available
50 CVertexBuffer::VBChunk* CVertexBufferManager::Allocate(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target)
51 {
52  CVertexBuffer::VBChunk* result=0;
53 
54  ENSURE(usage == GL_STREAM_DRAW || usage == GL_STATIC_DRAW || usage == GL_DYNAMIC_DRAW);
55 
56  ENSURE(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
57 
58  // TODO, RC - run some sanity checks on allocation request
59 
60  typedef std::list<CVertexBuffer*>::iterator Iter;
61 
62 #if DUMP_VB_STATS
63  debug_printf(L"\n============================\n# allocate vsize=%d nverts=%d\n\n", vertexSize, numVertices);
64  for (Iter iter = m_Buffers.begin(); iter != m_Buffers.end(); ++iter) {
65  CVertexBuffer* buffer = *iter;
66  if (buffer->CompatibleVertexType(vertexSize, usage, target))
67  {
68  debug_printf(L"%p\n", buffer);
69  buffer->DumpStatus();
70  }
71  }
72 #endif
73 
74  // iterate through all existing buffers testing for one that'll
75  // satisfy the allocation
76  for (Iter iter = m_Buffers.begin(); iter != m_Buffers.end(); ++iter) {
77  CVertexBuffer* buffer = *iter;
78  result = buffer->Allocate(vertexSize, numVertices, usage, target);
79  if (result)
80  return result;
81  }
82 
83  // got this far; need to allocate a new buffer
84  CVertexBuffer* buffer = new CVertexBuffer(vertexSize, usage, target);
85  m_Buffers.push_front(buffer);
86  result = buffer->Allocate(vertexSize, numVertices, usage, target);
87 
88  if (!result)
89  {
90  LOGERROR(L"Failed to create VBOs (%lu*%lu)", (unsigned long)vertexSize, (unsigned long)numVertices);
91  }
92 
93  return result;
94 }
95 
96 ///////////////////////////////////////////////////////////////////////////////
97 // Release: return given chunk to its owner
99 {
100  ENSURE(chunk);
101 #if DUMP_VB_STATS
102  debug_printf(L"\n============================\n# release %p nverts=%d\n\n", chunk, chunk->m_Count);
103 #endif
104  chunk->m_Owner->Release(chunk);
105 }
106 
107 
109 {
110  size_t total = 0;
111 
112  typedef std::list<CVertexBuffer*>::iterator Iter;
113  for (Iter iter = m_Buffers.begin(); iter != m_Buffers.end(); ++iter)
114  total += (*iter)->GetBytesReserved();
115 
116  return total;
117 }
118 
120 {
121  size_t total = 0;
122 
123  typedef std::list<CVertexBuffer*>::iterator Iter;
124  for (Iter iter = m_Buffers.begin(); iter != m_Buffers.end(); ++iter)
125  total += (*iter)->GetBytesAllocated();
126 
127  return total;
128 }
#define LOGERROR
Definition: CLogger.h:35
void Shutdown()
Explicit shutdown of the vertex buffer subsystem; releases all currently-allocated buffers...
CVertexBufferManager g_VBMan
VBChunk: describes a portion of this vertex buffer.
Definition: VertexBuffer.h:47
CVertexBuffer: encapsulation of ARB_vertex_buffer_object, also supplying some additional functionalit...
Definition: VertexBuffer.h:40
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
CVertexBuffer::VBChunk * Allocate(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target)
Try to allocate a vertex buffer of the given size and type.
void Release(VBChunk *chunk)
Return given chunk to this buffer.
size_t m_Count
Number of vertices used by chunk.
Definition: VertexBuffer.h:54
void Release(CVertexBuffer::VBChunk *chunk)
Returns the given chunk to its owning buffer.
CVertexBuffer * m_Owner
Owning (parent) vertex buffer.
Definition: VertexBuffer.h:50
std::list< CVertexBuffer * > m_Buffers
List of all known vertex buffers.
bool CompatibleVertexType(size_t vertexSize, GLenum usage, GLenum target)
Returns true if this vertex buffer is compatible with the specified vertex type and intended usage...
VBChunk * Allocate(size_t vertexSize, size_t numVertices, GLenum usage, GLenum target)
Try to allocate a buffer of given number of vertices (each of given size), and with the given type - ...
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
Definition: debug.cpp:142