aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lldrawpool.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/lldrawpool.cpp1261
1 files changed, 221 insertions, 1040 deletions
diff --git a/linden/indra/newview/lldrawpool.cpp b/linden/indra/newview/lldrawpool.cpp
index 18d6000..dc2e6ba 100644
--- a/linden/indra/newview/lldrawpool.cpp
+++ b/linden/indra/newview/lldrawpool.cpp
@@ -32,7 +32,6 @@
32#include "llfasttimer.h" 32#include "llfasttimer.h"
33#include "llviewercontrol.h" 33#include "llviewercontrol.h"
34 34
35#include "llagparray.h"
36#include "lldrawable.h" 35#include "lldrawable.h"
37#include "lldrawpoolalpha.h" 36#include "lldrawpoolalpha.h"
38#include "lldrawpoolavatar.h" 37#include "lldrawpoolavatar.h"
@@ -43,53 +42,38 @@
43#include "lldrawpoolsky.h" 42#include "lldrawpoolsky.h"
44#include "lldrawpoolstars.h" 43#include "lldrawpoolstars.h"
45#include "lldrawpooltree.h" 44#include "lldrawpooltree.h"
46#include "lldrawpooltreenew.h"
47#include "lldrawpoolterrain.h" 45#include "lldrawpoolterrain.h"
48#include "lldrawpoolwater.h" 46#include "lldrawpoolwater.h"
49#include "lldrawpoolhud.h"
50#include "llface.h" 47#include "llface.h"
51#include "llviewerobjectlist.h" // For debug listing. 48#include "llviewerobjectlist.h" // For debug listing.
52#include "llvotreenew.h"
53#include "pipeline.h" 49#include "pipeline.h"
54 50
55#include "llagparray.inl"
56
57U32 LLDrawPool::sDataSizes[LLDrawPool::DATA_MAX_TYPES] =
58{
59 12, // DATA_VERTICES
60 8, // DATA_TEX_COORDS0
61 8, // DATA_TEX_COORDS1
62 8, // DATA_TEX_COORDS2
63 8, // DATA_TEX_COORDS3
64 12, // DATA_NORMALS
65 4, // DATA_VERTEX_WEIGHTS,
66 16, // DATA_CLOTHING_WEIGHTS
67 12, // DATA_BINORMALS
68 4, // DATA_COLORS
69};
70
71S32 LLDrawPool::sNumDrawPools = 0; 51S32 LLDrawPool::sNumDrawPools = 0;
72 52
53
54//=============================
55// Draw Pool Implementation
56//=============================
73LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) 57LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
74{ 58{
75 LLDrawPool *poolp = NULL; 59 LLDrawPool *poolp = NULL;
76 switch (type) 60 switch (type)
77 { 61 {
78 case POOL_SIMPLE: 62 case POOL_SIMPLE:
79 poolp = new LLDrawPoolSimple(tex0); 63 poolp = new LLDrawPoolSimple();
80 break; 64 break;
81 case POOL_ALPHA: 65 case POOL_ALPHA:
82 poolp = new LLDrawPoolAlpha(); 66 poolp = new LLDrawPoolAlpha();
83 break; 67 break;
68 case POOL_ALPHA_POST_WATER:
69 poolp = new LLDrawPoolAlphaPostWater();
70 break;
84 case POOL_AVATAR: 71 case POOL_AVATAR:
85 poolp = new LLDrawPoolAvatar(); 72 poolp = new LLDrawPoolAvatar();
86 break; 73 break;
87 case POOL_TREE: 74 case POOL_TREE:
88 poolp = new LLDrawPoolTree(tex0); 75 poolp = new LLDrawPoolTree(tex0);
89 break; 76 break;
90 case POOL_TREE_NEW:
91 poolp = new LLDrawPoolTreeNew(tex0);
92 break;
93 case POOL_TERRAIN: 77 case POOL_TERRAIN:
94 poolp = new LLDrawPoolTerrain(tex0); 78 poolp = new LLDrawPoolTerrain(tex0);
95 break; 79 break;
@@ -99,9 +83,6 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
99 case POOL_STARS: 83 case POOL_STARS:
100 poolp = new LLDrawPoolStars(); 84 poolp = new LLDrawPoolStars();
101 break; 85 break;
102 case POOL_CLOUDS:
103 poolp = new LLDrawPoolClouds();
104 break;
105 case POOL_WATER: 86 case POOL_WATER:
106 poolp = new LLDrawPoolWater(); 87 poolp = new LLDrawPoolWater();
107 break; 88 break;
@@ -109,10 +90,7 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
109 poolp = new LLDrawPoolGround(); 90 poolp = new LLDrawPoolGround();
110 break; 91 break;
111 case POOL_BUMP: 92 case POOL_BUMP:
112 poolp = new LLDrawPoolBump(tex0); 93 poolp = new LLDrawPoolBump();
113 break;
114 case POOL_HUD:
115 poolp = new LLDrawPoolHUD();
116 break; 94 break;
117 default: 95 default:
118 llerrs << "Unknown draw pool type!" << llendl; 96 llerrs << "Unknown draw pool type!" << llendl;
@@ -123,183 +101,86 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
123 return poolp; 101 return poolp;
124} 102}
125 103
126LLDrawPool::LLDrawPool(const U32 type, const U32 data_mask_il, const U32 data_mask_nil) 104LLDrawPool::LLDrawPool(const U32 type)
127{ 105{
128 llassert(data_mask_il & DATA_VERTICES_MASK);
129 S32 i;
130 mType = type; 106 mType = type;
131 sNumDrawPools++; 107 sNumDrawPools++;
132 mId = sNumDrawPools; 108 mId = sNumDrawPools;
133 109 mVertexShaderLevel = 0;
134 mDataMaskIL = data_mask_il;
135 mDataMaskNIL = data_mask_nil;
136
137 U32 cur_mask = 0x01;
138 U32 cur_offset = 0;
139 for (i = 0; i < DATA_MAX_TYPES; i++)
140 {
141 mDataOffsets[i] = cur_offset;
142 if (cur_mask & mDataMaskIL)
143 {
144 cur_offset += sDataSizes[i];
145 }
146 cur_mask <<= 1;
147 }
148
149 mStride = cur_offset;
150
151 mCleanupUnused = FALSE;
152 mIndicesDrawn = 0; 110 mIndicesDrawn = 0;
153 mRebuildFreq = 128 + rand() % 5; 111}
154 mRebuildTime = 0;
155 mGeneration = 1;
156 mSkippedVertices = 0;
157
158 resetDrawOrders();
159 resetVertexData(0);
160
161 if (gGLManager.mHasATIVAO && !gGLManager.mIsRadeon9700)
162 {
163 // ATI 8500 doesn't like indices > 15 bit.
164 mMaxVertices = DEFAULT_MAX_VERTICES/2;
165 }
166 else
167 {
168 mMaxVertices = DEFAULT_MAX_VERTICES;
169 }
170 112
171 // JC: This must happen last, as setUseAGP reads many of the 113LLDrawPool::~LLDrawPool()
172 // above variables. 114{
173 mUseAGP = FALSE;
174 setUseAGP(gPipeline.usingAGP());
175 115
176 for (i=0; i<NUM_BUCKETS; i++)
177 {
178 mFreeListGeomHead[i] = -1;
179 mFreeListIndHead[i] = -1;
180 }
181 mVertexShaderLevel = 0;
182} 116}
183 117
184void LLDrawPool::destroy() 118LLViewerImage *LLDrawPool::getDebugTexture()
185{ 119{
186 if (!mReferences.empty()) 120 return NULL;
187 {
188 llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl;
189 }
190} 121}
191 122
192 123//virtual
193LLDrawPool::~LLDrawPool() 124void LLDrawPool::beginRenderPass( S32 pass )
194{ 125{
195 destroy();
196
197 llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );
198} 126}
199 127
200BOOL LLDrawPool::setUseAGP(BOOL use_agp) 128//virtual
129void LLDrawPool::endRenderPass( S32 pass )
201{ 130{
202 BOOL ok = TRUE; 131 glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
203 S32 vertex_count = mMemory.count() / mStride; 132 glDisableClientState ( GL_COLOR_ARRAY );
204 if (vertex_count > mMaxVertices && use_agp) 133 glDisableClientState ( GL_NORMAL_ARRAY );
205 {
206#ifdef DEBUG_AGP
207 llwarns << "Allocating " << vertex_count << " vertices in pool type " << getType() << ", disabling AGP!" << llendl
208#endif
209 use_agp = FALSE;
210 ok = FALSE;
211 }
212
213 if (mUseAGP != use_agp)
214 {
215 mUseAGP = use_agp;
216
217 BOOL ok = TRUE;
218 ok &= mMemory.setUseAGP(use_agp);
219
220 if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
221 {
222 ok &= mWeights.setUseAGP(use_agp);
223 }
224 if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
225 {
226 ok &= mClothingWeights.setUseAGP(use_agp);
227 }
228
229 if (!ok)
230 {
231 // Disable AGP if any one of these doesn't have AGP, we don't want to try
232 // mixing AGP and non-agp arrays in a single pool.
233#ifdef DEBUG_AGP
234 llinfos << "Aborting using AGP because set failed on a mem block!" << llendl;
235#endif
236 setUseAGP(FALSE);
237 ok = FALSE;
238 }
239 }
240 return ok;
241} 134}
242 135
243void LLDrawPool::flushAGP() 136U32 LLDrawPool::getTrianglesDrawn() const
244{ 137{
245 mMemory.flushAGP(); 138 return mIndicesDrawn / 3;
246
247 if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
248 {
249 mWeights.flushAGP();
250 }
251 if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
252 {
253 mClothingWeights.flushAGP();
254 }
255} 139}
256 140
257void LLDrawPool::syncAGP() 141void LLDrawPool::resetTrianglesDrawn()
258{ 142{
259 if (!getVertexCount()) 143 mIndicesDrawn = 0;
260 { 144}
261 return;
262 }
263 setUseAGP(gPipeline.usingAGP());
264 145
265 BOOL all_agp_on = TRUE; 146void LLDrawPool::addIndicesDrawn(const U32 indices)
266 mMemory.sync(); 147{
267 all_agp_on &= mMemory.isAGP(); 148 mIndicesDrawn += indices;
149}
268 150
269 if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK) 151//=============================
270 { 152// Face Pool Implementation
271 mWeights.sync(); 153//=============================
272 all_agp_on &= mWeights.isAGP(); 154LLFacePool::LLFacePool(const U32 type)
273 } 155: LLDrawPool(type)
156{
157 resetDrawOrders();
158}
274 159
275 if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) 160LLFacePool::~LLFacePool()
276 { 161{
277 mClothingWeights.sync(); 162 destroy();
278 all_agp_on &= mClothingWeights.isAGP(); 163}
279 }
280 164
281 // Since sometimes AGP allocation is done during syncs, we need 165void LLFacePool::destroy()
282 // to make sure that if AGP allocation fails, we fallback to non-agp. 166{
283 if (mUseAGP && !all_agp_on) 167 if (!mReferences.empty())
284 { 168 {
285#ifdef DEBUG_AGP 169 llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl;
286 llinfos << "setUseAGP false because of AGP sync failure!" << llendl;
287#endif
288 setUseAGP(FALSE);
289 } 170 }
290} 171}
291 172
292void LLDrawPool::dirtyTexture(const LLViewerImage *imagep) 173void LLFacePool::dirtyTextures(const std::set<LLViewerImage*>& textures)
293{ 174{
294} 175}
295 176
296BOOL LLDrawPool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data) 177BOOL LLFacePool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data)
297{ 178{
298 return TRUE; 179 return TRUE;
299} 180}
300 181
301// static 182// static
302S32 LLDrawPool::drawLoop(face_array_t& face_list, const U32* index_array) 183S32 LLFacePool::drawLoop(face_array_t& face_list)
303{ 184{
304 S32 res = 0; 185 S32 res = 0;
305 if (!face_list.empty()) 186 if (!face_list.empty())
@@ -308,19 +189,15 @@ S32 LLDrawPool::drawLoop(face_array_t& face_list, const U32* index_array)
308 iter != face_list.end(); iter++) 189 iter != face_list.end(); iter++)
309 { 190 {
310 LLFace *facep = *iter; 191 LLFace *facep = *iter;
311 if (facep->mSkipRender) 192 //facep->enableLights();
312 { 193 res += facep->renderIndexed();
313 continue;
314 }
315 facep->enableLights();
316 res += facep->renderIndexed(index_array);
317 } 194 }
318 } 195 }
319 return res; 196 return res;
320} 197}
321 198
322// static 199// static
323S32 LLDrawPool::drawLoopSetTex(face_array_t& face_list, const U32* index_array, S32 stage) 200S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
324{ 201{
325 S32 res = 0; 202 S32 res = 0;
326 if (!face_list.empty()) 203 if (!face_list.empty())
@@ -329,117 +206,30 @@ S32 LLDrawPool::drawLoopSetTex(face_array_t& face_list, const U32* index_array,
329 iter != face_list.end(); iter++) 206 iter != face_list.end(); iter++)
330 { 207 {
331 LLFace *facep = *iter; 208 LLFace *facep = *iter;
332 if (facep->mSkipRender)
333 {
334 continue;
335 }
336 facep->bindTexture(stage); 209 facep->bindTexture(stage);
337 facep->enableLights(); 210 facep->enableLights();
338 res += facep->renderIndexed(index_array); 211 res += facep->renderIndexed();
339 } 212 }
340 } 213 }
341 return res; 214 return res;
342} 215}
343 216
344void LLDrawPool::drawLoop() 217void LLFacePool::drawLoop()
345{ 218{
346 const U32* index_array = getRawIndices();
347 if (!mDrawFace.empty()) 219 if (!mDrawFace.empty())
348 { 220 {
349 mIndicesDrawn += drawLoop(mDrawFace, index_array); 221 mIndicesDrawn += drawLoop(mDrawFace);
350 } 222 }
351} 223}
352 224
353BOOL LLDrawPool::getVertexStrider(LLStrider<LLVector3> &vertices, const U32 index) 225void LLFacePool::renderFaceSelected(LLFace *facep,
354{
355 llassert(mDataMaskIL & LLDrawPool::DATA_VERTICES_MASK);
356 vertices = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_VERTICES] + index * mStride);
357 vertices.setStride(mStride);
358 return TRUE;
359}
360
361BOOL LLDrawPool::getTexCoordStrider(LLStrider<LLVector2> &tex_coords, const U32 index, const U32 pass)
362{
363 llassert(mDataMaskIL & (LLDrawPool::DATA_TEX_COORDS0_MASK << pass));
364 tex_coords = (LLVector2*)(mMemory.getMem() + mDataOffsets[DATA_TEX_COORDS0 + pass] + index * mStride);
365 tex_coords.setStride(mStride);
366 return TRUE;
367}
368
369
370BOOL LLDrawPool::getVertexWeightStrider(LLStrider<F32> &vertex_weights, const U32 index)
371{
372 llassert(mDataMaskNIL & LLDrawPool::DATA_VERTEX_WEIGHTS_MASK);
373
374 vertex_weights = &mWeights[index];
375 vertex_weights.setStride( 0 );
376 return TRUE;
377}
378
379BOOL LLDrawPool::getClothingWeightStrider(LLStrider<LLVector4> &clothing_weights, const U32 index)
380{
381 llassert(mDataMaskNIL & LLDrawPool::DATA_CLOTHING_WEIGHTS_MASK);
382
383 clothing_weights= &mClothingWeights[index];
384 clothing_weights.setStride( 0 );
385
386 return TRUE;
387}
388
389BOOL LLDrawPool::getNormalStrider(LLStrider<LLVector3> &normals, const U32 index)
390{
391 llassert((mDataMaskIL) & LLDrawPool::DATA_NORMALS_MASK);
392
393 normals = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_NORMALS] + index * mStride);
394
395 normals.setStride( mStride );
396
397 return TRUE;
398}
399
400
401BOOL LLDrawPool::getBinormalStrider(LLStrider<LLVector3> &binormals, const U32 index)
402{
403 llassert((mDataMaskIL) & LLDrawPool::DATA_BINORMALS_MASK);
404
405 binormals = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_BINORMALS] + index * mStride);
406
407 binormals.setStride( mStride );
408
409 return TRUE;
410}
411
412BOOL LLDrawPool::getColorStrider(LLStrider<LLColor4U> &colors, const U32 index)
413{
414 llassert((mDataMaskIL) & LLDrawPool::DATA_COLORS_MASK);
415
416 colors = (LLColor4U*)(mMemory.getMem() + mDataOffsets[DATA_COLORS] + index * mStride);
417
418 colors.setStride( mStride );
419
420 return TRUE;
421}
422
423//virtual
424void LLDrawPool::beginRenderPass( S32 pass )
425{
426}
427
428//virtual
429void LLDrawPool::endRenderPass( S32 pass )
430{
431 glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
432 glDisableClientState ( GL_COLOR_ARRAY );
433 glDisableClientState ( GL_NORMAL_ARRAY );
434}
435void LLDrawPool::renderFaceSelected(LLFace *facep,
436 LLImageGL *image, 226 LLImageGL *image,
437 const LLColor4 &color, 227 const LLColor4 &color,
438 const S32 index_offset, const S32 index_count) 228 const S32 index_offset, const S32 index_count)
439{ 229{
440} 230}
441 231
442void LLDrawPool::renderVisibility() 232void LLFacePool::renderVisibility()
443{ 233{
444 if (mDrawFace.empty()) 234 if (mDrawFace.empty())
445 { 235 {
@@ -525,893 +315,284 @@ void LLDrawPool::renderVisibility()
525 315
526} 316}
527 317
528void LLDrawPool::enqueue(LLFace* facep) 318void LLFacePool::enqueue(LLFace* facep)
529{
530 if (facep->isState(LLFace::BACKLIST))
531 {
532 mMoveFace.put(facep);
533 }
534 else
535 {
536#if ENABLE_FACE_LINKING
537 facep->mSkipRender = FALSE;
538 facep->mNextFace = NULL;
539
540 if (mDrawFace.size() > 0)
541 {
542 LLFace* last_face = mDrawFace[mDrawFace.size()-1];
543 if (match(last_face, facep))
544 {
545 last_face->link(facep);
546 }
547 }
548#endif
549 mDrawFace.put(facep);
550 }
551}
552
553void LLDrawPool::bindGLVertexPointer()
554{
555 mMemory.bindGLVertexPointer(getStride(DATA_VERTICES), mDataOffsets[DATA_VERTICES]);
556}
557
558void LLDrawPool::bindGLTexCoordPointer(const U32 pass)
559{
560 mMemory.bindGLTexCoordPointer(getStride(DATA_TEX_COORDS0+pass), mDataOffsets[DATA_TEX_COORDS0+pass]);
561}
562
563void LLDrawPool::bindGLNormalPointer()
564{
565 mMemory.bindGLNormalPointer(getStride(DATA_NORMALS), mDataOffsets[DATA_NORMALS]);
566}
567
568void LLDrawPool::bindGLBinormalPointer(S32 index)
569{
570 mMemory.bindGLBinormalPointer(index, getStride(DATA_BINORMALS), mDataOffsets[DATA_BINORMALS]);
571}
572
573void LLDrawPool::bindGLColorPointer()
574{ 319{
575 mMemory.bindGLColorPointer(getStride(DATA_COLORS), mDataOffsets[DATA_COLORS]); 320 mDrawFace.push_back(facep);
576} 321}
577 322
578void LLDrawPool::bindGLVertexWeightPointer(S32 index) 323// virtual
579{ 324BOOL LLFacePool::addFace(LLFace *facep)
580 mWeights.bindGLVertexWeightPointer(index, 0, 0);
581}
582
583void LLDrawPool::bindGLVertexClothingWeightPointer(S32 index)
584{
585 mClothingWeights.bindGLVertexClothingWeightPointer(index, 0, 0);
586}
587
588
589U32* LLDrawPool::getIndices(S32 index)
590{
591 return &mIndices[index];
592}
593
594const LLVector3& LLDrawPool::getVertex(const S32 index)
595{
596 llassert(mDataMaskIL & DATA_VERTICES_MASK);
597 llassert(index < mMemory.count());
598 llassert(mMemory.getMem());
599 return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_VERTICES] + index * mStride);
600}
601
602const LLVector2& LLDrawPool::getTexCoord(const S32 index, const U32 pass)
603{ 325{
604 llassert(mDataMaskIL & (LLDrawPool::DATA_TEX_COORDS0_MASK << pass)); 326 addFaceReference(facep);
605 llassert(index < mMemory.count()); 327 return TRUE;
606 return *(LLVector2*)(mMemory.getMem() + mDataOffsets[DATA_TEX_COORDS0 + pass] + index * mStride);
607} 328}
608 329
609const LLVector3& LLDrawPool::getNormal(const S32 index) 330// virtual
331BOOL LLFacePool::removeFace(LLFace *facep)
610{ 332{
611 llassert(mDataMaskIL & DATA_NORMALS_MASK); 333 removeFaceReference(facep);
612 llassert(index < mMemory.count());
613 return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_NORMALS] + index * mStride);
614}
615 334
616const LLVector3& LLDrawPool::getBinormal(const S32 index) 335 vector_replace_with_last(mDrawFace, facep);
617{
618 llassert(mDataMaskIL & DATA_BINORMALS_MASK);
619 llassert(index < mMemory.count());
620 return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_BINORMALS] + index * mStride);
621}
622 336
623const LLColor4U& LLDrawPool::getColor(const S32 index) 337 return TRUE;
624{
625 llassert(mDataMaskIL & DATA_COLORS_MASK);
626 llassert(index < mMemory.count());
627 return *(LLColor4U*)(mMemory.getMem() + mDataOffsets[DATA_COLORS] + index * mStride);
628} 338}
629 339
630const F32& LLDrawPool::getVertexWeight(const S32 index) 340// Not absolutely sure if we should be resetting all of the chained pools as well - djs
341void LLFacePool::resetDrawOrders()
631{ 342{
632 llassert(mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK); 343 mDrawFace.resize(0);
633 llassert(index < mWeights.count());
634 llassert(mWeights.getMem());
635 return mWeights[index];
636} 344}
637 345
638const LLVector4& LLDrawPool::getClothingWeight(const S32 index) 346LLViewerImage *LLFacePool::getTexture()
639{ 347{
640 llassert(mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK); 348 return NULL;
641 llassert(index < mClothingWeights.count());
642 llassert(mClothingWeights.getMem());
643 return mClothingWeights[index];
644} 349}
645 350
646////////////////////////////////////////////////////////////////////////////// 351void LLFacePool::removeFaceReference(LLFace *facep)
647
648#define USE_FREE_LIST 0
649#define DEBUG_FREELIST 0
650
651struct tFreeListNode
652{ 352{
653 U32 count; 353 if (facep->getReferenceIndex() != -1)
654 S32 next;
655};
656
657#if DEBUG_FREELIST
658static void check_list(U8 *pool, S32 stride, S32 head, S32 max)
659{
660 int count = 0;
661
662 while (head >= 0)
663 { 354 {
664 tFreeListNode *node = (tFreeListNode *)(pool + head*stride); 355 if (facep->getReferenceIndex() != (S32)mReferences.size())
665 count++; 356 {
666 if ((count > max) || ((node->count>>20) != 0xabc) || ((node->count&0xfffff) < 2)) 357 LLFace *back = mReferences.back();
667 llerrs << "Bad Ind List" << llendl; 358 mReferences[facep->getReferenceIndex()] = back;
668 head = node->next; 359 back->setReferenceIndex(facep->getReferenceIndex());
360 }
361 mReferences.pop_back();
669 } 362 }
363 facep->setReferenceIndex(-1);
670} 364}
671#define CHECK_LIST(x) check_list##x
672#else
673#define CHECK_LIST(x)
674#endif
675 365
676// DEBUG! 366void LLFacePool::addFaceReference(LLFace *facep)
677void LLDrawPool::CheckIntegrity()
678{ 367{
679#if DEBUG_FREELIST 368 if (-1 == facep->getReferenceIndex())
680 int bucket;
681 for (bucket=0; bucket<NUM_BUCKETS; bucket++)
682 { 369 {
683 CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[bucket], mMemory.count() / mStride)); 370 facep->setReferenceIndex(mReferences.size());
684 CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[bucket], mIndices.count())); 371 mReferences.push_back(facep);
685 } 372 }
686#endif
687} 373}
688 374
689int LLDrawPool::freeListBucket(U32 count) 375BOOL LLFacePool::verify() const
690{ 376{
691 int bucket; 377 BOOL ok = TRUE;
692
693 // llassert(NUM_BUCKETS == 8)
694 378
695 if (count & ~511) // >= 512 379 for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin();
696 bucket = 7; 380 iter != mDrawFace.end(); iter++)
697 else if (count & 256) // 256-511
698 bucket = 6;
699 else if (count & 128)
700 bucket = 5;
701 else if (count & 64)
702 bucket = 4;
703 else if (count & 32)
704 bucket = 3;
705 else if (count & 16)
706 bucket = 2;
707 else if (count & 8) // 8-15
708 bucket = 1;
709 else // 0-7
710 bucket = 0;
711 return bucket;
712}
713
714void remove_node(int nodeidx, int pidx, U8 *membase, int stride, int *head)
715{
716 LLDrawPool::FreeListNode *node = (LLDrawPool::FreeListNode *)(membase + nodeidx*stride);
717 if (pidx >= 0)
718 {
719 LLDrawPool::FreeListNode *pnode = (LLDrawPool::FreeListNode *)(membase + pidx*stride);
720 pnode->next = node->next;
721 }
722 else
723 {
724 *head = node->next;
725 }
726}
727
728void LLDrawPool::freeListAddGeom(S32 index, U32 count)
729{
730#if USE_FREE_LIST
731 int i;
732 U8 *membase = (U8*)mMemory.getMem();
733 // See if next block or previous block is free, if so combine them
734 for (i=0; i<NUM_BUCKETS; i++)
735 {
736 int pidx = -1;
737 int nodeidx = mFreeListGeomHead[i];
738 while(nodeidx >= 0)
739 {
740 int change = 0;
741 FreeListNode *node = (FreeListNode *)(membase + nodeidx*mStride);
742 int nodecount = node->count & 0xffff;
743 // Check for prev block
744 if (nodeidx + nodecount == index)
745 {
746 remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]);
747 // Combine nodes
748 index = nodeidx;
749 count += nodecount;
750 i = 0; // start over ; i = NUM_BUCKETS // done
751 change = 1;
752 //break;
753 }
754 // Check for next block
755 if (nodeidx == index + count)
756 {
757 remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]);
758 // Combine nodes
759 count += nodecount;
760 i = 0; // start over ; i = NUM_BUCKETS // done
761 change = 1;
762 //break;
763 }
764 if (change)
765 break;
766 pidx = nodeidx;
767 nodeidx = node->next;
768 }
769 }
770 // Add (extended) block to free list
771 if (count >= 2) // need 2 words to store free list (theoreticly mStride could = 4)
772 { 381 {
773 CheckIntegrity(); 382 const LLFace* facep = *iter;
774 if ((index + count)*mStride >= mMemory.count()) 383 if (facep->getPool() != this)
775 { 384 {
776 mMemory.shrinkTo(index*mStride); 385 llinfos << "Face in wrong pool!" << llendl;
386 facep->printDebugInfo();
387 ok = FALSE;
777 } 388 }
778 else 389 else if (!facep->verify())
779 { 390 {
780 int bucket = freeListBucket(count); 391 ok = FALSE;
781 FreeListNode *node = (FreeListNode *)(membase + index*mStride);
782 node->count = count | (0xabc<<20);
783 node->next = mFreeListGeomHead[bucket];
784 mFreeListGeomHead[bucket] = index;
785 } 392 }
786 CheckIntegrity();
787 } 393 }
788#endif
789}
790 394
791void LLDrawPool::freeListAddInd(S32 index, U32 count) 395 return ok;
792{
793#if USE_FREE_LIST
794 int i;
795 const U32 *membase = mIndices.getMem();
796 // See if next block or previous block is free, if so combine them
797 for (i=0; i<NUM_BUCKETS; i++)
798 {
799 int pidx = -1;
800 int nodeidx = mFreeListIndHead[i];
801 while(nodeidx >= 0)
802 {
803 int change = 0;
804 FreeListNode *node = (FreeListNode *)(membase + nodeidx);
805 int nodecount = node->count & 0xffff;
806 // Check for prev block
807 if (nodeidx + nodecount == index)
808 {
809 remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]);
810 // Combine nodes
811 index = nodeidx;
812 count += nodecount;
813 i = 0; // start over ; i = NUM_BUCKETS // done
814 change = 1;
815 //break;
816 }
817 // Check for next block
818 if (nodeidx == index + count)
819 {
820 remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]);
821 // Combine nodes
822 count += nodecount;
823 i = 0; // start over ; i = NUM_BUCKETS // done
824 change = 1;
825 //break;
826 }
827 if (change)
828 break;
829 pidx = nodeidx;
830 nodeidx = node->next;
831 }
832 }
833 // Add (extended) block to free list
834 if (count >= 2) // need 2 words to store free list
835 {
836 CheckIntegrity();
837 if (index + count >= mIndices.count())
838 {
839 mIndices.shrinkTo(index);
840 }
841 else
842 {
843 int bucket = freeListBucket(count);
844 FreeListNode *node = (FreeListNode *)(membase + index);
845 node->count = count | (0xabc<<20);
846 node->next = mFreeListIndHead[bucket];
847 mFreeListIndHead[bucket] = index;
848 }
849 CheckIntegrity();
850 }
851#endif
852} 396}
853 397
854S32 LLDrawPool::freeListFindGeom(U32 count) 398void LLFacePool::printDebugInfo() const
855{ 399{
856#if USE_FREE_LIST 400 llinfos << "Pool " << this << " Type: " << getType() << llendl;
857 int i, nodeidx, pidx;
858 int firstbucket = freeListBucket(count);
859 U8 *membase = (U8*)mMemory.getMem();
860 for (i=firstbucket; i<NUM_BUCKETS; i++)
861 {
862 pidx = -1;
863 nodeidx = mFreeListGeomHead[i];
864 CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[i], mMemory.count() / mStride));
865 while(nodeidx >= 0)
866 {
867 FreeListNode *node = (FreeListNode *)(membase + nodeidx*mStride);
868 int nodecount = node->count & 0xffff;
869 llassert((node->count>>20) == 0xabc);
870 if (nodecount >= count)
871 {
872 remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]);
873#if 1
874 if (nodecount > count)
875 {
876 int leftover = nodecount - count;
877 freeListAddGeom(nodeidx + count, leftover);
878 }
879#endif
880 return nodeidx;
881 }
882 pidx = nodeidx;
883 nodeidx = node->next;
884 }
885 }
886#endif // USE_FREE_LIST
887 return -1;
888} 401}
889 402
890S32 LLDrawPool::freeListFindInd(U32 count) 403BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
404
405void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
891{ 406{
892#if USE_FREE_LIST 407 if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
893 int i, nodeidx, pidx;
894 int firstbucket = freeListBucket(count);
895 U32 *membase = (U32 *)mIndices.getMem();
896 for (i=firstbucket; i<NUM_BUCKETS; i++)
897 { 408 {
898 pidx = -1; 409 glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV);
899 nodeidx = mFreeListIndHead[i];
900 CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[i], mIndices.count()));
901 while(nodeidx >= 0)
902 {
903 FreeListNode *node = (FreeListNode *)(membase + nodeidx);
904 int nodecount = node->count & 0xffff;
905 llassert((node->count>>20) == 0xabc);
906 if (nodecount >= count)
907 {
908 remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]);
909#if 1
910 if (nodecount > count)
911 {
912 int leftover = nodecount - count;
913 freeListAddInd(nodeidx + count, leftover);
914 }
915#endif
916 return nodeidx;
917 }
918 pidx = nodeidx;
919 nodeidx = node->next;
920 }
921 } 410 }
922#endif // USE_FREE_LIST 411 else
923 return -1;
924}
925
926//////////////////////////////////////////////////////////////////////////////
927
928S32 LLDrawPool::reserveGeom(const U32 geom_count)
929{
930 LLFastTimer t(LLFastTimer::FTM_GEO_RESERVE);
931
932 S32 index;
933 index = freeListFindGeom(geom_count);
934 if (index < 0)
935 { 412 {
936 index = mMemory.count() / mStride; 413 glColor4fv(color.mV);
937 if (!geom_count)
938 {
939 llwarns << "Attempting to reserve zero bytes!" << llendl;
940 return index;
941 }
942
943 S32 bytes = geom_count * mStride;
944
945 if ((index + (S32)geom_count) > (S32)mMaxVertices)
946 {
947 //
948 // Various drivers have issues with the number of indices being greater than a certain number.
949 // if you're using AGP. Disable AGP if we've got more vertices than in the pool.
950 //
951#ifdef DEBUG_AGP
952 llinfos << "setUseAGP false because of large vertex count in reserveGeom" << llendl;
953#endif
954 setUseAGP(FALSE);
955 }
956
957 mMemory.reserve_block(bytes);
958 if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
959 {
960 mWeights.reserve_block(geom_count);
961 }
962 if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
963 {
964 mClothingWeights.reserve_block(geom_count);
965 }
966 } 414 }
967 CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[0], mMemory.count() / mStride));
968 return index;
969} 415}
970 416
971S32 LLDrawPool::reserveInd(U32 indCount) 417void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
972{ 418{
973 S32 index; 419 if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
974 index = freeListFindInd(indCount);
975 if (index < 0)
976 { 420 {
977 index = mIndices.count(); 421 glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV);
978
979 if (indCount)
980 {
981 mIndices.reserve_block(indCount);
982 }
983 } 422 }
984 for (U32 i=0;i<indCount;i++) 423 else
985 { 424 {
986 mIndices[index+i]=0; 425 glColor4ubv(color.mV);
987 } 426 }
988 CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[0], mIndices.count()));
989 return index;
990} 427}
991 428
992S32 LLDrawPool::unReserveGeom(const S32 index, const U32 count) 429void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
993{ 430{
994 if (index < 0 || count == 0) 431 if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
995 return -1;
996
997 freeListAddGeom(index, count);
998
999#if 0
1000 int i;
1001 S32 bytes,words;
1002 U32 *memp;
1003 // Fill mem with bad data (for testing only)
1004 bytes = count * mStride;
1005 bytes -= sizeof(FreeListNode);
1006 memp = (U32*)(mMemory.getMem() + index * mStride);
1007 memp += sizeof(FreeListNode)>>2;
1008 words = bytes >> 2;
1009 for (i=0; i<words; i++)
1010 *memp++ = 0xffffffff;
1011
1012 words = count; // (sizeof each array is a word)
1013 if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
1014 { 432 {
1015 memp = (U32*)(&mWeights[index]); 433 glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a);
1016 for (i=0; i<words; i++)
1017 *memp++ = 0xffffffff;
1018 } 434 }
1019 if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) 435 else
1020 { 436 {
1021 memp = (U32*)(&mClothingWeights[index]); 437 glColor4f(r,g,b,a);
1022 for (i=0; i<count; i++)
1023 *memp++ = 0xffffffff;
1024 } 438 }
1025#endif
1026 return -1;
1027} 439}
1028 440
1029S32 LLDrawPool::unReserveInd(const S32 index, const U32 count)
1030{
1031 if (index < 0 || count == 0)
1032 return -1;
1033 441
1034 freeListAddInd(index, count); 442//=============================
1035 443// Render Pass Implementation
1036#if 0 444//=============================
1037 int i; 445LLRenderPass::LLRenderPass(const U32 type)
1038 U32 *memp = &mIndices[index]; 446: LLDrawPool(type)
1039 for (i=0; i<count; i++)
1040 *memp++ = 0xffffffff;
1041#endif
1042 return -1;
1043}
1044
1045//////////////////////////////////////////////////////////////////////////////
1046
1047const U32 LLDrawPool::getIndexCount() const
1048{ 447{
1049 return mIndices.count();
1050}
1051 448
1052const U32 LLDrawPool::getVertexCount() const
1053{
1054 return mMemory.count() / mStride;
1055} 449}
1056 450
1057const U32 LLDrawPool::getTexCoordCount(U32 pass) const 451LLRenderPass::~LLRenderPass()
1058{ 452{
1059 return mMemory.count() / mStride;
1060}
1061 453
1062
1063const U32 LLDrawPool::getNormalCount() const
1064{
1065 return mMemory.count() / mStride;
1066} 454}
1067 455
1068 456LLDrawPool* LLRenderPass::instancePool()
1069const U32 LLDrawPool::getBinormalCount() const
1070{ 457{
1071 return mMemory.count() / mStride; 458#if LL_RELEASE_FOR_DOWNLOAD
1072} 459 llwarns << "Attempting to instance a render pass. Invalid operation." << llendl;
1073 460#else
1074const U32 LLDrawPool::getColorCount() const 461 llerrs << "Attempting to instance a render pass. Invalid operation." << llendl;
1075{ 462#endif
1076 return mMemory.count() / mStride; 463 return NULL;
1077}
1078
1079const U32 LLDrawPool::getVertexWeightCount() const
1080{
1081 return mWeights.count();
1082} 464}
1083 465
1084// virtual 466void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
1085BOOL LLDrawPool::addFace(LLFace *facep) 467{
1086{ 468 std::vector<LLDrawInfo*>& draw_info = group->mDrawMap[type];
1087 addFaceReference(facep); 469
1088 return TRUE; 470 for (std::vector<LLDrawInfo*>::const_iterator k = draw_info.begin(); k != draw_info.end(); ++k)
471 {
472 LLDrawInfo& params = **k;
473 pushBatch(params, mask, texture);
474 }
1089} 475}
1090 476
1091// virtual 477void LLRenderPass::renderInvisible(U32 mask)
1092BOOL LLDrawPool::removeFace(LLFace *facep)
1093{ 478{
1094 removeFaceReference(facep); 479#if !LL_RELEASE_FOR_DOWNLOAD
1095 480 LLGLState::checkClientArrays(mask);
1096 vector_replace_with_last(mDrawFace, facep); 481#endif
1097
1098 facep->unReserve();
1099 482
1100 return TRUE; 483 std::vector<LLDrawInfo*>& draw_info = gPipeline.mRenderMap[LLRenderPass::PASS_INVISIBLE];
1101}
1102 484
1103// Not absolutely sure if we should be resetting all of the chained pools as well - djs 485 U32* indices_pointer = NULL;
1104void LLDrawPool::resetDrawOrders() 486 for (std::vector<LLDrawInfo*>::iterator i = draw_info.begin(); i != draw_info.end(); ++i)
1105{ 487 {
1106 mDrawFace.resize(0); 488 LLDrawInfo& params = **i;
489 params.mVertexBuffer->setBuffer(mask);
490 indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer();
491 glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount,
492 GL_UNSIGNED_INT, indices_pointer+params.mOffset);
493 gPipeline.mTrianglesDrawn += params.mCount/3;
494 }
1107} 495}
1108 496
1109void LLDrawPool::resetIndices(S32 indices_count) 497void LLRenderPass::renderTexture(U32 type, U32 mask)
1110{ 498{
1111 mIndices.reset(indices_count); 499#if !LL_RELEASE_FOR_DOWNLOAD
1112 for (S32 i=0; i<NUM_BUCKETS; i++) 500 LLGLState::checkClientArrays(mask);
1113 mFreeListIndHead[i] = -1; 501#endif
1114}
1115 502
1116void LLDrawPool::resetVertexData(S32 reserve_count) 503 std::vector<LLDrawInfo*>& draw_info = gPipeline.mRenderMap[type];
1117{
1118 mMemory.reset(reserve_count*mStride);
1119
1120 for (S32 i=0; i<NUM_BUCKETS; i++)
1121 {
1122 mFreeListGeomHead[i] = -1;
1123 }
1124 if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
1125 {
1126 mWeights.reset(reserve_count);
1127 }
1128 504
1129 if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK) 505 for (std::vector<LLDrawInfo*>::iterator i = draw_info.begin(); i != draw_info.end(); ++i)
1130 { 506 {
1131 mClothingWeights.reset(reserve_count); 507 LLDrawInfo& params = **i;
508 pushBatch(params, mask, TRUE);
1132 } 509 }
1133} 510}
1134 511
1135void LLDrawPool::resetAll() 512void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
1136{
1137 resetDrawOrders();
1138 resetVertexData(0);
1139 mGeneration++;
1140
1141}
1142
1143S32 LLDrawPool::rebuild()
1144{ 513{
1145 mRebuildTime++; 514 if (params.mVertexBuffer.isNull())
1146
1147 BOOL needs_rebuild = FALSE;
1148 S32 rebuild_cost = 0;
1149
1150 if (mUseAGP)
1151 {
1152 if (getVertexCount() > 0.75f*DEFAULT_MAX_VERTICES)
1153 {
1154 if (mRebuildTime > 8)
1155 {
1156 needs_rebuild = TRUE;
1157 }
1158#ifdef DEBUG_AGP
1159 llwarns << "More than " << DEFAULT_MAX_VERTICES << " in pool type " << (S32)mType << " at rebuild!" << llendl;
1160#endif
1161 }
1162 }
1163
1164 // rebuild de-allocates 'stale' objects, so we still need to do a rebuild periodically
1165 if (mRebuildFreq > 0 && mRebuildTime >= mRebuildFreq)
1166 { 515 {
1167 needs_rebuild = TRUE; 516 return;
1168 } 517 }
1169 518
1170 if (needs_rebuild) 519 if (texture)
1171 { 520 {
1172 mGeneration++; 521 if (params.mTexture.notNull())
1173
1174 if (mReferences.empty())
1175 { 522 {
1176 resetIndices(0); 523 params.mTexture->bind();
1177 resetVertexData(0); 524 if (params.mTextureMatrix)
1178 }
1179 else
1180 {
1181 for (std::vector<LLFace*>::iterator iter = mReferences.begin();
1182 iter != mReferences.end(); iter++)
1183 {
1184 LLFace *facep = *iter;
1185 if (facep->hasGeometry() && !facep->isState(LLFace::BACKLIST | LLFace::SHARED_GEOM))
1186 {
1187 facep->backup();
1188 }
1189 }
1190 S32 tot_verts = 0;
1191 S32 tot_indices = 0;
1192 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
1193 iter != mDrawFace.end(); iter++)
1194 {
1195 LLFace *facep = *iter;
1196 if (facep->isState(LLFace::BACKLIST))
1197 {
1198 tot_verts += facep->getGeomCount();
1199 tot_indices += facep->getIndicesCount();
1200 }
1201 }
1202 for (std::vector<LLFace*>::iterator iter = mMoveFace.begin();
1203 iter != mMoveFace.end(); iter++)
1204 { 525 {
1205 LLFace *facep = *iter; 526 glMatrixMode(GL_TEXTURE);
1206 if (facep->isState(LLFace::BACKLIST)) 527 glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
1207 {
1208 tot_verts += facep->getGeomCount();
1209 tot_indices += facep->getIndicesCount();
1210 }
1211 }
1212
1213 resetIndices(tot_indices);
1214 flushAGP();
1215 resetVertexData(tot_verts);
1216
1217 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
1218 iter != mDrawFace.end(); iter++)
1219 {
1220 LLFace *facep = *iter;
1221 llassert(facep->getPool() == this);
1222 facep->restore();
1223 } 528 }
529 params.mTexture->addTextureStats(params.mVSize);
1224 } 530 }
1225 mRebuildTime = 0; 531 else
1226 setDirty();
1227 }
1228
1229 if (!mMoveFace.empty())
1230 {
1231 for (std::vector<LLFace*>::iterator iter = mMoveFace.begin();
1232 iter != mMoveFace.end(); iter++)
1233 {
1234 LLFace *facep = *iter;
1235 facep->restore();
1236 enqueue(facep);
1237 }
1238 setDirty();
1239 mMoveFace.reset();
1240 rebuild_cost++;
1241 }
1242 return rebuild_cost;
1243}
1244
1245LLViewerImage *LLDrawPool::getTexture()
1246{
1247 return NULL;
1248}
1249
1250LLViewerImage *LLDrawPool::getDebugTexture()
1251{
1252 return NULL;
1253}
1254
1255void LLDrawPool::removeFaceReference(LLFace *facep)
1256{
1257 if (facep->getReferenceIndex() != -1)
1258 {
1259 if (facep->getReferenceIndex() != (S32)mReferences.size())
1260 { 532 {
1261 LLFace *back = mReferences.back(); 533 LLImageGL::unbindTexture(0);
1262 mReferences[facep->getReferenceIndex()] = back;
1263 back->setReferenceIndex(facep->getReferenceIndex());
1264 } 534 }
1265 mReferences.pop_back();
1266 } 535 }
1267 facep->setReferenceIndex(-1); 536
1268} 537 params.mVertexBuffer->setBuffer(mask);
538 U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer();
539 glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount,
540 GL_UNSIGNED_INT, indices_pointer+params.mOffset);
541 gPipeline.mTrianglesDrawn += params.mCount/3;
1269 542
1270void LLDrawPool::addFaceReference(LLFace *facep) 543 if (params.mTextureMatrix && texture && params.mTexture.notNull())
1271{
1272 if (-1 == facep->getReferenceIndex())
1273 { 544 {
1274 facep->setReferenceIndex(mReferences.size()); 545 glLoadIdentity();
1275 mReferences.push_back(facep); 546 glMatrixMode(GL_MODELVIEW);
1276 } 547 }
1277} 548}
1278 549
1279U32 LLDrawPool::getTrianglesDrawn() const 550void LLRenderPass::renderActive(U32 type, U32 mask, BOOL texture)
1280{ 551{
1281 return mIndicesDrawn / 3; 552#if !LL_RELEASE_FOR_DOWNLOAD
1282} 553 LLGLState::checkClientArrays(mask);
1283 554#endif
1284void LLDrawPool::resetTrianglesDrawn()
1285{
1286 mIndicesDrawn = 0;
1287}
1288
1289void LLDrawPool::addIndicesDrawn(const U32 indices)
1290{
1291 mIndicesDrawn += indices;
1292}
1293 555
1294BOOL LLDrawPool::verify() const 556 LLSpatialBridge* last_bridge = NULL;
1295{ 557 glPushMatrix();
1296 BOOL ok = TRUE; 558
1297 // Verify all indices in the pool are in the right range 559 for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i)
1298 const U32 *indicesp = getRawIndices();
1299 for (U32 i = 0; i < getIndexCount(); i++)
1300 { 560 {
1301 if (indicesp[i] > getVertexCount()) 561 LLSpatialGroup* group = *i;
562 if (!group->isDead() &&
563 gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
564 group->mDrawMap.find(type) != group->mDrawMap.end())
1302 { 565 {
1303 ok = FALSE; 566 LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition;
1304 llinfos << "Bad index in tree pool!" << llendl; 567 if (bridge != last_bridge)
1305 } 568 {
1306 } 569 glPopMatrix();
570 glPushMatrix();
571 glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix);
572 last_bridge = bridge;
573 }
1307 574
1308 for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin(); 575 renderGroup(group,type,mask,texture);
1309 iter != mDrawFace.end(); iter++)
1310 {
1311 const LLFace* facep = *iter;
1312 if (facep->getPool() != this)
1313 {
1314 llinfos << "Face in wrong pool!" << llendl;
1315 facep->printDebugInfo();
1316 ok = FALSE;
1317 }
1318 else if (!facep->verify())
1319 {
1320 ok = FALSE;
1321 } 576 }
1322 } 577 }
1323 578
1324 return ok; 579 glPopMatrix();
1325}
1326
1327void LLDrawPool::printDebugInfo() const
1328{
1329 llinfos << "Pool " << this << " Type: " << getType() << llendl;
1330 llinfos << "--------------------" << llendl;
1331 llinfos << "Vertex count: " << getVertexCount() << llendl;
1332 llinfos << "Normal count: " << getNormalCount() << llendl;
1333 llinfos << "Indices count: " << getIndexCount() << llendl;
1334 llinfos << llendl;
1335}
1336
1337
1338S32 LLDrawPool::getMemUsage(const BOOL print)
1339{
1340 S32 mem_usage = 0;
1341
1342 mem_usage += sizeof(this);
1343
1344 // Usage beyond the pipeline allocated data (color and mMemory)
1345 mem_usage += mIndices.getMax() * sizeof(U32);
1346 mem_usage += mDrawFace.capacity() * sizeof(LLFace *);
1347 mem_usage += mMoveFace.capacity() * sizeof(LLFace *);
1348 mem_usage += mReferences.capacity() * sizeof(LLFace *);
1349
1350 mem_usage += mMemory.getSysMemUsage();
1351 mem_usage += mWeights.getSysMemUsage();
1352 mem_usage += mClothingWeights.getSysMemUsage();
1353
1354 return mem_usage;
1355}
1356
1357LLColor3 LLDrawPool::getDebugColor() const
1358{
1359 return LLColor3(0.f, 0.f, 0.f);
1360}
1361
1362void LLDrawPool::setDirty()
1363{
1364 mMemory.setDirty();
1365 mWeights.setDirty();
1366 mClothingWeights.setDirty();
1367}
1368
1369BOOL LLDrawPool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
1370
1371void LLDrawPool::LLOverrideFaceColor::setColor(const LLColor4& color)
1372{
1373 if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0)
1374 {
1375 glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV);
1376 }
1377 else
1378 {
1379 glColor4fv(color.mV);
1380 }
1381} 580}
1382 581
1383void LLDrawPool::LLOverrideFaceColor::setColor(const LLColor4U& color) 582void LLRenderPass::renderStatic(U32 type, U32 mask, BOOL texture)
1384{ 583{
1385 if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0) 584#if !LL_RELEASE_FOR_DOWNLOAD
1386 { 585 LLGLState::checkClientArrays(mask);
1387 glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV); 586#endif
1388 }
1389 else
1390 {
1391 glColor4ubv(color.mV);
1392 }
1393}
1394 587
1395void LLDrawPool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a) 588 for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mVisibleGroups.begin(); i != gPipeline.mVisibleGroups.end(); ++i)
1396{
1397 if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0)
1398 {
1399 glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a);
1400 }
1401 else
1402 { 589 {
1403 glColor4f(r,g,b,a); 590 LLSpatialGroup* group = *i;
591 if (!group->isDead() &&
592 gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
593 group->mDrawMap.find(type) != group->mDrawMap.end())
594 {
595 renderGroup(group,type,mask,texture);
596 }
1404 } 597 }
1405} 598}
1406
1407// virtual
1408void LLDrawPool::enableShade()
1409{ }
1410
1411// virtual
1412void LLDrawPool::disableShade()
1413{ }
1414
1415// virtual
1416void LLDrawPool::setShade(F32 shade)
1417{ }