aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lldrawpool.h
blob: 2ce13fb2436f6526d875a377c66d5eadfd7ab223 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
/** 
 * @file lldrawpool.h
 * @brief LLDrawPool class definition
 *
 * Copyright (c) 2002-2007, Linden Research, Inc.
 * 
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlife.com/developers/opensource/gplv2
 * 
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at http://secondlife.com/developers/opensource/flossexception
 * 
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 * 
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 */

#ifndef LL_LLDRAWPOOL_H
#define LL_LLDRAWPOOL_H

#include "llagparray.h"
#include "lldarray.h"
#include "lldlinked.h"
#include "llstrider.h"
#include "llviewerimage.h"
#include "v4coloru.h"
#include "v2math.h"
#include "v3math.h"
#include "llstrider.h"

class LLFace;
class LLImageGL;
class LLViewerImage;

#define DEFAULT_MAX_VERTICES 65535

class LLDrawPool
{
public:
	typedef LLDynamicArray<LLFace*, 128> face_array_t;
	
	enum
	{
		SHADER_LEVEL_SCATTERING = 2
	};

public:
	LLDrawPool(const U32 type, const U32 data_mask_il, const U32 data_mask_nil); 
	virtual ~LLDrawPool();

	static LLDrawPool* createPool(const U32 type, LLViewerImage *tex0 = NULL);

	void flushAGP(); // Flush the AGP buffers so they can be repacked and reallocated.
	void syncAGP();

	virtual LLDrawPool *instancePool() = 0;	// Create an empty new instance of the pool.
	virtual void beginRenderPass( S32 pass );
	virtual void endRenderPass( S32 pass );
	virtual S32	 getNumPasses() { return 1; }
	virtual void render(S32 pass = 0) = 0;
	virtual void renderForSelect() = 0;
	virtual BOOL match(LLFace* last_face, LLFace* facep) { return FALSE; }
	virtual void renderFaceSelected(LLFace *facep, LLImageGL *image, const LLColor4 &color,
									const S32 index_offset = 0, const S32 index_count = 0);

	virtual void prerender() = 0;
	virtual S32 rebuild();

	virtual S32 getMaterialAttribIndex() = 0;

	virtual LLViewerImage *getTexture();
	virtual LLViewerImage *getDebugTexture();
	virtual void dirtyTexture(const LLViewerImage* texturep);

	virtual void enqueue(LLFace *face);
	virtual BOOL addFace(LLFace *face);
	virtual BOOL removeFace(LLFace *face);

	virtual BOOL verify() const;		// Verify that all data in the draw pool is correct!
	virtual LLColor3 getDebugColor() const; // For AGP debug display

	virtual void resetDrawOrders();
	virtual void resetVertexData(S32 reserve_count);
	virtual void resetIndices(S32 num_indices);
	void resetAll();

	BOOL moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data = FALSE);


	S32 getId() const { return mId; }
	U32 getType() const { return mType; }

	const U32 getStride() const;
	inline const U32 getStride(const U32 data_type) const;
	inline const U32 getOffset(const U32 data_type) const;

	S32	reserveGeom(U32 count);
	S32	reserveInd (U32 count);
	S32 unReserveGeom(const S32 index, const U32 count);
	S32 unReserveInd(const S32 index, const U32 count);

	void bindGLVertexPointer();
	void bindGLTexCoordPointer(const U32 pass=0);
	void bindGLNormalPointer();
	void bindGLBinormalPointer(S32 index);
	void bindGLColorPointer();
	void bindGLVertexWeightPointer(S32 index);
	void bindGLVertexClothingWeightPointer(S32 index);

	const U32  getIndexCount() const;
	const U32  getTexCoordCount(const U32 pass=0) const;
	const U32  getVertexCount() const;
	const U32  getNormalCount() const;
	const U32  getBinormalCount() const;
	const U32  getColorCount() const;
	const U32  getVertexWeightCount() const;

	void  setDirty();
	void  setDirtyMemory()						{ mMemory.setDirty(); }
	void  setDirtyWeights()						{ mWeights.setDirty(); }

	const U32* getRawIndices() const			{ return mIndices.getMem(); }

	U32 getIndex(const S32 index)				{ return mIndices[index]; } // Use to get one index
	U32 *getIndices(const S32 index); 			// Used to get an array of indices for reading/writing
	void CheckIntegrity(); // DEBUG
	
	const LLVector3& getVertex(const S32 index);
	const LLVector2& getTexCoord(const S32 index, const U32 pass);
	const LLVector3& getNormal(const S32 index);
	const LLVector3& getBinormal(const S32 index);
	const LLColor4U& getColor(const S32 index);
	const F32& getVertexWeight(const S32 index);
	const LLVector4& getClothingWeight(const S32 index);

	void setRebuild(const BOOL rebuild);

	void destroy();

	void buildEdges();

	static S32 drawLoop(face_array_t& face_list, const U32* index_array);
	static S32 drawLoopSetTex(face_array_t& face_list, const U32* index_array, S32 stage);
	void drawLoop();

	void renderVisibility();

	void addFaceReference(LLFace *facep);
	void removeFaceReference(LLFace *facep);
	U32	getTrianglesDrawn() const;
	void resetTrianglesDrawn();
	void addIndicesDrawn(const U32 indices);

	void printDebugInfo() const;
	S32 getMemUsage(const BOOL print = FALSE);
	
	BOOL setUseAGP(BOOL use_agp);
	BOOL canUseAGP() const		{ return mMemory.isAGP(); } // Return TRUE if this pool can use AGP

	S32 getMaxVertices() const	{ return mMaxVertices; }
	S32 getVertexShaderLevel() const { return mVertexShaderLevel; }
	
	friend class LLFace;
	friend class LLPipeline;
public:

	enum
	{
		// Correspond to LLPipeline render type
		POOL_SKY = 1,
		POOL_STARS,
		POOL_GROUND,
		POOL_TERRAIN,	
		POOL_SIMPLE,
		POOL_MEDIA,		// unused
		POOL_BUMP,
		POOL_AVATAR,
		POOL_TREE,
		POOL_TREE_NEW,
		POOL_WATER,		
		POOL_CLOUDS,
		POOL_ALPHA,
		POOL_HUD,
	};


	// If you change the order or add params to these, you also need to adjust the sizes in the
	// mDataSizes array defined in lldrawpool.cpp
	typedef enum e_data_type
	{
		DATA_VERTICES		= 0,
		DATA_TEX_COORDS0	= 1,
		DATA_TEX_COORDS1	= 2,
		DATA_TEX_COORDS2	= 3,
		DATA_TEX_COORDS3	= 4,
		DATA_NORMALS		= 5,
		DATA_VERTEX_WEIGHTS = 6,
		DATA_CLOTHING_WEIGHTS = 7,
		DATA_BINORMALS		= 8,
		DATA_COLORS			= 9,
		DATA_MAX_TYPES		= 10
	} EDataType;

	typedef enum e_data_mask
	{
		DATA_VERTICES_MASK			= 1 << DATA_VERTICES,
		DATA_TEX_COORDS0_MASK		= 1 << DATA_TEX_COORDS0,
		DATA_TEX_COORDS1_MASK		= 1 << DATA_TEX_COORDS1,
		DATA_TEX_COORDS2_MASK		= 1 << DATA_TEX_COORDS2,
		DATA_TEX_COORDS3_MASK		= 1 << DATA_TEX_COORDS3,
		DATA_NORMALS_MASK			= 1 << DATA_NORMALS,
		DATA_VERTEX_WEIGHTS_MASK	= 1 << DATA_VERTEX_WEIGHTS,
		DATA_CLOTHING_WEIGHTS_MASK	= 1 << DATA_CLOTHING_WEIGHTS,
		DATA_BINORMALS_MASK			= 1 << DATA_BINORMALS,
		DATA_COLORS_MASK			= 1 << DATA_COLORS,

		// Masks for standard types.
		// IL for interleaved, NIL for non-interleaved.
		DATA_SIMPLE_IL_MASK				= DATA_VERTICES_MASK | DATA_TEX_COORDS0_MASK | DATA_NORMALS_MASK,
		DATA_SIMPLE_NIL_MASK			= 0,
		DATA_BUMP_IL_MASK				= DATA_SIMPLE_IL_MASK | DATA_BINORMALS_MASK | DATA_TEX_COORDS1_MASK,
	} EDataMask;

	face_array_t	mDrawFace;
	face_array_t	mMoveFace;
	face_array_t	mReferences;

	U32 mDataMaskIL;	// Interleaved data
	U32 mDataMaskNIL;	// Non-interleaved data
	U32 mDataOffsets[DATA_MAX_TYPES];
	S32 mStride;

	S32	mRebuildFreq;
	S32	mRebuildTime;
	S32	mGeneration;

	
	S32 mSkippedVertices;

	static U32 sDataSizes[DATA_MAX_TYPES];
	static S32 sNumDrawPools;

protected:
	LLAGPArray<U8>          mMemory;
	LLAGPArray<F32>			mWeights;
	LLAGPArray<LLVector4>	mClothingWeights;
	LLAGPArray<U32>         mIndices;

public:

	BOOL getVertexStrider      (LLStrider<LLVector3> &vertices,   const U32 index = 0);
	BOOL getTexCoordStrider    (LLStrider<LLVector2> &tex_coords, const U32 index = 0, const U32 pass=0);
	BOOL getNormalStrider      (LLStrider<LLVector3> &normals,    const U32 index = 0);
	BOOL getBinormalStrider    (LLStrider<LLVector3> &binormals,  const U32 index = 0);
	BOOL getColorStrider   	   (LLStrider<LLColor4U> &colors,  const U32 index = 0);
	BOOL getVertexWeightStrider(LLStrider<F32>       &vertex_weights, const U32 index = 0);
	BOOL getClothingWeightStrider(LLStrider<LLVector4>       &clothing_weights, const U32 index = 0);

public:
	enum { NUM_BUCKETS = 8 };	// Need to change freeListBucket() if NUM_BUCKETS changes
	struct FreeListNode
	{
		U32 count;
		S32 next;
	};
protected:
	int freeListBucket(U32 count);
	void freeListAddGeom(S32 index, U32 count);
	void freeListAddInd(S32 index, U32 count);
	S32 freeListFindGeom(U32 count);
	S32 freeListFindInd(U32 count);
	
protected:
	BOOL mUseAGP;
	S32 mVertexShaderLevel;
	S32	mId;
	U32 mType;				// Type of draw pool
	S32 mMaxVertices;
	S32	mIndicesDrawn;
	BOOL mCleanupUnused; // Cleanup unused data when too full

	S32 mFreeListGeomHead[8];
	S32 mFreeListIndHead[8];

public:
	class LLOverrideFaceColor
	{
	public:
		LLOverrideFaceColor(LLDrawPool* pool)
			: mOverride(sOverrideFaceColor), mPool(pool)
		{
			sOverrideFaceColor = TRUE;
		}
		LLOverrideFaceColor(LLDrawPool* pool, const LLColor4& color)
			: mOverride(sOverrideFaceColor), mPool(pool)
		{
			sOverrideFaceColor = TRUE;
			setColor(color);
		}
		LLOverrideFaceColor(LLDrawPool* pool, const LLColor4U& color)
			: mOverride(sOverrideFaceColor), mPool(pool)
		{
			sOverrideFaceColor = TRUE;
			setColor(color);
		}
		LLOverrideFaceColor(LLDrawPool* pool, F32 r, F32 g, F32 b, F32 a)
			: mOverride(sOverrideFaceColor), mPool(pool)
		{
			sOverrideFaceColor = TRUE;
			setColor(r, g, b, a);
		}
		~LLOverrideFaceColor()
		{
			sOverrideFaceColor = mOverride;
		}
		void setColor(const LLColor4& color);
		void setColor(const LLColor4U& color);
		void setColor(F32 r, F32 g, F32 b, F32 a);
		BOOL mOverride;
		LLDrawPool* mPool;
		static BOOL sOverrideFaceColor;
	};

	virtual void enableShade();
	virtual void disableShade();
	virtual void setShade(F32 shade);
	
};

inline const U32 LLDrawPool::getStride() const
{
	return mStride;
}

inline const U32 LLDrawPool::getOffset(const U32 data_type) const
{
	return  mDataOffsets[data_type];
}

inline const U32 LLDrawPool::getStride(const U32 data_type) const
{
	if (mDataMaskIL & (1 << data_type))
	{
		return mStride;
	}
	else if (mDataMaskNIL & (1 << data_type))
	{
		return 0;
	}
	else
	{
		llerrs << "Getting stride for unsupported data type " << data_type << llendl;
		return 0;
	}
}

#endif //LL_LLDRAWPOOL_H