PageRenderTime 40ms CodeModel.GetById 1ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llrender/llvertexbuffer.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 324 lines | 210 code | 52 blank | 62 comment | 1 complexity | 8dcb9f20be308661032c1a9d66d8b2c8 MD5 | raw file
  1/** 
  2 * @file llvertexbuffer.h
  3 * @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects
  4 *
  5 * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_LLVERTEXBUFFER_H
 28#define LL_LLVERTEXBUFFER_H
 29
 30#include "llgl.h"
 31#include "v2math.h"
 32#include "v3math.h"
 33#include "v4math.h"
 34#include "v4coloru.h"
 35#include "llstrider.h"
 36#include "llrender.h"
 37#include <set>
 38#include <vector>
 39#include <list>
 40
 41#define LL_MAX_VERTEX_ATTRIB_LOCATION 64
 42
 43//============================================================================
 44// NOTES
 45// Threading:
 46//  All constructors should take an 'create' paramater which should only be
 47//  'true' when called from the main thread. Otherwise createGLBuffer() will
 48//  be called as soon as getVertexPointer(), etc is called (which MUST ONLY be
 49//  called from the main (i.e OpenGL) thread)
 50
 51
 52//============================================================================
 53// gl name pools for dynamic and streaming buffers
 54class LLVBOPool
 55{
 56public:
 57	static U32 sBytesPooled;
 58
 59	U32 mUsage;
 60	U32 mType;
 61
 62	//size MUST be a power of 2
 63	U8* allocate(U32& name, U32 size);
 64	
 65	//size MUST be the size provided to allocate that returned the given name
 66	void release(U32 name, U8* buffer, U32 size);
 67	
 68	//destroy all records in mFreeList
 69	void cleanup();
 70
 71	class Record
 72	{
 73	public:
 74		U32 mGLName;
 75		U8* mClientData;
 76	};
 77
 78	typedef std::list<Record> record_list_t;
 79	std::vector<record_list_t> mFreeList;
 80};
 81
 82class LLGLFence
 83{
 84public:
 85	virtual void placeFence() = 0;
 86	virtual void wait() = 0;
 87};
 88
 89//============================================================================
 90// base class 
 91class LLPrivateMemoryPool ;
 92class LLVertexBuffer : public LLRefCount
 93{
 94public:
 95	class MappedRegion
 96	{
 97	public:
 98		S32 mType;
 99		S32 mIndex;
100		S32 mCount;
101		
102		MappedRegion(S32 type, S32 index, S32 count);
103	};
104
105	LLVertexBuffer(const LLVertexBuffer& rhs)
106	{
107		*this = rhs;
108	}
109
110	const LLVertexBuffer& operator=(const LLVertexBuffer& rhs)
111	{
112		llerrs << "Illegal operation!" << llendl;
113		return *this;
114	}
115
116	static LLVBOPool sStreamVBOPool;
117	static LLVBOPool sDynamicVBOPool;
118	static LLVBOPool sStreamIBOPool;
119	static LLVBOPool sDynamicIBOPool;
120
121	static BOOL	sUseStreamDraw;
122	static BOOL sUseVAO;
123	static BOOL	sPreferStreamDraw;
124
125	static void initClass(bool use_vbo, bool no_vbo_mapping);
126	static void cleanupClass();
127	static void setupClientArrays(U32 data_mask);
128	static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
129	static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
130
131 	static void unbind(); //unbind any bound vertex buffer
132
133	//get the size of a vertex with the given typemask
134	static S32 calcVertexSize(const U32& typemask);
135
136	//get the size of a buffer with the given typemask and vertex count
137	//fill offsets with the offset of each vertex component array into the buffer
138	// indexed by the following enum
139	static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);		
140
141	
142	//WARNING -- when updating these enums you MUST 
143	// 1 - update LLVertexBuffer::sTypeSize
144	// 2 - add a strider accessor
145	// 3 - modify LLVertexBuffer::setupVertexBuffer
146	// 4 - modify LLVertexBuffer::setupClientArray
147	// 5 - modify LLViewerShaderMgr::mReservedAttribs
148	// 6 - update LLVertexBuffer::setupVertexArray
149	enum {
150		TYPE_VERTEX = 0,
151		TYPE_NORMAL,
152		TYPE_TEXCOORD0,
153		TYPE_TEXCOORD1,
154		TYPE_TEXCOORD2,
155		TYPE_TEXCOORD3,
156		TYPE_COLOR,
157		TYPE_EMISSIVE,
158		TYPE_BINORMAL,
159		TYPE_WEIGHT,
160		TYPE_WEIGHT4,
161		TYPE_CLOTHWEIGHT,
162		TYPE_TEXTURE_INDEX,
163		TYPE_MAX,
164		TYPE_INDEX,		
165	};
166	enum {
167		MAP_VERTEX = (1<<TYPE_VERTEX),
168		MAP_NORMAL = (1<<TYPE_NORMAL),
169		MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0),
170		MAP_TEXCOORD1 = (1<<TYPE_TEXCOORD1),
171		MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
172		MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
173		MAP_COLOR = (1<<TYPE_COLOR),
174		MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
175		// These use VertexAttribPointer and should possibly be made generic
176		MAP_BINORMAL = (1<<TYPE_BINORMAL),
177		MAP_WEIGHT = (1<<TYPE_WEIGHT),
178		MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
179		MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
180		MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),
181	};
182	
183protected:
184	friend class LLRender;
185
186	virtual ~LLVertexBuffer(); // use unref()
187
188	virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()
189	void setupVertexArray();
190	
191	void	genBuffer(U32 size);
192	void	genIndices(U32 size);
193	bool	bindGLBuffer(bool force_bind = false);
194	bool	bindGLIndices(bool force_bind = false);
195	bool	bindGLArray();
196	void	releaseBuffer();
197	void	releaseIndices();
198	void	createGLBuffer(U32 size);
199	void	createGLIndices(U32 size);
200	void 	destroyGLBuffer();
201	void 	destroyGLIndices();
202	void	updateNumVerts(S32 nverts);
203	void	updateNumIndices(S32 nindices); 
204	virtual BOOL	useVBOs() const;
205	void	unmapBuffer();
206		
207public:
208	LLVertexBuffer(U32 typemask, S32 usage);
209	
210	// map for data access
211	U8*		mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
212	U8*		mapIndexBuffer(S32 index, S32 count, bool map_range);
213
214	// set for rendering
215	virtual void	setBuffer(U32 data_mask); 	// calls  setupVertexBuffer() if data_mask is not 0
216	void flush(); //flush pending data to GL memory
217	// allocate buffer
218	void	allocateBuffer(S32 nverts, S32 nindices, bool create);
219	virtual void resizeBuffer(S32 newnverts, S32 newnindices);
220			
221	// Only call each getVertexPointer, etc, once before calling unmapBuffer()
222	// call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
223	// example:
224	//   vb->getVertexBuffer(verts);
225	//   vb->getNormalStrider(norms);
226	//   setVertsNorms(verts, norms);
227	//   vb->unmapBuffer();
228	bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
229	bool getVertexStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
230	bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
231	bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
232	bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
233	bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
234	bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
235	bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
236	bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
237	bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
238	bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
239	bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
240	
241
242	BOOL isEmpty() const					{ return mEmpty; }
243	BOOL isLocked() const					{ return mVertexLocked || mIndexLocked; }
244	S32 getNumVerts() const					{ return mNumVerts; }
245	S32 getNumIndices() const				{ return mNumIndices; }
246	
247	U8* getIndicesPointer() const			{ return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
248	U8* getVerticesPointer() const			{ return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
249	U32 getTypeMask() const					{ return mTypeMask; }
250	bool hasDataType(S32 type) const		{ return ((1 << type) & getTypeMask()); }
251	S32 getSize() const;
252	S32 getIndicesSize() const				{ return mIndicesSize; }
253	U8* getMappedData() const				{ return mMappedData; }
254	U8* getMappedIndices() const			{ return mMappedIndexData; }
255	S32 getOffset(S32 type) const			{ return mOffsets[type]; }
256	S32 getUsage() const					{ return mUsage; }
257
258	void draw(U32 mode, U32 count, U32 indices_offset) const;
259	void drawArrays(U32 mode, U32 offset, U32 count) const;
260	void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
261
262	//for debugging, validate data in given range is valid
263	void validateRange(U32 start, U32 end, U32 count, U32 offset) const;
264
265	
266
267protected:	
268	S32		mNumVerts;		// Number of vertices allocated
269	S32		mNumIndices;	// Number of indices allocated
270	
271	ptrdiff_t mAlignedOffset;
272	ptrdiff_t mAlignedIndexOffset;
273	S32		mSize;
274	S32		mIndicesSize;
275	U32		mTypeMask;
276	S32		mUsage;			// GL usage
277	U32		mGLBuffer;		// GL VBO handle
278	U32		mGLIndices;		// GL IBO handle
279	U32		mGLArray;		// GL VAO handle
280	
281	U8*		mMappedData;	// pointer to currently mapped data (NULL if unmapped)
282	U8*		mMappedIndexData;	// pointer to currently mapped indices (NULL if unmapped)
283	BOOL	mVertexLocked;			// if TRUE, vertex buffer is being or has been written to in client memory
284	BOOL	mIndexLocked;			// if TRUE, index buffer is being or has been written to in client memory
285	BOOL	mFinal;			// if TRUE, buffer can not be mapped again
286	BOOL	mEmpty;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.	
287	S32		mOffsets[TYPE_MAX];
288
289	std::vector<MappedRegion> mMappedVertexRegions;
290	std::vector<MappedRegion> mMappedIndexRegions;
291
292	mutable LLGLFence* mFence;
293
294	void placeFence() const;
295	void waitFence() const;
296
297
298private:
299	static LLPrivateMemoryPool* sPrivatePoolp ;
300
301public:
302	static S32 sCount;
303	static S32 sGLCount;
304	static S32 sMappedCount;
305	static BOOL sMapped;
306	typedef std::list<LLVertexBuffer*> buffer_list_t;
307		
308	static BOOL sDisableVBOMapping; //disable glMapBufferARB
309	static BOOL sEnableVBOs;
310	static S32 sTypeSize[TYPE_MAX];
311	static U32 sGLMode[LLRender::NUM_MODES];
312	static U32 sGLRenderBuffer;
313	static U32 sGLRenderArray;
314	static U32 sGLRenderIndices;
315	static BOOL sVBOActive;
316	static BOOL sIBOActive;
317	static U32 sLastMask;
318	static U32 sAllocatedBytes;
319	static U32 sBindCount;
320	static U32 sSetCount;
321};
322
323
324#endif // LL_LLVERTEXBUFFER_H