aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:50 -0500
committerJacek Antonelli2008-08-15 23:44:50 -0500
commit89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch)
treebcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/llrender
parentSecond Life viewer sources 1.13.3.2 (diff)
downloadmeta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/llrender')
-rw-r--r--linden/indra/llrender/files.lst4
-rw-r--r--linden/indra/llrender/llagpmempool.cpp194
-rw-r--r--linden/indra/llrender/llagpmempool.h121
-rw-r--r--linden/indra/llrender/llagpmempoolapple.cpp314
-rw-r--r--linden/indra/llrender/llagpmempoolapple.h95
-rw-r--r--linden/indra/llrender/llagpmempoolarb.cpp230
-rw-r--r--linden/indra/llrender/llagpmempoolarb.h103
-rw-r--r--linden/indra/llrender/llagpmempoolati.cpp160
-rw-r--r--linden/indra/llrender/llagpmempoolati.h92
-rw-r--r--linden/indra/llrender/llagpmempoolnv.cpp320
-rw-r--r--linden/indra/llrender/llagpmempoolnv.h95
-rw-r--r--linden/indra/llrender/llfont.h1
-rw-r--r--linden/indra/llrender/llfontgl.cpp12
-rw-r--r--linden/indra/llrender/llgldbg.cpp8
-rw-r--r--linden/indra/llrender/llimagegl.cpp34
-rw-r--r--linden/indra/llrender/llimagegl.h3
-rw-r--r--linden/indra/llrender/llrender.vcproj18
-rw-r--r--linden/indra/llrender/llrender_vc8.vcproj302
-rw-r--r--linden/indra/llrender/llvertexbuffer.cpp922
-rw-r--r--linden/indra/llrender/llvertexbuffer.h179
-rw-r--r--linden/indra/llrender/llvertexprogramgl.cpp6
-rw-r--r--linden/indra/llrender/text_out.cpp4
22 files changed, 1453 insertions, 1764 deletions
diff --git a/linden/indra/llrender/files.lst b/linden/indra/llrender/files.lst
index e7b3cec..a813342 100644
--- a/linden/indra/llrender/files.lst
+++ b/linden/indra/llrender/files.lst
@@ -1,8 +1,6 @@
1llrender/llagpmempoolarb.cpp
2llrender/llagpmempool.cpp
3llrender/llfont.cpp 1llrender/llfont.cpp
4llrender/llfontgl.cpp 2llrender/llfontgl.cpp
5llrender/llgldbg.cpp 3llrender/llgldbg.cpp
6llrender/llimagegl.cpp 4llrender/llimagegl.cpp
7llrender/llvertexprogramgl.cpp 5llrender/llvertexbuffer.cpp
8llrender/text_out.cpp 6llrender/text_out.cpp
diff --git a/linden/indra/llrender/llagpmempool.cpp b/linden/indra/llrender/llagpmempool.cpp
deleted file mode 100644
index 39cd3e8..0000000
--- a/linden/indra/llrender/llagpmempool.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
1/**
2 * @file llagpmempool.cpp
3 * @brief LLAGPMemPool base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "llagpmempool.h"
31#include "llgl.h"
32
33#include "llagpmempoolarb.h"
34#include "llagpmempoolnv.h"
35#include "llagpmempoolati.h"
36
37#if LL_DARWIN
38#include "llagpmempoolapple.h"
39#endif // LL_DARWIN
40
41//static
42S32 LLAGPMemPool::LLFreeBlock::sNumBlocks = 0;
43
44LLAGPMemPool::LLAGPMemPool()
45{
46 mSize = 0;
47 mTotalAllocated = 0;
48}
49
50LLAGPMemPool::~LLAGPMemPool()
51{
52 mFreeList.deleteAll();
53}
54
55LLAGPMemPool *LLAGPMemPool::createPool(const U32 size, const BOOL use_vbo)
56{
57 if (gGLManager.mHasVertexBufferObject && use_vbo)
58 {
59 return new LLAGPMemPoolARB(size);
60 }
61#if LL_WINDOWS // *FIX: linux can use these, too, with some work.
62 if (gGLManager.mHasNVFence)
63 {
64 return new LLAGPMemPoolNV(size);
65 }
66 else if (gGLManager.mHasATIVAO)
67 {
68 return new LLAGPMemPoolATI(size);
69 }
70 else
71#elif LL_DARWIN
72 if (gGLManager.mHasAPPLEFence && gGLManager.mHasAPPLEVertexArrayRange)
73 {
74 return new LLAGPMemPoolAPPLE(size);
75 }
76 else
77#endif
78 {
79 // No AGP memory allocation at all!
80 return NULL;
81 }
82}
83
84
85LLAGPMemBlock *LLAGPMemPool::allocBlock(const S32 size)
86{
87 S32 aligned_size = size;
88 if (size & 0x0f)
89 {
90 aligned_size += 16 - (size & 0x0f);
91 }
92
93 if (aligned_size > (mSize - mTotalAllocated))
94 {
95 // We're totally out of AGP memory, bail.
96 return NULL;
97 }
98
99 LLFreeBlock *free_block = mFreeList.getFirst();
100
101 while (free_block && free_block->mSize < aligned_size)
102 {
103 free_block = free_block->getNext();
104 }
105
106 U32 offset = 0;
107
108 if (free_block)
109 {
110 if (free_block->mSize == aligned_size)
111 {
112 free_block->unlink();
113 offset = free_block->mOffset;
114 delete free_block;
115 }
116 else
117 {
118 offset = free_block->mOffset + free_block->mSize - aligned_size;
119 free_block->mSize -= aligned_size;
120 if (0 == free_block->mSize)
121 {
122 free_block->unlink();
123 }
124 }
125 }
126 else
127 {
128 //llwarns << "LLAGPMemPool unable to allocate " << size << " bytes" << llendl;
129 return NULL;
130 }
131
132 mTotalAllocated += aligned_size;
133 return createBlock(offset, aligned_size);
134}
135
136
137void LLAGPMemPool::freeBlock(LLAGPMemBlock *blockp)
138{
139 if (!blockp->getSize())
140 {
141 return;
142 }
143
144 LLFreeBlock *prev_free = NULL;
145 LLFreeBlock *cur_free = mFreeList.getFirst();
146
147 while (cur_free && blockp->getOffset() > (U32)cur_free->mOffset)
148 {
149 prev_free = cur_free;
150 cur_free = cur_free->getNext();
151 }
152
153 LLFreeBlock *new_free = new LLFreeBlock(blockp->getOffset(), blockp->getSize());
154
155 if (prev_free)
156 {
157 prev_free->append(*new_free);
158 coalesce(new_free);
159 coalesce(prev_free);
160 }
161 else
162 {
163 mFreeList.append(*new_free);
164 coalesce(new_free);
165 }
166 mTotalAllocated -= blockp->getSize();
167}
168
169void LLAGPMemPool::coalesce(LLFreeBlock *free_block)
170{
171 LLFreeBlock *next = free_block->getNext();
172
173 if (next && (free_block->mOffset + free_block->mSize == next->mOffset))
174 {
175 free_block->mSize += next->mSize;
176
177 next->unlink();
178 delete next;
179
180 coalesce(free_block);
181 }
182}
183
184void LLAGPMemPool::printFreeList()
185{
186 LLFreeBlock *cur_block = mFreeList.getFirst();
187 while (cur_block)
188 {
189 llinfos << "Cur block begin: " << cur_block->mOffset << llendl;
190 llinfos << "Cur block end: " << cur_block->mOffset + cur_block->mSize << llendl;
191 cur_block = cur_block->getNext();
192 }
193}
194
diff --git a/linden/indra/llrender/llagpmempool.h b/linden/indra/llrender/llagpmempool.h
deleted file mode 100644
index f992876..0000000
--- a/linden/indra/llrender/llagpmempool.h
+++ /dev/null
@@ -1,121 +0,0 @@
1/**
2 * @file llagpmempool.h
3 * @brief LLAGPMemPool base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LLAGPMEMPOOL_H
29#define LL_LLAGPMEMPOOL_H
30
31#include "stdtypes.h"
32#include "lldlinked.h"
33
34// Raw memory handling abstraction, which handles interaction with
35// the nVidia and ATI AGP extensions.
36
37// Minimum size we allow allocation for, in order to allow AGP usage...
38const S32 MIN_AGP_SIZE = 8000000;
39
40class LLAGPMemBlock;
41
42class LLAGPMemPool
43{
44public:
45 LLAGPMemPool();
46 virtual ~LLAGPMemPool();
47
48 virtual LLAGPMemBlock *allocBlock(const S32 size);
49 virtual void freeBlock(LLAGPMemBlock *blockp);
50
51 virtual void flush() = 0;
52 virtual void dump() = 0;
53 virtual void enable() = 0;
54 virtual void disable() = 0;
55 virtual void bind() = 0;
56
57 virtual S32 getSize() { return mSize; }
58
59 S32 getTotalAllocated() const { return mTotalAllocated; }
60 static LLAGPMemPool *createPool(const U32 size, const BOOL use_vbo);
61
62 struct LLFreeBlock: public LLDLinked<LLFreeBlock>
63 {
64 S32 mOffset;
65 S32 mSize;
66 LLFreeBlock(const S32 offset, const S32 size) { mOffset = offset; mSize = size; sNumBlocks++; }
67 ~LLFreeBlock() { sNumBlocks--; }
68
69 static S32 sNumBlocks;
70 };
71
72 // Fencing (for nVidia and Apple) - default is to do nothing (ATI, ARB do not need fencing)
73 virtual U32 createFence() { return 0; }
74 virtual void deleteFence(const U32 fence) {}
75 virtual void sendFence(U32 fence) {}
76 virtual void waitFence(U32 fence) {}
77
78 void printFreeList();
79protected:
80
81 void coalesce(LLFreeBlock *free_block);
82 virtual LLAGPMemBlock *createBlock(const U32 offset, const U32 size) = 0;
83 LLDLinked<LLFreeBlock> mFreeList;
84
85 S32 mSize;
86 S32 mTotalAllocated;
87};
88
89// An AGP memory block, which contains all the info needed to
90// copy data in/out.
91class LLAGPMemBlock
92{
93public:
94 LLAGPMemBlock(LLAGPMemPool *mem_poolp) : mMemPoolp(mem_poolp) {}
95 virtual ~LLAGPMemBlock() {}
96 virtual void copy (void *source, const U32 size_bytes) = 0;
97 virtual void copyColor(void *source, const U32 size_bytes) = 0;
98
99 virtual void bindGLVertexPointer(const U32 stride, const U32 offset) = 0;
100 virtual void bindGLNormalPointer(const U32 stride, const U32 offset) = 0;
101 virtual void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset) = 0;
102 virtual void bindGLColorPointer(const U32 stride, const U32 offset) = 0;
103 virtual void bindGLTexCoordPointer(const U32 stride, const U32 offset) = 0;
104 virtual void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset) = 0;
105 virtual void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset) = 0;
106
107 virtual BOOL hasMappedMem() const = 0;
108 virtual U8* getMappedMem() = 0;
109
110 virtual U32 createFence() = 0;
111 virtual void deleteFence(const U32 fence) = 0;
112 virtual void sendFence(U32 fence) = 0;
113 virtual void waitFence(U32 fence) = 0;
114
115 virtual U32 getOffset() const = 0;
116 virtual U32 getSize() const = 0;
117protected:
118 LLAGPMemPool *mMemPoolp;
119};
120
121#endif // LL_LLAGPMEMPOOL_H
diff --git a/linden/indra/llrender/llagpmempoolapple.cpp b/linden/indra/llrender/llagpmempoolapple.cpp
deleted file mode 100644
index 9aa4993..0000000
--- a/linden/indra/llrender/llagpmempoolapple.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
1/**
2 * @file llagpmempoolapple.cpp
3 * @brief LLAGPMemPoolAPPLE base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifdef LL_DARWIN
29
30#include "linden_common.h"
31
32#include "llagpmempoolapple.h"
33#include "llgl.h"
34
35#include "llglheaders.h"
36
37LLAGPMemPoolAPPLE::LLAGPMemPoolAPPLE(S32 request) : LLAGPMemPool()
38{
39 llinfos << "Creating LLAGPMemPoolAPPLE" << llendl;
40 stop_glerror();
41 if (!gGLManager.mHasAPPLEFence || !gGLManager.mHasAPPLEVertexArrayRange)
42 {
43 llerrs << "necessary extensions not present!" << llendl;
44 }
45
46 // No special allocation is necessary for the Apple extensions
47 mBase = (U8*)::malloc(request);
48 mSize = request;
49
50 if (mBase)
51 {
52 mFreeList.append(*(new LLFreeBlock(0,mSize)));
53 }
54 else
55 {
56 mSize = 0;
57 }
58
59 flush_glerror();
60}
61
62LLAGPMemBlockAPPLE::~LLAGPMemBlockAPPLE()
63{
64 mMemPoolp->freeBlock(this);
65}
66
67LLAGPMemBlock *LLAGPMemPoolAPPLE::createBlock(const U32 offset, const U32 size)
68{
69 return new LLAGPMemBlockAPPLE(this, mBase, offset, size);
70}
71
72LLAGPMemPoolAPPLE::~LLAGPMemPoolAPPLE()
73{
74 if (mBase)
75 {
76 // MBW -- This really belongs in a call which is the opposite of bind()...
77 glVertexArrayRangeAPPLE(0, 0);
78 ::free(mBase);
79 }
80}
81
82void LLAGPMemPoolAPPLE::bind()
83{
84 if(mBase)
85 {
86 glVertexArrayRangeAPPLE(mSize, mBase);
87 }
88}
89
90void LLAGPMemPoolAPPLE::enable()
91{
92 glEnableClientState(GL_VERTEX_ARRAY_RANGE_APPLE);
93}
94
95void LLAGPMemPoolAPPLE::disable()
96{
97 glDisableClientState(GL_VERTEX_ARRAY_RANGE_APPLE);
98}
99
100void LLAGPMemPoolAPPLE::flush()
101{
102 if(mBase)
103 {
104 glFlushVertexArrayRangeAPPLE(mSize, mBase);
105 }
106}
107
108void LLAGPMemPoolAPPLE::dump()
109{
110 LLFreeBlock *prev = 0;
111 LLFreeBlock *block = mFreeList.getFirst();
112
113 int d=0;
114
115 int i=0;
116 while (block)
117 {
118 i++;
119 if (prev)
120 {
121 d = (S32)block->mOffset - ((S32)prev->mOffset + prev->mSize);
122 }
123 else d = 0;
124
125 prev = block;
126 block = block->getNext();
127 }
128}
129
130
131U32 LLAGPMemPoolAPPLE::createFence()
132{
133 U32 fence;
134 glGenFencesAPPLE(1, (GLuint*)&fence);
135 glSetFenceAPPLE(fence);
136 glFinishFenceAPPLE(fence);
137 return fence;
138}
139
140
141void LLAGPMemPoolAPPLE::deleteFence(const U32 fence)
142{
143 glDeleteFencesAPPLE(1, (GLuint*)&fence);
144}
145
146
147void LLAGPMemPoolAPPLE::sendFence(U32 fence)
148{
149 glSetFenceAPPLE(fence);
150}
151
152
153void LLAGPMemPoolAPPLE::waitFence(U32 fence)
154{
155 if(!glTestFenceAPPLE(fence))
156 {
157 glFinishFenceAPPLE(fence);
158 }
159}
160
161
162/////////////////////////////
163//
164// LLAGPMemBlockAPPLE
165//
166// APPLE Implementation of an AGP memory block
167//
168
169LLAGPMemBlockAPPLE::LLAGPMemBlockAPPLE(LLAGPMemPool *mem_poolp, U8 *baseptr, S32 offset, const U32 size) : LLAGPMemBlock(mem_poolp)
170{
171 mMemp = baseptr + offset;
172 mOffset = offset;
173 mSize = size;
174}
175
176
177void LLAGPMemBlockAPPLE::bindGLVertexPointer(const U32 stride, const U32 offset)
178{
179 if (!mMemp)
180 {
181 llerrs << "Binding empty vertex array" << llendl;
182 }
183 glVertexPointer(3, GL_FLOAT, stride, mMemp + offset);
184}
185
186void LLAGPMemBlockAPPLE::bindGLNormalPointer(const U32 stride, const U32 offset)
187{
188 if (!mMemp)
189 {
190 llerrs << "Binding empty normal array" << llendl;
191 }
192 glNormalPointer(GL_FLOAT, stride, mMemp + offset);
193}
194
195
196void LLAGPMemBlockAPPLE::bindGLColorPointer(const U32 stride, const U32 offset)
197{
198 if (!mMemp)
199 {
200 llerrs << "Binding empty color array" << llendl;
201 }
202 glColorPointer(4, GL_UNSIGNED_BYTE, stride, mMemp + offset);
203}
204
205
206void LLAGPMemBlockAPPLE::bindGLTexCoordPointer(const U32 stride, const U32 offset)
207{
208 if (!mMemp)
209 {
210 llerrs << "Binding empty texcoord array" << llendl;
211 }
212 glTexCoordPointer(2, GL_FLOAT, stride, mMemp + offset);
213}
214
215
216void LLAGPMemBlockAPPLE::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset)
217{
218 if (!mMemp)
219 {
220 llerrs << "Binding empty vertex weight array" << llendl;
221 }
222
223 if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, (F32 *)(mMemp + offset));
224}
225
226void LLAGPMemBlockAPPLE::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset)
227{
228 if (!mMemp)
229 {
230 llerrs << "Binding empty vertex weight array" << llendl;
231 }
232
233 if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, 0, (F32 *)(mMemp + offset));
234}
235
236void LLAGPMemBlockAPPLE::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset)
237{
238 if (!mMemp)
239 {
240 llerrs << "Binding empty vertex weight array" << llendl;
241 }
242 set_vertex_clothing_weights(index, stride, (LLVector4 *)(mMemp + offset));
243}
244
245U8* LLAGPMemBlockAPPLE::getMappedMem()
246{
247 return mMemp;
248}
249
250
251void LLAGPMemBlockAPPLE::copy(void *mem, const U32 size)
252{
253 if (!mMemp || !mem)
254 {
255 return;
256 }
257 llassert(size <= mSize);
258
259 memcpy( mMemp, mem, size );
260
261 glFlushVertexArrayRangeAPPLE(size, mMemp);
262}
263
264void LLAGPMemBlockAPPLE::copyColor(void *mem, const U32 size)
265{
266 if (!mMemp || !mem)
267 {
268 return;
269 }
270 llassert(size <= mSize);
271
272 memcpy( mMemp, mem, size );
273
274 glFlushVertexArrayRangeAPPLE(size, mMemp);
275}
276
277
278
279U32 LLAGPMemBlockAPPLE::createFence()
280{
281 U32 fence;
282 glGenFencesAPPLE(1, (GLuint*)&fence);
283 glSetFenceAPPLE(fence);
284 glFinishFenceAPPLE(fence);
285 return fence;
286}
287
288void LLAGPMemBlockAPPLE::deleteFence(const U32 fence)
289{
290 glDeleteFencesAPPLE(1, (GLuint*)&fence);
291}
292
293void LLAGPMemBlockAPPLE::sendFence(U32 fence)
294{
295 glSetFenceAPPLE(fence);
296}
297
298void LLAGPMemBlockAPPLE::waitFence(U32 fence)
299{
300 if(!glTestFenceAPPLE(fence))
301 {
302 glFinishFenceAPPLE(fence);
303 }
304}
305
306// MBW -- May want this at some point...
307#if 0
308void LLAGPMemBlockAPPLE::flush()
309{
310 glFlushVertexArrayRangeAPPLE(mSize, mMemp);
311}
312#endif
313
314#endif // LL_DARWIN
diff --git a/linden/indra/llrender/llagpmempoolapple.h b/linden/indra/llrender/llagpmempoolapple.h
deleted file mode 100644
index 4a72a28..0000000
--- a/linden/indra/llrender/llagpmempoolapple.h
+++ /dev/null
@@ -1,95 +0,0 @@
1/**
2 * @file llagpmempoolapple.h
3 * @brief LLAGPMemPoolAPPLE base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LLAGPMEMPOOLAPPLE_H
29#define LL_LLAGPMEMPOOLAPPLE_H
30
31#include "llagpmempool.h"
32
33#if LL_DARWIN
34class LLAGPMemPoolAPPLE : public LLAGPMemPool
35{
36public:
37 LLAGPMemPoolAPPLE(S32 request);
38 virtual ~LLAGPMemPoolAPPLE();
39
40 /*virtual*/ void flush();
41 /*virtual*/ void dump();
42 /*virtual*/ void enable();
43 /*virtual*/ void disable();
44 /*virtual*/ void bind();
45
46 /*virtual*/ U32 createFence();
47 /*virtual*/ void deleteFence(const U32 fence);
48 /*virtual*/ void sendFence(U32 fence);
49 /*virtual*/ void waitFence(U32 fence);
50
51protected:
52 /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size);
53
54protected:
55 U8 *mBase;
56};
57
58class LLAGPMemBlockAPPLE : public LLAGPMemBlock
59{
60public:
61 LLAGPMemBlockAPPLE(LLAGPMemPool *mem_poolp, U8 *baseptr, const S32 offset, const U32 size);
62 virtual ~LLAGPMemBlockAPPLE();
63
64 /*virtual*/ void copy (void *source, const U32 size_bytes);
65 /*virtual*/ void copyColor(void *source, const U32 size_bytes);
66 /*virtual*/ void free();
67
68 /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset);
69 /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset);
70 /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset);
71 /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset);
72 /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset);
73 /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset);
74 /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset);
75
76 /*virtual*/ U32 getOffset() const { return mOffset; }
77 /*virtual*/ U32 getSize() const { return mSize; }
78
79 /*virtual*/ BOOL hasMappedMem() const { return TRUE; }
80 /*virtual*/ U8* getMappedMem();
81 /*virtual*/ U32 createFence();
82 /*virtual*/ void deleteFence(const U32 fence);
83 /*virtual*/ void sendFence(U32 fence);
84 /*virtual*/ void waitFence(U32 fence);
85
86private:
87 U8 *mMemp;
88 U32 mOffset; // Offset from base
89 U32 mSize;
90 friend class LLAGPMemPoolAPPLE;
91};
92
93#endif // LL_DARWIN
94
95#endif // LL_LLAGPMEMPOOLAPPLE_H
diff --git a/linden/indra/llrender/llagpmempoolarb.cpp b/linden/indra/llrender/llagpmempoolarb.cpp
deleted file mode 100644
index ab97c97..0000000
--- a/linden/indra/llrender/llagpmempoolarb.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
1/**
2 * @file llagpmempoolarb.cpp
3 * @brief LLAGPMemPoolARB base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29#include "llagpmempoolarb.h"
30#include "llgl.h"
31
32#include "llglheaders.h"
33
34LLAGPMemPoolARB::LLAGPMemPoolARB(S32 request) : LLAGPMemPool()
35{
36 llinfos << "Creating LLAGPMemPoolARB" << llendl;
37 stop_glerror();
38 if (!gGLManager.mHasVertexBufferObject)
39 {
40 llerrs << "No ARB vertex buffer object extension!" << llendl;
41 }
42
43 mName = 0;
44
45 mSize = request;
46 flush_glerror();
47}
48
49
50LLAGPMemPoolARB::~LLAGPMemPoolARB()
51{
52}
53
54
55LLAGPMemBlock* LLAGPMemPoolARB::allocBlock(const S32 size)
56{
57 return allocBlock(size, GL_ARRAY_BUFFER_ARB);
58}
59
60LLAGPMemBlock *LLAGPMemPoolARB::allocBlock(const S32 size, U32 target)
61{
62 S32 aligned_size = size;
63 if (size & 0x0f)
64 {
65 aligned_size += 16 - (size & 0x0f);
66 }
67
68 if (aligned_size > (mSize - mTotalAllocated))
69 {
70 // We're totally out of AGP memory, bail.
71 return (LLAGPMemBlock *)0;
72 }
73
74 mTotalAllocated += aligned_size;
75 return createBlock(0, aligned_size, target);
76}
77
78
79void LLAGPMemPoolARB::freeBlock(LLAGPMemBlock *blockp)
80{
81 if (!blockp->getSize())
82 {
83 return;
84 }
85 LLAGPMemBlockARB *arb_blockp = (LLAGPMemBlockARB*)blockp;
86 U32 name[1];
87 name[0] = arb_blockp->getName();
88 stop_glerror();
89 glDeleteBuffersARB(1, (GLuint*)name);
90 stop_glerror();
91 mTotalAllocated -= blockp->getSize();
92}
93
94LLAGPMemBlock *LLAGPMemPoolARB::createBlock(const U32 offset, const U32 size)
95{
96 return createBlock(offset, size, GL_ARRAY_BUFFER_ARB);
97}
98
99LLAGPMemBlock *LLAGPMemPoolARB::createBlock(const U32 offset, const U32 size, const U32 target)
100{
101 U32 name[1];
102 stop_glerror();
103 glGenBuffersARB(1, (GLuint*)name);
104 stop_glerror();
105 return new LLAGPMemBlockARB(this, name[0], offset, size, target);
106}
107
108void LLAGPMemPoolARB::disable()
109{
110}
111
112void LLAGPMemPoolARB::dump()
113{
114}
115
116
117/////////////////////////////
118//
119// LLAGPMemBlockARB
120//
121// ARB ImplementARBon of an AGP memory block
122//
123
124LLAGPMemBlockARB::LLAGPMemBlockARB(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size, U32 target) :
125 LLAGPMemBlock(mem_poolp), mTarget(target)
126{
127 llassert(name > 0);
128 mName = name;
129 stop_glerror();
130 glBindBufferARB(mTarget, mName);
131 stop_glerror();
132
133 glBufferDataARB(mTarget, size, NULL, GL_DYNAMIC_DRAW_ARB);
134
135 stop_glerror();
136 glBindBufferARB(mTarget, 0);
137 stop_glerror();
138 mSize = size;
139}
140
141
142void LLAGPMemBlockARB::bindGLVertexPointer(const U32 stride, const U32 offset)
143{
144 stop_glerror();
145 glBindBufferARB(mTarget, mName);
146 glVertexPointer(3, GL_FLOAT, stride, (GLvoid*)((intptr_t)offset));
147 glBindBufferARB(mTarget, 0);
148}
149
150
151void LLAGPMemBlockARB::bindGLNormalPointer(const U32 stride, const U32 offset)
152{
153 stop_glerror();
154 glBindBufferARB(mTarget, mName);
155 glNormalPointer(GL_FLOAT, stride, (GLvoid*)((intptr_t)offset));
156 glBindBufferARB(mTarget, 0);
157 stop_glerror();
158}
159
160
161void LLAGPMemBlockARB::bindGLColorPointer(const U32 stride, const U32 offset)
162{
163 stop_glerror();
164 glBindBufferARB(mTarget, mName);
165 glColorPointer(4, GL_UNSIGNED_BYTE, stride, (GLvoid*)((intptr_t)offset));
166 glBindBufferARB(mTarget, 0);
167 stop_glerror();
168}
169
170
171void LLAGPMemBlockARB::bindGLTexCoordPointer(const U32 stride, const U32 offset)
172{
173 stop_glerror();
174 glBindBufferARB(mTarget, mName);
175 glTexCoordPointer(2, GL_FLOAT, stride, (GLvoid*)((intptr_t)offset));
176 glBindBufferARB(mTarget, 0);
177 stop_glerror();
178}
179
180
181void LLAGPMemBlockARB::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset)
182{
183 stop_glerror();
184 glBindBufferARB(mTarget, mName);
185 set_vertex_weights(index, (F32*)(intptr_t)offset);
186 glBindBufferARB(mTarget, 0);
187 stop_glerror();
188}
189
190void LLAGPMemBlockARB::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset)
191{
192 stop_glerror();
193 glBindBufferARB(mTarget, mName);
194 set_binormals(index, stride, (LLVector3*)(intptr_t)offset);
195 glBindBufferARB(mTarget, 0);
196 stop_glerror();
197}
198
199
200void LLAGPMemBlockARB::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset)
201{
202 return;
203}
204
205
206void LLAGPMemBlockARB::copy(void *mem, const U32 size)
207{
208 stop_glerror();
209 llassert(size <= mSize);
210 glBindBufferARB(mTarget, mName);
211 glBufferSubDataARB(mTarget, 0, size, mem);
212 glBindBufferARB(mTarget, 0);
213 stop_glerror();
214}
215
216void LLAGPMemBlockARB::copyColor(void *mem, const U32 size)
217{
218 stop_glerror();
219 llassert(size <= mSize);
220 glBindBufferARB(mTarget, mName);
221 glBufferSubDataARB(mTarget, 0, size, mem);
222 glBindBufferARB(mTarget, 0);
223 stop_glerror();
224}
225
226
227U8* LLAGPMemBlockARB::getMappedMem()
228{
229 return NULL;
230}
diff --git a/linden/indra/llrender/llagpmempoolarb.h b/linden/indra/llrender/llagpmempoolarb.h
deleted file mode 100644
index 7358862..0000000
--- a/linden/indra/llrender/llagpmempoolarb.h
+++ /dev/null
@@ -1,103 +0,0 @@
1/**
2 * @file llagpmempoolarb.h
3 * @brief LLAGPMemPoolARB base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LLAGPMEMPOOLARB_H
29#define LL_LLAGPMEMPOOLARB_H
30
31#include "llagpmempool.h"
32
33class LLAGPMemPoolARB : public LLAGPMemPool
34{
35public:
36 LLAGPMemPoolARB(S32 request);
37 virtual ~LLAGPMemPoolARB();
38
39 /*virtual*/ LLAGPMemBlock* allocBlock(const S32 size);
40 LLAGPMemBlock *allocBlock(const S32 size, U32 target);
41 /*virtual*/ void freeBlock(LLAGPMemBlock *blockp);
42
43 void bind() {}
44
45 void enable() {}
46
47 /*virtual*/ void disable();
48
49 void flush() {}
50
51 // No point in these being inline, is there? They're virtual functions anyway...
52 /*virtual*/ inline LLAGPMemBlock *alloc(S32 size);
53 /*virtual*/ inline void free(LLAGPMemBlock *block);
54 /*virtual*/ inline void dump();
55protected:
56 /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size);
57 LLAGPMemBlock *createBlock(const U32 offset, const U32 size, const U32 target);
58
59protected:
60 U32 mName;
61};
62
63class LLAGPMemBlockARB : public LLAGPMemBlock
64{
65public:
66 LLAGPMemBlockARB(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size, U32 target);
67 virtual ~LLAGPMemBlockARB() { mMemPoolp->freeBlock(this); };
68
69 /*virtual*/ void copy (void *source, const U32 size_bytes);
70 /*virtual*/ void copyColor(void *source, const U32 size_bytes);
71 /*virtual*/ void free();
72
73 /*virtual*/ void bind();
74 /*virtual*/ void unbind();
75
76 /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset);
77 /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset);
78 /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset);
79 /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset);
80 /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset);
81 /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset);
82 /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset);
83
84 /*virtual*/ U32 getOffset() const { return 0; }
85 /*virtual*/ U32 getSize() const { return mSize; }
86
87 /*virtual*/ BOOL hasMappedMem() const { return FALSE; }
88 /*virtual*/ U8* getMappedMem();
89 /*virtual*/ U32 createFence() { return 0; }
90 /*virtual*/ void deleteFence(const U32 fence) {}
91 /*virtual*/ void sendFence(U32 fence) { }
92 /*virtual*/ void waitFence(U32 fence) { }
93
94 U32 getName() const { return mName; }
95private:
96 U32 mName;
97 U32 mSize;
98 U32 mTarget;
99
100 friend class LLAGPMemPoolARB;
101};
102
103#endif // LL_LLAGPMEMPOOLARB_H
diff --git a/linden/indra/llrender/llagpmempoolati.cpp b/linden/indra/llrender/llagpmempoolati.cpp
deleted file mode 100644
index f29db95..0000000
--- a/linden/indra/llrender/llagpmempoolati.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
1/**
2 * @file llagpmempoolati.cpp
3 * @brief LLAGPMemPoolATI base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#include "llagpmempoolati.h"
31#include "llgl.h"
32
33#include "llglheaders.h"
34
35LLAGPMemPoolATI::LLAGPMemPoolATI(S32 request) : LLAGPMemPool()
36{
37 llinfos << "Creating LLAGPMemPoolATI" << llendl;
38 stop_glerror();
39 if (!gGLManager.mHasATIVAO)
40 {
41 llerrs << "No ATI AGI memory extension!" << llendl;
42 }
43
44 mName = 0;
45
46 // More than 4MB of agp available
47 while (!mName && (request > 0))
48 {
49 mName = glNewObjectBufferATI(request, NULL, GL_DYNAMIC_ATI);
50 mSize = request;
51 request >>= 1;
52 }
53
54 if (mName)
55 {
56 mFreeList.append(*(new LLFreeBlock(0, mSize)));
57 }
58 else
59 {
60 llinfos << "Unable to allocate AGP memory!" << llendl;
61 mSize = 0;
62 }
63 flush_glerror();
64}
65
66
67LLAGPMemPoolATI::~LLAGPMemPoolATI()
68{
69 if (mName)
70 {
71 glFreeObjectBufferATI(mName);
72 }
73}
74
75
76LLAGPMemBlock *LLAGPMemPoolATI::createBlock(const U32 offset, const U32 size)
77{
78 return new LLAGPMemBlockATI(this, mName, offset, size);
79}
80
81
82void LLAGPMemPoolATI::dump()
83{
84}
85
86
87/////////////////////////////
88//
89// LLAGPMemBlockATI
90//
91// ATI Implementation of an AGP memory block
92//
93
94LLAGPMemBlockATI::LLAGPMemBlockATI(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size) :
95 LLAGPMemBlock(mem_poolp)
96{
97 mName = name;
98 mOffset = offset;
99 mSize = size;
100}
101
102
103void LLAGPMemBlockATI::bindGLVertexPointer(const U32 stride, const U32 offset)
104{
105 glArrayObjectATI(GL_VERTEX_ARRAY, 3, GL_FLOAT, stride, mName, mOffset + offset);
106}
107
108
109void LLAGPMemBlockATI::bindGLNormalPointer(const U32 stride, const U32 offset)
110{
111 glArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, stride, mName, mOffset + offset);
112}
113
114
115void LLAGPMemBlockATI::bindGLColorPointer(const U32 stride, const U32 offset)
116{
117 glArrayObjectATI(GL_COLOR_ARRAY, 4, GL_UNSIGNED_BYTE, stride, mName, mOffset + offset);
118}
119
120
121void LLAGPMemBlockATI::bindGLTexCoordPointer(const U32 stride, const U32 offset)
122{
123 glArrayObjectATI(GL_TEXTURE_COORD_ARRAY, 2, GL_FLOAT, stride, mName, mOffset + offset);
124}
125
126
127void LLAGPMemBlockATI::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset)
128{
129 glVertexAttribArrayObjectATI(index, 3, GL_FLOAT, FALSE, stride, mName, mOffset + offset);
130}
131
132
133void LLAGPMemBlockATI::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset)
134{
135 //glArrayObjectATI(GL_WEIGHT_ARRAY_ARB, 1, GL_FLOAT, stride, mName, mOffset + offset);
136 glVertexAttribArrayObjectATI(index, 1, GL_FLOAT, FALSE, stride, mName, mOffset + offset);
137}
138
139void LLAGPMemBlockATI::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset)
140{
141 glVertexAttribArrayObjectATI(index, 4, GL_FLOAT, FALSE, stride, mName, mOffset + offset);
142}
143
144U8* LLAGPMemBlockATI::getMappedMem()
145{
146 return NULL;
147}
148
149void LLAGPMemBlockATI::copy(void *mem, const U32 size)
150{
151 llassert(size <= mSize);
152 glUpdateObjectBufferATI(mName, mOffset, size, mem, GL_PRESERVE_ATI);
153}
154
155void LLAGPMemBlockATI::copyColor(void *mem, const U32 size)
156{
157 llassert(size <= mSize);
158 glUpdateObjectBufferATI(mName, mOffset, size, mem, GL_PRESERVE_ATI);
159}
160
diff --git a/linden/indra/llrender/llagpmempoolati.h b/linden/indra/llrender/llagpmempoolati.h
deleted file mode 100644
index 67803f6..0000000
--- a/linden/indra/llrender/llagpmempoolati.h
+++ /dev/null
@@ -1,92 +0,0 @@
1/**
2 * @file llagpmempoolati.h
3 * @brief LLAGPMemPoolATI base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LLAGPMEMPOOLATI_H
29#define LL_LLAGPMEMPOOLATI_H
30
31#include "llagpmempool.h"
32
33class LLAGPMemPoolATI : public LLAGPMemPool
34{
35public:
36 LLAGPMemPoolATI(S32 request);
37 virtual ~LLAGPMemPoolATI();
38
39 void bind() {}
40
41 void enable() {}
42
43 void disable() {}
44
45 void flush() {}
46
47 // No point in these being inline, is there? They're virtual functions anyway...
48 /*virtual*/ inline LLAGPMemBlock *alloc(S32 size);
49 /*virtual*/ inline void free(LLAGPMemBlock *block);
50 /*virtual*/ inline void dump();
51protected:
52 /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size);
53
54protected:
55 U32 mName;
56};
57
58class LLAGPMemBlockATI : public LLAGPMemBlock
59{
60public:
61 LLAGPMemBlockATI(LLAGPMemPool *mem_poolp, const U32 name, const U32 offset, const U32 size);
62 virtual ~LLAGPMemBlockATI() { mMemPoolp->freeBlock(this); };
63
64 /*virtual*/ void copy (void *source, const U32 size_bytes);
65 /*virtual*/ void copyColor(void *source, const U32 size_bytes);
66 /*virtual*/ void free();
67 /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset);
68 /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset);
69 /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride,const U32 offset);
70 /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset);
71 /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset);
72 /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset);
73 /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset);
74
75 /*virtual*/ U32 getOffset() const { return mOffset; }
76 /*virtual*/ U32 getSize() const { return mSize; }
77
78 /*virtual*/ BOOL hasMappedMem() const { return TRUE; }
79 /*virtual*/ U8* getMappedMem();
80 /*virtual*/ U32 createFence() { return 0; }
81 /*virtual*/ void deleteFence(const U32 fence) {}
82 /*virtual*/ void sendFence(U32 fence) { }
83 /*virtual*/ void waitFence(U32 fence) { }
84private:
85 U32 mName;
86 U32 mOffset;
87 U32 mSize;
88
89 friend class LLAGPMemPoolATI;
90};
91
92#endif // LL_LLAGPMEMPOOLATI_H
diff --git a/linden/indra/llrender/llagpmempoolnv.cpp b/linden/indra/llrender/llagpmempoolnv.cpp
deleted file mode 100644
index 8bbaef9..0000000
--- a/linden/indra/llrender/llagpmempoolnv.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
1/**
2 * @file llagpmempoolnv.cpp
3 * @brief LLAGPMemPoolNV base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "linden_common.h"
29
30#ifndef LL_LINUX
31
32#include "llagpmempoolnv.h"
33#include "llgl.h"
34
35#include "llglheaders.h"
36
37#if LL_WINDOWS
38//#define LL_USE_NEW_MEM_OPS 1
39#endif
40#if LL_USE_NEW_MEM_OPS
41#include "new_mem_ops.h"
42#endif
43
44BOOL LLAGPMemPoolNV::sWriteOK = TRUE;
45
46LLAGPMemPoolNV::LLAGPMemPoolNV(int request) : LLAGPMemPool()
47{
48 llinfos << "Creating LLAGPMemPoolNV" << llendl;
49 stop_glerror();
50 if (!gGLManager.mHasNVFence)
51 {
52 llerrs << "wglAllocateMemoryNV not defined!" << llendl;
53 }
54
55 mBase = 0;
56
57 if (!mBase)
58 {
59 // More than 4MB of AGP available
60 while (!mBase && (request > 0))
61 {
62 // Stupid arbitrary nVidia magic numbers.
63 // read freq, write freq, priority
64 // AGP: 0.0, 0.1, 0.5
65 // Video: 0.0, 0.1, 1.0
66 mBase = (U8*)wglAllocateMemoryNV(request, 0.0f, 0.1f, 0.5f);
67 mSize = request;
68 request >>= 1;
69 }
70 }
71
72 if (mBase)
73 {
74 mFreeList.append(*(new LLFreeBlock(0,mSize)));
75 }
76 else
77 {
78 mSize = 0;
79 }
80
81 sWriteOK = TRUE;
82 flush_glerror();
83}
84
85
86LLAGPMemBlock *LLAGPMemPoolNV::createBlock(const U32 offset, const U32 size)
87{
88 return new LLAGPMemBlockNV(this, mBase, offset, size);
89}
90
91LLAGPMemPoolNV::~LLAGPMemPoolNV()
92{
93 if (mBase)
94 {
95 wglFreeMemoryNV(mBase);
96 }
97}
98
99void LLAGPMemPoolNV::bind()
100{
101 glVertexArrayRangeNV(mSize, mBase);
102}
103
104void LLAGPMemPoolNV::enable()
105{
106 glEnableClientState(GL_VERTEX_ARRAY_RANGE_NV);
107 sWriteOK = FALSE;
108}
109
110void LLAGPMemPoolNV::disable()
111{
112 glDisableClientState(GL_VERTEX_ARRAY_RANGE_NV);
113 sWriteOK = TRUE;
114}
115
116void LLAGPMemPoolNV::flush()
117{
118 glFlushVertexArrayRangeNV();
119}
120
121U32 LLAGPMemPoolNV::createFence()
122{
123 U32 fence;
124 glGenFencesNV(1, &fence);
125 glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
126 glFinishFenceNV(fence);
127 return fence;
128}
129
130void LLAGPMemPoolNV::deleteFence(const U32 fence)
131{
132 glDeleteFencesNV(1, &fence);
133}
134
135void LLAGPMemPoolNV::sendFence(U32 fence)
136{
137 glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
138}
139
140void LLAGPMemPoolNV::waitFence(U32 fence)
141{
142 if(!glTestFenceNV(fence))
143 {
144 glFinishFenceNV(fence);
145 }
146}
147
148
149//static
150BOOL LLAGPMemPoolNV::isWriteOK()
151{
152 return sWriteOK;
153}
154
155void LLAGPMemPoolNV::dump()
156{
157 LLFreeBlock *prev = 0;
158 LLFreeBlock *block = mFreeList.getFirst();
159
160 int d=0;
161
162 int i=0;
163 while (block)
164 {
165 i++;
166 if (prev)
167 {
168 d = (S32)block->mOffset - ((S32)prev->mOffset + prev->mSize);
169 }
170 else d = 0;
171
172 prev = block;
173 block = block->getNext();
174 }
175}
176
177
178LLAGPMemBlockNV::LLAGPMemBlockNV(LLAGPMemPool *mem_poolp, U8 *baseptr, S32 offset, const U32 size) : LLAGPMemBlock(mem_poolp)
179{
180 mMemp = baseptr + offset;
181 mOffset = offset;
182 mSize = size;
183}
184
185extern U8* gAGPVertices;
186
187void LLAGPMemBlockNV::bindGLVertexPointer(const U32 stride, const U32 offset)
188{
189 if (!mMemp)
190 {
191 llerrs << "Binding empty vertex array" << llendl;
192 }
193 glVertexPointer(3, GL_FLOAT, stride, mMemp + offset);
194}
195
196void LLAGPMemBlockNV::bindGLNormalPointer(const U32 stride, const U32 offset)
197{
198 if (!mMemp)
199 {
200 llerrs << "Binding empty normal array" << llendl;
201 }
202 glNormalPointer(GL_FLOAT, stride, mMemp + offset);
203}
204
205
206void LLAGPMemBlockNV::bindGLColorPointer(const U32 stride, const U32 offset)
207{
208 if (!mMemp)
209 {
210 llerrs << "Binding empty color array" << llendl;
211 }
212 glColorPointer(4, GL_UNSIGNED_BYTE, stride, mMemp + offset);
213}
214
215
216void LLAGPMemBlockNV::bindGLTexCoordPointer(const U32 stride, const U32 offset)
217{
218 if (!mMemp)
219 {
220 llerrs << "Binding empty texcoord array" << llendl;
221 }
222 glTexCoordPointer(2, GL_FLOAT, stride, mMemp + offset);
223}
224
225
226void LLAGPMemBlockNV::bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset)
227{
228 if (!mMemp)
229 {
230 llerrs << "Binding empty vertex weight array" << llendl;
231 }
232
233 glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, (F32 *)(mMemp + offset));
234}
235
236void LLAGPMemBlockNV::bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset)
237{
238 if (!mMemp)
239 {
240 llerrs << "Binding empty vertex weight array" << llendl;
241 }
242
243 glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, 0, (F32 *)(mMemp + offset));
244}
245
246void LLAGPMemBlockNV::bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset)
247{
248 if (!mMemp)
249 {
250 llerrs << "Binding empty vertex weight array" << llendl;
251 }
252 set_vertex_clothing_weights(index, stride, (LLVector4 *)(mMemp + offset));
253}
254
255U8* LLAGPMemBlockNV::getMappedMem()
256{
257 return mMemp;
258}
259
260void LLAGPMemBlockNV::copy(void *mem, const U32 size)
261{
262 if (!mMemp || !mem)
263 {
264 return;
265 }
266 llassert(LLAGPMemPoolNV::isWriteOK());
267 llassert(size <= mSize);
268
269#if LL_USE_NEW_MEM_OPS
270 inline_new_memcpy( mMemp, mem, size );
271#else
272 memcpy( mMemp, mem, size );
273#endif
274}
275
276void LLAGPMemBlockNV::copyColor(void *mem, const U32 size)
277{
278 if (!mMemp || !mem)
279 {
280 return;
281 }
282 llassert(LLAGPMemPoolNV::isWriteOK());
283 llassert(size <= mSize);
284
285#if LL_USE_NEW_MEM_OPS
286 inline_new_memcpy( mMemp, mem, size );
287#else
288 memcpy( mMemp, mem, size );
289#endif
290}
291
292
293U32 LLAGPMemBlockNV::createFence()
294{
295 U32 fence;
296 glGenFencesNV(1, &fence);
297 glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
298 glFinishFenceNV(fence);
299 return fence;
300}
301
302void LLAGPMemBlockNV::deleteFence(const U32 fence)
303{
304 glDeleteFencesNV(1, &fence);
305}
306
307void LLAGPMemBlockNV::sendFence(U32 fence)
308{
309 glSetFenceNV(fence, GL_ALL_COMPLETED_NV);
310}
311
312void LLAGPMemBlockNV::waitFence(U32 fence)
313{
314 if(!glTestFenceNV(fence))
315 {
316 glFinishFenceNV(fence);
317 }
318}
319
320#endif //LL_LINUX
diff --git a/linden/indra/llrender/llagpmempoolnv.h b/linden/indra/llrender/llagpmempoolnv.h
deleted file mode 100644
index cffe397..0000000
--- a/linden/indra/llrender/llagpmempoolnv.h
+++ /dev/null
@@ -1,95 +0,0 @@
1/**
2 * @file llagpmempoolnv.h
3 * @brief LLAGPMemPoolNV base class
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LLAGPMEMPOOLNV_H
29#define LL_LLAGPMEMPOOLNV_H
30
31#include "llagpmempool.h"
32
33class LLAGPMemPoolNV : public LLAGPMemPool
34{
35public:
36 LLAGPMemPoolNV(int request);
37 virtual ~LLAGPMemPoolNV();
38
39 /*virtual*/ void flush();
40 /*virtual*/ void dump();
41 /*virtual*/ void enable();
42 /*virtual*/ void disable();
43 /*virtual*/ void bind();
44
45 static BOOL isWriteOK();
46
47 /*virtual*/ U32 createFence();
48 /*virtual*/ void deleteFence(const U32 fence);
49 /*virtual*/ void sendFence(U32 fence);
50 /*virtual*/ void waitFence(U32 fence);
51protected:
52 /*virtual*/ LLAGPMemBlock *createBlock(const U32 offset, const U32 size);
53
54protected:
55 U8 *mBase;
56
57 static BOOL sWriteOK;
58};
59
60class LLAGPMemBlockNV : public LLAGPMemBlock
61{
62public:
63 LLAGPMemBlockNV(LLAGPMemPool *mem_poolp, U8 *baseptr, const S32 offset, const U32 size);
64 virtual ~LLAGPMemBlockNV() { mMemPoolp->freeBlock(this); };
65
66 /*virtual*/ void copy (void *source, const U32 size_bytes);
67 /*virtual*/ void copyColor(void *source, const U32 size_bytes);
68 /*virtual*/ void free();
69
70 /*virtual*/ void bindGLVertexPointer(const U32 stride, const U32 offset);
71 /*virtual*/ void bindGLNormalPointer(const U32 stride, const U32 offset);
72 /*virtual*/ void bindGLBinormalPointer(const S32 index, const U32 stride, const U32 offset);
73 /*virtual*/ void bindGLColorPointer(const U32 stride, const U32 offset);
74 /*virtual*/ void bindGLTexCoordPointer(const U32 stride, const U32 offset);
75 /*virtual*/ void bindGLVertexWeightPointer(const S32 index, const U32 stride, const U32 offset);
76 /*virtual*/ void bindGLVertexClothingWeightPointer(const S32 index, const U32 stride, const U32 offset);
77
78 /*virtual*/ U32 getOffset() const { return mOffset; }
79 /*virtual*/ U32 getSize() const { return mSize; }
80
81 /*virtual*/ BOOL hasMappedMem() const { return TRUE; }
82 /*virtual*/ U8* getMappedMem();
83 /*virtual*/ U32 createFence();
84 /*virtual*/ void deleteFence(const U32 fence);
85 /*virtual*/ void sendFence(U32 fence);
86 /*virtual*/ void waitFence(U32 fence);
87
88private:
89 U8 *mMemp;
90 U32 mOffset; // Offset from base
91 U32 mSize;
92 friend class LLAGPMemPoolNV;
93};
94
95#endif // LL_LLAGPMEMPOOLNV_H
diff --git a/linden/indra/llrender/llfont.h b/linden/indra/llrender/llfont.h
index dadeafd..a84a302 100644
--- a/linden/indra/llrender/llfont.h
+++ b/linden/indra/llrender/llfont.h
@@ -31,6 +31,7 @@
31#include <map> 31#include <map>
32//#include "lllocalidhashmap.h" 32//#include "lllocalidhashmap.h"
33#include "llmemory.h" 33#include "llmemory.h"
34#include "llstl.h"
34 35
35class LLImageRaw; 36class LLImageRaw;
36class LLFontManager; 37class LLFontManager;
diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp
index 2774e8d..2740c6c 100644
--- a/linden/indra/llrender/llfontgl.cpp
+++ b/linden/indra/llrender/llfontgl.cpp
@@ -33,6 +33,7 @@
33#include "llfontgl.h" 33#include "llfontgl.h"
34#include "llgl.h" 34#include "llgl.h"
35#include "v4color.h" 35#include "v4color.h"
36#include "llstl.h"
36 37
37const S32 BOLD_OFFSET = 1; 38const S32 BOLD_OFFSET = 1;
38 39
@@ -155,7 +156,7 @@ LLString LLFontGL::getFontPathSystem()
155 // Try to figure out where the system's font files are stored. 156 // Try to figure out where the system's font files are stored.
156 char *system_root = NULL; 157 char *system_root = NULL;
157#if LL_WINDOWS 158#if LL_WINDOWS
158 system_root = getenv("SystemRoot"); 159 system_root = getenv("SystemRoot"); /* Flawfinder: ignore */
159 if (!system_root) 160 if (!system_root)
160 { 161 {
161 llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; 162 llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl;
@@ -647,7 +648,7 @@ S32 LLFontGL::render(const LLWString &wstr,
647 case LEFT: 648 case LEFT:
648 break; 649 break;
649 case RIGHT: 650 case RIGHT:
650 cur_x -= (F32)getWidth(wstr.c_str(), 0, length) * sScaleX; 651 cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX));
651 break; 652 break;
652 case HCENTER: 653 case HCENTER:
653 cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX)) / 2; 654 cur_x -= llmin(scaled_max_pixels, llround(getWidthF32(wstr.c_str(), 0, length) * sScaleX)) / 2;
@@ -672,12 +673,13 @@ S32 LLFontGL::render(const LLWString &wstr,
672 673
673 674
674 BOOL draw_ellipses = FALSE; 675 BOOL draw_ellipses = FALSE;
675 if (use_ellipses) 676 if (use_ellipses && halign == LEFT)
676 { 677 {
677 // check for too long of a string 678 // check for too long of a string
678 if (getWidthF32(wstr.c_str(), 0, max_chars) > scaled_max_pixels) 679 if (getWidthF32(wstr.c_str(), 0, max_chars) > scaled_max_pixels)
679 { 680 {
680 const LLWString dots(utf8str_to_wstring(LLString("..."))); 681 // use four dots for ellipsis width to generate padding
682 const LLWString dots(utf8str_to_wstring(LLString("....")));
681 scaled_max_pixels = llmax(0, scaled_max_pixels - llround(getWidthF32(dots.c_str()))); 683 scaled_max_pixels = llmax(0, scaled_max_pixels - llround(getWidthF32(dots.c_str())));
682 draw_ellipses = TRUE; 684 draw_ellipses = TRUE;
683 } 685 }
@@ -1330,7 +1332,7 @@ LLString LLFontGL::nameFromFont(const LLFontGL* fontp)
1330{ 1332{
1331 if (fontp == sSansSerifHuge) 1333 if (fontp == sSansSerifHuge)
1332 { 1334 {
1333 return LLString("SansSerifHude"); 1335 return LLString("SansSerifHuge");
1334 } 1336 }
1335 else if (fontp == sSansSerifSmall) 1337 else if (fontp == sSansSerifSmall)
1336 { 1338 {
diff --git a/linden/indra/llrender/llgldbg.cpp b/linden/indra/llrender/llgldbg.cpp
index 4d9f5f9..ab35353 100644
--- a/linden/indra/llrender/llgldbg.cpp
+++ b/linden/indra/llrender/llgldbg.cpp
@@ -89,8 +89,8 @@ char *fv4(F32 *f)
89//------------------------------------------------------------------------ 89//------------------------------------------------------------------------
90char *fv3(F32 *f) 90char *fv3(F32 *f)
91{ 91{
92 static char str[128]; 92 static char str[128]; /* Flawfinder: ignore */
93 sprintf(str, "%8.3f, %8.3f, %8.3f", f[0], f[1], f[2]); 93 snprintf(str, sizeof(str), "%8.3f, %8.3f, %8.3f", f[0], f[1], f[2]); /* Flawfinder: ignore */
94 return str; 94 return str;
95} 95}
96 96
@@ -99,8 +99,8 @@ char *fv3(F32 *f)
99//------------------------------------------------------------------------ 99//------------------------------------------------------------------------
100char *fv1(F32 *f) 100char *fv1(F32 *f)
101{ 101{
102 static char str[128]; 102 static char str[128]; /* Flawfinder: ignore */
103 sprintf(str, "%8.3f", f[0]); 103 snprintf(str, sizeof(str), "%8.3f", f[0]); /* Flawfinder: ignore */
104 return str; 104 return str;
105} 105}
106 106
diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp
index 5ea7322..8386e95 100644
--- a/linden/indra/llrender/llimagegl.cpp
+++ b/linden/indra/llrender/llimagegl.cpp
@@ -134,6 +134,15 @@ void LLImageGL::unbindTexture(S32 stage, LLGLenum bind_target)
134 sCurrentBoundTextures[stage] = 0; 134 sCurrentBoundTextures[stage] = 0;
135} 135}
136 136
137// static (duplicated for speed and to avoid GL_TEXTURE_2D default argument which requires GL header dependency)
138void LLImageGL::unbindTexture(S32 stage)
139{
140 glActiveTextureARB(GL_TEXTURE0_ARB + stage);
141 glClientActiveTextureARB(GL_TEXTURE0_ARB + stage);
142 glBindTexture(GL_TEXTURE_2D, 0);
143 sCurrentBoundTextures[stage] = 0;
144}
145
137// static 146// static
138void LLImageGL::updateStats(F32 current_time) 147void LLImageGL::updateStats(F32 current_time)
139{ 148{
@@ -390,13 +399,8 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const
390 llwarns << "Trying to bind a texture while GL is disabled!" << llendl; 399 llwarns << "Trying to bind a texture while GL is disabled!" << llendl;
391 } 400 }
392 401
393 stop_glerror();
394
395 glActiveTextureARB(GL_TEXTURE0_ARB + stage); 402 glActiveTextureARB(GL_TEXTURE0_ARB + stage);
396 //glClientActiveTextureARB(GL_TEXTURE0_ARB + stage); 403
397
398 stop_glerror();
399
400 if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName) 404 if (sCurrentBoundTextures[stage] && sCurrentBoundTextures[stage] == mTexName)
401 { 405 {
402 // already set! 406 // already set!
@@ -411,7 +415,6 @@ BOOL LLImageGL::bindTextureInternal(const S32 stage) const
411 415
412 glBindTexture(mBindTarget, mTexName); 416 glBindTexture(mBindTarget, mTexName);
413 sCurrentBoundTextures[stage] = mTexName; 417 sCurrentBoundTextures[stage] = mTexName;
414 stop_glerror();
415 418
416 if (mLastBindTime != sLastFrameTime) 419 if (mLastBindTime != sLastFrameTime)
417 { 420 {
@@ -650,6 +653,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
650 } 653 }
651 mHasMipMaps = FALSE; 654 mHasMipMaps = FALSE;
652 } 655 }
656 glFlush();
653 stop_glerror(); 657 stop_glerror();
654} 658}
655 659
@@ -664,6 +668,11 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
664 llwarns << "Setting subimage on image without GL texture" << llendl; 668 llwarns << "Setting subimage on image without GL texture" << llendl;
665 return FALSE; 669 return FALSE;
666 } 670 }
671 if (datap == NULL)
672 {
673 llwarns << "Setting subimage on image with NULL datap" << llendl;
674 return FALSE;
675 }
667 676
668 if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight()) 677 if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight())
669 { 678 {
@@ -676,7 +685,9 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
676 dump(); 685 dump();
677 llerrs << "setSubImage called with mipmapped image (not supported)" << llendl; 686 llerrs << "setSubImage called with mipmapped image (not supported)" << llendl;
678 } 687 }
679 llassert(mCurrentDiscardLevel == 0); 688 llassert_always(mCurrentDiscardLevel == 0);
689 llassert_always(x_pos >= 0 && y_pos >= 0);
690
680 if (((x_pos + width) > getWidth()) || 691 if (((x_pos + width) > getWidth()) ||
681 (y_pos + height) > getHeight()) 692 (y_pos + height) > getHeight())
682 { 693 {
@@ -717,9 +728,12 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
717 728
718 datap += (y_pos * data_width + x_pos) * getComponents(); 729 datap += (y_pos * data_width + x_pos) * getComponents();
719 // Update the GL texture 730 // Update the GL texture
720 llverify(bindTextureInternal(0)); 731 BOOL res = bindTextureInternal(0);
732 if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl;
721 stop_glerror(); 733 stop_glerror();
722 734
735 LLGLEnable tex( GL_TEXTURE_2D );
736
723 glTexSubImage2D(mTarget, 0, x_pos, y_pos, 737 glTexSubImage2D(mTarget, 0, x_pos, y_pos,
724 width, height, mFormatPrimary, mFormatType, datap); 738 width, height, mFormatPrimary, mFormatType, datap);
725 stop_glerror(); 739 stop_glerror();
@@ -733,7 +747,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
733 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 747 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
734 stop_glerror(); 748 stop_glerror();
735 } 749 }
736 750 glFlush();
737 return TRUE; 751 return TRUE;
738} 752}
739 753
diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h
index 6356703..20c31d1 100644
--- a/linden/indra/llrender/llimagegl.h
+++ b/linden/indra/llrender/llimagegl.h
@@ -36,7 +36,7 @@
36 36
37//============================================================================ 37//============================================================================
38 38
39class LLImageGL : public LLThreadSafeRefCount 39class LLImageGL : public LLRefCount
40{ 40{
41public: 41public:
42 // Size calculation 42 // Size calculation
@@ -48,6 +48,7 @@ public:
48 // Usually you want stage = 0 and bind_target = GL_TEXTURE_2D 48 // Usually you want stage = 0 and bind_target = GL_TEXTURE_2D
49 static void bindExternalTexture( LLGLuint gl_name, S32 stage, LLGLenum bind_target); 49 static void bindExternalTexture( LLGLuint gl_name, S32 stage, LLGLenum bind_target);
50 static void unbindTexture(S32 stage, LLGLenum target); 50 static void unbindTexture(S32 stage, LLGLenum target);
51 static void unbindTexture(S32 stage); // Uses GL_TEXTURE_2D (not a default arg to avoid gl.h dependency)
51 52
52 // needs to be called every frame 53 // needs to be called every frame
53 static void updateStats(F32 current_time); 54 static void updateStats(F32 current_time);
diff --git a/linden/indra/llrender/llrender.vcproj b/linden/indra/llrender/llrender.vcproj
index 9ca9b03..d13384d 100644
--- a/linden/indra/llrender/llrender.vcproj
+++ b/linden/indra/llrender/llrender.vcproj
@@ -154,18 +154,6 @@
154 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" 154 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
155 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> 155 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
156 <File 156 <File
157 RelativePath=".\llagpmempool.cpp">
158 </File>
159 <File
160 RelativePath=".\llagpmempoolarb.cpp">
161 </File>
162 <File
163 RelativePath=".\llagpmempoolati.cpp">
164 </File>
165 <File
166 RelativePath=".\llagpmempoolnv.cpp">
167 </File>
168 <File
169 RelativePath=".\llfont.cpp"> 157 RelativePath=".\llfont.cpp">
170 </File> 158 </File>
171 <File 159 <File
@@ -178,6 +166,9 @@
178 RelativePath=".\llimagegl.cpp"> 166 RelativePath=".\llimagegl.cpp">
179 </File> 167 </File>
180 <File 168 <File
169 RelativePath=".\llvertexbuffer.cpp">
170 </File>
171 <File
181 RelativePath=".\text_out.cpp"> 172 RelativePath=".\text_out.cpp">
182 </File> 173 </File>
183 </Filter> 174 </Filter>
@@ -213,6 +204,9 @@
213 RelativePath=".\llimagegl.h"> 204 RelativePath=".\llimagegl.h">
214 </File> 205 </File>
215 <File 206 <File
207 RelativePath=".\llvertexbuffer.h">
208 </File>
209 <File
216 RelativePath=".\llvertexprogramgl.h"> 210 RelativePath=".\llvertexprogramgl.h">
217 </File> 211 </File>
218 <File 212 <File
diff --git a/linden/indra/llrender/llrender_vc8.vcproj b/linden/indra/llrender/llrender_vc8.vcproj
new file mode 100644
index 0000000..daa2cfc
--- /dev/null
+++ b/linden/indra/llrender/llrender_vc8.vcproj
@@ -0,0 +1,302 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="8.00"
5 Name="llrender"
6 ProjectGUID="{2ADE3C14-94C4-40BF-B033-70F3C954EE90}"
7 Keyword="Win32Proj"
8 >
9 <Platforms>
10 <Platform
11 Name="Win32"
12 />
13 </Platforms>
14 <ToolFiles>
15 </ToolFiles>
16 <Configurations>
17 <Configuration
18 Name="Debug|Win32"
19 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
20 IntermediateDirectory="Debug"
21 ConfigurationType="4"
22 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
23 CharacterSet="1"
24 >
25 <Tool
26 Name="VCPreBuildEventTool"
27 />
28 <Tool
29 Name="VCCustomBuildTool"
30 />
31 <Tool
32 Name="VCXMLDataGeneratorTool"
33 />
34 <Tool
35 Name="VCWebServiceProxyGeneratorTool"
36 />
37 <Tool
38 Name="VCMIDLTool"
39 />
40 <Tool
41 Name="VCCLCompilerTool"
42 Optimization="0"
43 AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\llimage;..\llwindow;..\..\libraries\i686-win32\include;..\..\libraries\include\"
44 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_DEBUG"
45 MinimalRebuild="true"
46 BasicRuntimeChecks="3"
47 RuntimeLibrary="1"
48 StructMemberAlignment="4"
49 TreatWChar_tAsBuiltInType="false"
50 ForceConformanceInForLoopScope="true"
51 UsePrecompiledHeader="0"
52 WarningLevel="3"
53 WarnAsError="true"
54 Detect64BitPortabilityProblems="false"
55 DebugInformationFormat="4"
56 />
57 <Tool
58 Name="VCManagedResourceCompilerTool"
59 />
60 <Tool
61 Name="VCResourceCompilerTool"
62 />
63 <Tool
64 Name="VCPreLinkEventTool"
65 />
66 <Tool
67 Name="VCLibrarianTool"
68 OutputFile="$(OutDir)/llrender.lib"
69 />
70 <Tool
71 Name="VCALinkTool"
72 />
73 <Tool
74 Name="VCXDCMakeTool"
75 />
76 <Tool
77 Name="VCBscMakeTool"
78 />
79 <Tool
80 Name="VCFxCopTool"
81 />
82 <Tool
83 Name="VCPostBuildEventTool"
84 />
85 </Configuration>
86 <Configuration
87 Name="Release|Win32"
88 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
89 IntermediateDirectory="Release"
90 ConfigurationType="4"
91 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
92 CharacterSet="1"
93 >
94 <Tool
95 Name="VCPreBuildEventTool"
96 />
97 <Tool
98 Name="VCCustomBuildTool"
99 />
100 <Tool
101 Name="VCXMLDataGeneratorTool"
102 />
103 <Tool
104 Name="VCWebServiceProxyGeneratorTool"
105 />
106 <Tool
107 Name="VCMIDLTool"
108 />
109 <Tool
110 Name="VCCLCompilerTool"
111 InlineFunctionExpansion="2"
112 EnableIntrinsicFunctions="true"
113 AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\llimage;..\llwindow;..\..\libraries\i686-win32\include;..\..\libraries\include\"
114 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE"
115 RuntimeLibrary="0"
116 StructMemberAlignment="0"
117 TreatWChar_tAsBuiltInType="false"
118 ForceConformanceInForLoopScope="true"
119 UsePrecompiledHeader="0"
120 WarningLevel="3"
121 WarnAsError="true"
122 Detect64BitPortabilityProblems="false"
123 DebugInformationFormat="3"
124 />
125 <Tool
126 Name="VCManagedResourceCompilerTool"
127 />
128 <Tool
129 Name="VCResourceCompilerTool"
130 />
131 <Tool
132 Name="VCPreLinkEventTool"
133 />
134 <Tool
135 Name="VCLibrarianTool"
136 OutputFile="$(OutDir)/llrender.lib"
137 />
138 <Tool
139 Name="VCALinkTool"
140 />
141 <Tool
142 Name="VCXDCMakeTool"
143 />
144 <Tool
145 Name="VCBscMakeTool"
146 />
147 <Tool
148 Name="VCFxCopTool"
149 />
150 <Tool
151 Name="VCPostBuildEventTool"
152 />
153 </Configuration>
154 <Configuration
155 Name="ReleaseNoOpt|Win32"
156 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
157 IntermediateDirectory="$(ConfigurationName)"
158 ConfigurationType="4"
159 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
160 CharacterSet="1"
161 >
162 <Tool
163 Name="VCPreBuildEventTool"
164 />
165 <Tool
166 Name="VCCustomBuildTool"
167 />
168 <Tool
169 Name="VCXMLDataGeneratorTool"
170 />
171 <Tool
172 Name="VCWebServiceProxyGeneratorTool"
173 />
174 <Tool
175 Name="VCMIDLTool"
176 />
177 <Tool
178 Name="VCCLCompilerTool"
179 Optimization="0"
180 AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\llimage;..\llwindow;..\..\libraries\i686-win32\include;..\..\libraries\include\"
181 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE"
182 RuntimeLibrary="0"
183 StructMemberAlignment="0"
184 TreatWChar_tAsBuiltInType="false"
185 ForceConformanceInForLoopScope="true"
186 UsePrecompiledHeader="0"
187 WarningLevel="3"
188 WarnAsError="true"
189 Detect64BitPortabilityProblems="false"
190 DebugInformationFormat="3"
191 />
192 <Tool
193 Name="VCManagedResourceCompilerTool"
194 />
195 <Tool
196 Name="VCResourceCompilerTool"
197 />
198 <Tool
199 Name="VCPreLinkEventTool"
200 />
201 <Tool
202 Name="VCLibrarianTool"
203 OutputFile="$(OutDir)/llrender.lib"
204 />
205 <Tool
206 Name="VCALinkTool"
207 />
208 <Tool
209 Name="VCXDCMakeTool"
210 />
211 <Tool
212 Name="VCBscMakeTool"
213 />
214 <Tool
215 Name="VCFxCopTool"
216 />
217 <Tool
218 Name="VCPostBuildEventTool"
219 />
220 </Configuration>
221 </Configurations>
222 <References>
223 </References>
224 <Files>
225 <Filter
226 Name="Source Files"
227 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
228 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
229 >
230 <File
231 RelativePath=".\llfont.cpp"
232 >
233 </File>
234 <File
235 RelativePath=".\llfontgl.cpp"
236 >
237 </File>
238 <File
239 RelativePath=".\llgldbg.cpp"
240 >
241 </File>
242 <File
243 RelativePath=".\llimagegl.cpp"
244 >
245 </File>
246 <File
247 RelativePath=".\llvertexbuffer.cpp"
248 >
249 </File>
250 <File
251 RelativePath=".\text_out.cpp"
252 >
253 </File>
254 </Filter>
255 <Filter
256 Name="Header Files"
257 Filter="h;hpp;hxx;hm;inl;inc;xsd"
258 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
259 >
260 <File
261 RelativePath=".\glext.h"
262 >
263 </File>
264 <File
265 RelativePath=".\llfont.h"
266 >
267 </File>
268 <File
269 RelativePath=".\llfontgl.h"
270 >
271 </File>
272 <File
273 RelativePath=".\llgldbg.h"
274 >
275 </File>
276 <File
277 RelativePath=".\llimagegl.h"
278 >
279 </File>
280 <File
281 RelativePath=".\llvertexbuffer.h"
282 >
283 </File>
284 <File
285 RelativePath=".\llvertexprogramgl.h"
286 >
287 </File>
288 <File
289 RelativePath=".\text_out.h"
290 >
291 </File>
292 </Filter>
293 <Filter
294 Name="Resource Files"
295 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
296 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
297 >
298 </Filter>
299 </Files>
300 <Globals>
301 </Globals>
302</VisualStudioProject>
diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp
new file mode 100644
index 0000000..b94f593
--- /dev/null
+++ b/linden/indra/llrender/llvertexbuffer.cpp
@@ -0,0 +1,922 @@
1#include "linden_common.h"
2
3#include "llvertexbuffer.h"
4// #include "llrender.h"
5#include "llglheaders.h"
6#include "llmemory.h"
7#include "llmemtype.h"
8
9//============================================================================
10
11//static
12S32 LLVertexBuffer::sCount = 0;
13S32 LLVertexBuffer::sGLCount = 0;
14BOOL LLVertexBuffer::sEnableVBOs = TRUE;
15U32 LLVertexBuffer::sGLRenderBuffer = 0;
16U32 LLVertexBuffer::sGLRenderIndices = 0;
17U32 LLVertexBuffer::sLastMask = 0;
18BOOL LLVertexBuffer::sVBOActive = FALSE;
19BOOL LLVertexBuffer::sIBOActive = FALSE;
20U32 LLVertexBuffer::sAllocatedBytes = 0;
21BOOL LLVertexBuffer::sRenderActive = FALSE;
22
23std::vector<U32> LLVertexBuffer::sDeleteList;
24LLVertexBuffer::buffer_list_t LLVertexBuffer::sLockedList;
25
26S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] =
27{
28 sizeof(LLVector3), // TYPE_VERTEX,
29 sizeof(LLVector3), // TYPE_NORMAL,
30 sizeof(LLVector2), // TYPE_TEXCOORD,
31 sizeof(LLVector2), // TYPE_TEXCOORD2,
32 sizeof(LLColor4U), // TYPE_COLOR,
33 sizeof(LLVector3), // TYPE_BINORMAL,
34 sizeof(F32), // TYPE_WEIGHT,
35 sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
36};
37
38//static
39void LLVertexBuffer::initClass(bool use_vbo)
40{
41 sEnableVBOs = use_vbo;
42}
43
44//static
45void LLVertexBuffer::unbind()
46{
47 if (sVBOActive)
48 {
49 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
50 sVBOActive = FALSE;
51 }
52 if (sIBOActive)
53 {
54 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
55 sIBOActive = FALSE;
56 }
57
58 sGLRenderBuffer = 0;
59 sGLRenderIndices = 0;
60}
61
62//static
63void LLVertexBuffer::cleanupClass()
64{
65 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
66 sLockedList.clear();
67 startRender();
68 stopRender();
69 clientCopy(); // deletes GL buffers
70}
71
72//static, call before rendering VBOs
73void LLVertexBuffer::startRender()
74{
75 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
76 if (sEnableVBOs)
77 {
78 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
79 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
80 sVBOActive = FALSE;
81 sIBOActive = FALSE;
82 }
83
84 sRenderActive = TRUE;
85 sGLRenderBuffer = 0;
86 sGLRenderIndices = 0;
87 sLastMask = 0;
88}
89
90void LLVertexBuffer::stopRender()
91{
92 sRenderActive = FALSE;
93}
94
95void LLVertexBuffer::clientCopy(F64 max_time)
96{
97 if (!sDeleteList.empty())
98 {
99 size_t num = sDeleteList.size();
100 glDeleteBuffersARB(sDeleteList.size(), (GLuint*) &(sDeleteList[0]));
101 sDeleteList.clear();
102 sGLCount -= num;
103 }
104
105 if (sEnableVBOs)
106 {
107 LLTimer timer;
108 BOOL reset = TRUE;
109 buffer_list_t::iterator iter = sLockedList.begin();
110 while(iter != sLockedList.end())
111 {
112 LLVertexBuffer* buffer = *iter;
113 if (buffer->isLocked() && buffer->useVBOs())
114 {
115 buffer->setBuffer(0);
116 }
117 ++iter;
118 if (reset)
119 {
120 reset = FALSE;
121 timer.reset(); //skip first copy (don't count pipeline stall)
122 }
123 else
124 {
125 if (timer.getElapsedTimeF64() > max_time)
126 {
127 break;
128 }
129 }
130
131 }
132
133 sLockedList.erase(sLockedList.begin(), iter);
134 }
135}
136
137//----------------------------------------------------------------------------
138
139// For debugging
140struct VTNC /// Simple
141{
142 F32 v1,v2,v3;
143 F32 n1,n2,n3;
144 F32 t1,t2;
145 U32 c;
146};
147static VTNC dbg_vtnc;
148
149struct VTUNCB // Simple + Bump
150{
151 F32 v1,v2,v3;
152 F32 n1,n2,n3;
153 F32 t1,t2;
154 F32 u1,u2;
155 F32 b1,b2,b3;
156 U32 c;
157};
158static VTUNCB dbg_vtuncb;
159
160struct VTUNC // Surfacepatch
161{
162 F32 v1,v2,v3;
163 F32 n1,n2,n3;
164 F32 t1,t2;
165 F32 u1,u2;
166 U32 c;
167};
168static VTUNC dbg_vtunc;
169
170struct VTNW /// Avatar
171{
172 F32 v1,v2,v3;
173 F32 n1,n2,n3;
174 F32 t1,t2;
175 F32 w;
176};
177static VTNW dbg_vtnw;
178
179struct VTNPAD /// Avatar Output
180{
181 F32 v1,v2,v3,p1;
182 F32 n1,n2,n3,p2;
183 F32 t1,t2,p3,p4;
184};
185static VTNPAD dbg_vtnpad;
186
187//----------------------------------------------------------------------------
188
189LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
190 LLRefCount(),
191 mNumVerts(0), mNumIndices(0), mUsage(usage), mGLBuffer(0), mGLIndices(0),
192 mMappedData(NULL),
193 mMappedIndexData(NULL), mLocked(FALSE),
194 mFinal(FALSE),
195 mFilthy(FALSE),
196 mEmpty(TRUE),
197 mResized(FALSE)
198{
199 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
200 if (!sEnableVBOs)
201 {
202 mUsage = GL_STREAM_DRAW_ARB;
203 }
204
205 S32 stride = 0;
206 for (S32 i=0; i<TYPE_MAX; i++)
207 {
208 U32 mask = 1<<i;
209 if (typemask & mask)
210 {
211 mOffsets[i] = stride;
212 stride += sTypeOffsets[i];
213 }
214 }
215 mTypeMask = typemask;
216 mStride = stride;
217 sCount++;
218}
219
220// protected, use unref()
221//virtual
222LLVertexBuffer::~LLVertexBuffer()
223{
224 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
225 destroyGLBuffer();
226 destroyGLIndices();
227 sCount--;
228
229 if (mLocked)
230 {
231 //pull off of locked list
232 for (buffer_list_t::iterator i = sLockedList.begin(); i != sLockedList.end(); ++i)
233 {
234 if (*i == this)
235 {
236 sLockedList.erase(i);
237 break;
238 }
239 }
240 }
241};
242
243//----------------------------------------------------------------------------
244
245void LLVertexBuffer::createGLBuffer()
246{
247 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
248
249 U32 size = getSize();
250 if (mGLBuffer)
251 {
252 destroyGLBuffer();
253 }
254
255 if (size == 0)
256 {
257 return;
258 }
259
260 mMappedData = new U8[size];
261 memset(mMappedData, 0, size);
262 mEmpty = TRUE;
263
264 if (useVBOs())
265 {
266 glGenBuffersARB(1, (GLuint*) &mGLBuffer);
267 mResized = TRUE;
268 sGLCount++;
269 }
270 else
271 {
272 static int gl_buffer_idx = 0;
273 mGLBuffer = ++gl_buffer_idx;
274 }
275}
276
277void LLVertexBuffer::createGLIndices()
278{
279 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
280 U32 size = getIndicesSize();
281
282 if (mGLIndices)
283 {
284 destroyGLIndices();
285 }
286
287 if (size == 0)
288 {
289 return;
290 }
291
292 mMappedIndexData = new U8[size];
293 memset(mMappedIndexData, 0, size);
294 mEmpty = TRUE;
295
296 if (useVBOs())
297 {
298 glGenBuffersARB(1, (GLuint*) &mGLIndices);
299 mResized = TRUE;
300 sGLCount++;
301 }
302 else
303 {
304 static int gl_buffer_idx = 0;
305 mGLIndices = ++gl_buffer_idx;
306 }
307}
308
309void LLVertexBuffer::destroyGLBuffer()
310{
311 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
312 if (mGLBuffer)
313 {
314 if (useVBOs())
315 {
316 sDeleteList.push_back(mGLBuffer);
317 }
318
319 delete [] mMappedData;
320 mMappedData = NULL;
321 mEmpty = TRUE;
322 sAllocatedBytes -= getSize();
323 }
324
325 mGLBuffer = 0;
326}
327
328void LLVertexBuffer::destroyGLIndices()
329{
330 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
331 if (mGLIndices)
332 {
333 if (useVBOs())
334 {
335 sDeleteList.push_back(mGLIndices);
336 }
337
338 delete [] mMappedIndexData;
339 mMappedIndexData = NULL;
340 mEmpty = TRUE;
341 sAllocatedBytes -= getIndicesSize();
342 }
343
344 mGLIndices = 0;
345}
346
347void LLVertexBuffer::updateNumVerts(S32 nverts)
348{
349 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
350 if (!mDynamicSize)
351 {
352 mNumVerts = nverts;
353 }
354 else if (mUsage == GL_STATIC_DRAW_ARB ||
355 nverts > mNumVerts ||
356 nverts < mNumVerts/2)
357 {
358 if (mUsage != GL_STATIC_DRAW_ARB)
359 {
360 nverts += nverts/4;
361 }
362
363 mNumVerts = nverts;
364 }
365}
366
367void LLVertexBuffer::updateNumIndices(S32 nindices)
368{
369 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
370 if (!mDynamicSize)
371 {
372 mNumIndices = nindices;
373 }
374 else if (mUsage == GL_STATIC_DRAW_ARB ||
375 nindices > mNumIndices ||
376 nindices < mNumIndices/2)
377 {
378 if (mUsage != GL_STATIC_DRAW_ARB)
379 {
380 nindices += nindices/4;
381 }
382
383 mNumIndices = nindices;
384 }
385}
386
387void LLVertexBuffer::makeStatic()
388{
389 if (!sEnableVBOs)
390 {
391 return;
392 }
393
394 if (sRenderActive)
395 {
396 llerrs << "Make static called during render." << llendl;
397 }
398
399 if (mUsage != GL_STATIC_DRAW_ARB)
400 {
401 if (useVBOs())
402 {
403 if (mGLBuffer)
404 {
405 sDeleteList.push_back(mGLBuffer);
406 }
407 if (mGLIndices)
408 {
409 sDeleteList.push_back(mGLIndices);
410 }
411 }
412
413 if (mGLBuffer)
414 {
415 sGLCount++;
416 glGenBuffersARB(1, (GLuint*) &mGLBuffer);
417 }
418 if (mGLIndices)
419 {
420 sGLCount++;
421 glGenBuffersARB(1, (GLuint*) &mGLIndices);
422 }
423
424 mUsage = GL_STATIC_DRAW_ARB;
425 mResized = TRUE;
426
427 if (!mLocked)
428 {
429 mLocked = TRUE;
430 sLockedList.push_back(this);
431 }
432 }
433}
434
435void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
436{
437 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
438
439 updateNumVerts(nverts);
440 updateNumIndices(nindices);
441
442 if (mMappedData)
443 {
444 llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl;
445 }
446 if (create && (nverts || nindices))
447 {
448 createGLBuffer();
449 createGLIndices();
450 }
451
452 sAllocatedBytes += getSize() + getIndicesSize();
453}
454
455void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
456{
457 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
458 mDynamicSize = TRUE;
459 if (mUsage == GL_STATIC_DRAW_ARB)
460 { //always delete/allocate static buffers on resize
461 destroyGLBuffer();
462 destroyGLIndices();
463 allocateBuffer(newnverts, newnindices, TRUE);
464 mFinal = FALSE;
465 }
466 else if (newnverts > mNumVerts || newnindices > mNumIndices ||
467 newnverts < mNumVerts/2 || newnindices < mNumIndices/2)
468 {
469 sAllocatedBytes -= getSize() + getIndicesSize();
470
471 S32 oldsize = getSize();
472 S32 old_index_size = getIndicesSize();
473
474 updateNumVerts(newnverts);
475 updateNumIndices(newnindices);
476
477 S32 newsize = getSize();
478 S32 new_index_size = getIndicesSize();
479
480 sAllocatedBytes += newsize + new_index_size;
481
482 if (newsize)
483 {
484 if (!mGLBuffer)
485 { //no buffer exists, create a new one
486 createGLBuffer();
487 }
488 else
489 {
490 //delete old buffer, keep GL buffer for now
491 U8* old = mMappedData;
492 mMappedData = new U8[newsize];
493 if (old)
494 {
495 memcpy(mMappedData, old, llmin(newsize, oldsize));
496 if (newsize > oldsize)
497 {
498 memset(mMappedData+oldsize, 0, newsize-oldsize);
499 }
500
501 delete [] old;
502 }
503 else
504 {
505 memset(mMappedData, 0, newsize);
506 mEmpty = TRUE;
507 }
508 mResized = TRUE;
509 }
510 }
511 else if (mGLBuffer)
512 {
513 destroyGLBuffer();
514 }
515
516 if (new_index_size)
517 {
518 if (!mGLIndices)
519 {
520 createGLIndices();
521 }
522 else
523 {
524 //delete old buffer, keep GL buffer for now
525 U8* old = mMappedIndexData;
526 mMappedIndexData = new U8[new_index_size];
527 if (old)
528 {
529 memcpy(mMappedIndexData, old, llmin(new_index_size, old_index_size));
530 if (new_index_size > old_index_size)
531 {
532 memset(mMappedIndexData+old_index_size, 0, new_index_size - old_index_size);
533 }
534 delete [] old;
535 }
536 else
537 {
538 memset(mMappedIndexData, 0, new_index_size);
539 mEmpty = TRUE;
540 }
541 mResized = TRUE;
542 }
543 }
544 else if (mGLIndices)
545 {
546 destroyGLIndices();
547 }
548 }
549}
550
551BOOL LLVertexBuffer::useVBOs() const
552{
553 //it's generally ineffective to use VBO for things that are streaming
554 //when we already have a client buffer around
555 if (mUsage == GL_STREAM_DRAW_ARB)
556 {
557 return FALSE;
558 }
559
560 return sEnableVBOs && (!sRenderActive || !mLocked);
561}
562
563//----------------------------------------------------------------------------
564
565// Map for data access
566U8* LLVertexBuffer::mapBuffer(S32 access)
567{
568 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
569 if (sRenderActive)
570 {
571 llwarns << "Buffer mapped during render frame!" << llendl;
572 }
573 if (!mGLBuffer && !mGLIndices)
574 {
575 llerrs << "LLVertexBuffer::mapBuffer() called before createGLBuffer" << llendl;
576 }
577 if (mFinal)
578 {
579 llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
580 }
581 if (!mMappedData && !mMappedIndexData)
582 {
583 llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
584 }
585
586 if (!mLocked && useVBOs())
587 {
588 mLocked = TRUE;
589 sLockedList.push_back(this);
590 }
591
592 return mMappedData;
593}
594
595void LLVertexBuffer::unmapBuffer()
596{
597 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
598 if (mMappedData || mMappedIndexData)
599 {
600 if (useVBOs() && mLocked)
601 {
602 if (mGLBuffer)
603 {
604 if (mResized)
605 {
606 glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), mMappedData, mUsage);
607 }
608 else
609 {
610 if (mEmpty || mDirtyRegions.empty())
611 {
612 glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
613 }
614 else
615 {
616 for (std::vector<DirtyRegion>::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i)
617 {
618 DirtyRegion& region = *i;
619 glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, region.mIndex*mStride, region.mCount*mStride, mMappedData + region.mIndex*mStride);
620 }
621 }
622 }
623 }
624
625 if (mGLIndices)
626 {
627 if (mResized)
628 {
629 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), mMappedIndexData, mUsage);
630 }
631 else
632 {
633 if (mEmpty || mDirtyRegions.empty())
634 {
635 glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
636 }
637 else
638 {
639 for (std::vector<DirtyRegion>::iterator i = mDirtyRegions.begin(); i != mDirtyRegions.end(); ++i)
640 {
641 DirtyRegion& region = *i;
642 glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, region.mIndicesIndex*sizeof(U32),
643 region.mIndicesCount*sizeof(U32), mMappedIndexData + region.mIndicesIndex*sizeof(U32));
644 }
645 }
646 }
647 }
648
649 mDirtyRegions.clear();
650 mFilthy = FALSE;
651 mResized = FALSE;
652
653 if (mUsage == GL_STATIC_DRAW_ARB)
654 { //static draw buffers can only be mapped a single time
655 //throw out client data (we won't be using it again)
656 delete [] mMappedData;
657 delete [] mMappedIndexData;
658 mMappedIndexData = NULL;
659 mMappedData = NULL;
660 mEmpty = TRUE;
661 mFinal = TRUE;
662 }
663 else
664 {
665 mEmpty = FALSE;
666 }
667
668 mLocked = FALSE;
669
670 glFlush();
671 }
672 }
673}
674
675//----------------------------------------------------------------------------
676
677template <class T,S32 type> struct VertexBufferStrider
678{
679 typedef LLStrider<T> strider_t;
680 static bool get(LLVertexBuffer& vbo,
681 strider_t& strider,
682 S32 index)
683 {
684 vbo.mapBuffer();
685 if (type == LLVertexBuffer::TYPE_INDEX)
686 {
687 S32 stride = sizeof(T);
688 strider = (T*)(vbo.getMappedIndices() + index*stride);
689 strider.setStride(0);
690 return TRUE;
691 }
692 else if (vbo.hasDataType(type))
693 {
694 S32 stride = vbo.getStride();
695 strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride);
696 strider.setStride(stride);
697 return TRUE;
698 }
699 else
700 {
701 llerrs << "VertexBufferStrider could not find valid vertex data." << llendl;
702 }
703 return FALSE;
704 }
705};
706
707
708bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index)
709{
710 return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index);
711}
712bool LLVertexBuffer::getIndexStrider(LLStrider<U32>& strider, S32 index)
713{
714 return VertexBufferStrider<U32,TYPE_INDEX>::get(*this, strider, index);
715}
716bool LLVertexBuffer::getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index)
717{
718 return VertexBufferStrider<LLVector2,TYPE_TEXCOORD>::get(*this, strider, index);
719}
720bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index)
721{
722 return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index);
723}
724bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index)
725{
726 return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index);
727}
728bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index)
729{
730 return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index);
731}
732bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index)
733{
734 return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index);
735}
736bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index)
737{
738 return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index);
739}
740bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index)
741{
742 return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index);
743}
744
745void LLVertexBuffer::setStride(S32 type, S32 new_stride)
746{
747 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
748 if (mNumVerts)
749 {
750 llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl;
751 }
752 // This code assumes that setStride() will only be called once per VBO per type.
753 S32 delta = new_stride - sTypeOffsets[type];
754 for (S32 i=type+1; i<TYPE_MAX; i++)
755 {
756 if (mTypeMask & (1<<i))
757 {
758 mOffsets[i] += delta;
759 }
760 }
761 mStride += delta;
762}
763
764//----------------------------------------------------------------------------
765
766// Set for rendering
767void LLVertexBuffer::setBuffer(U32 data_mask)
768{
769 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
770 //set up pointers if the data mask is different ...
771 BOOL setup = (sLastMask != data_mask);
772
773 if (useVBOs())
774 {
775 if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))
776 {
777 glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
778 sVBOActive = TRUE;
779 setup = TRUE; // ... or the bound buffer changed
780 }
781 if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))
782 {
783 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
784 sIBOActive = TRUE;
785 }
786
787 unmapBuffer();
788 }
789 else
790 {
791 if (mGLBuffer)
792 {
793 if (sEnableVBOs && sVBOActive)
794 {
795 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
796 sVBOActive = FALSE;
797 setup = TRUE; // ... or a VBO is deactivated
798 }
799 if (sGLRenderBuffer != mGLBuffer)
800 {
801 setup = TRUE; // ... or a client memory pointer changed
802 }
803 }
804 if (sEnableVBOs && mGLIndices && sIBOActive)
805 {
806 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
807 sIBOActive = FALSE;
808 }
809 }
810
811 if (mGLIndices)
812 {
813 sGLRenderIndices = mGLIndices;
814 }
815 if (mGLBuffer)
816 {
817 sGLRenderBuffer = mGLBuffer;
818 if (data_mask && setup)
819 {
820 if (!sRenderActive)
821 {
822 llwarns << "Vertex buffer set for rendering outside of render frame." << llendl;
823 }
824 setupVertexBuffer(data_mask); // subclass specific setup (virtual function)
825 sLastMask = data_mask;
826 }
827 }
828}
829
830// virtual (default)
831void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
832{
833 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
834 stop_glerror();
835 U8* base = useVBOs() ? NULL : mMappedData;
836 S32 stride = mStride;
837
838 if ((data_mask & mTypeMask) != data_mask)
839 {
840 llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
841 }
842
843 if (data_mask & MAP_VERTEX)
844 {
845 glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0));
846 }
847 if (data_mask & MAP_NORMAL)
848 {
849 glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL]));
850 }
851 if (data_mask & MAP_TEXCOORD2)
852 {
853 glClientActiveTextureARB(GL_TEXTURE1_ARB);
854 glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
855 }
856 if (data_mask & MAP_TEXCOORD)
857 {
858 glClientActiveTextureARB(GL_TEXTURE0_ARB);
859 glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD]));
860 }
861 if (data_mask & MAP_COLOR)
862 {
863 glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR]));
864 }
865 if (data_mask & MAP_BINORMAL)
866 {
867 glVertexAttribPointerARB(6, 3, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_BINORMAL]));
868 }
869 if (data_mask & MAP_WEIGHT)
870 {
871 glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT]));
872 }
873 if (data_mask & MAP_CLOTHWEIGHT)
874 {
875 glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
876 }
877
878 llglassertok();
879}
880
881void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count)
882{
883 if (useVBOs() && !mFilthy)
884 {
885 if (!mDirtyRegions.empty())
886 {
887 DirtyRegion& region = *(mDirtyRegions.rbegin());
888
889 if (region.mIndex+region.mCount > vert_index)
890 {
891 //this buffer has received multiple updates since the last copy, mark it filthy
892 mFilthy = TRUE;
893 mDirtyRegions.clear();
894 return;
895 }
896
897 if (region.mIndex + region.mCount == vert_index &&
898 region.mIndicesIndex + region.mIndicesCount == indices_index)
899 {
900 region.mCount += vert_count;
901 region.mIndicesCount += indices_count;
902 return;
903 }
904 }
905
906 mDirtyRegions.push_back(DirtyRegion(vert_index,vert_count,indices_index,indices_count));
907 }
908}
909
910void LLVertexBuffer::markClean()
911{
912 if (!mResized && !mEmpty && !mFilthy)
913 {
914 buffer_list_t::reverse_iterator iter = sLockedList.rbegin();
915 if (*iter == this)
916 {
917 mLocked = FALSE;
918 sLockedList.pop_back();
919 }
920 }
921}
922
diff --git a/linden/indra/llrender/llvertexbuffer.h b/linden/indra/llrender/llvertexbuffer.h
new file mode 100644
index 0000000..b221d35
--- /dev/null
+++ b/linden/indra/llrender/llvertexbuffer.h
@@ -0,0 +1,179 @@
1#ifndef LL_LLVERTEXBUFFER_H
2#define LL_LLVERTEXBUFFER_H
3
4#include "llgl.h"
5#include "v2math.h"
6#include "v3math.h"
7#include "v4math.h"
8#include "v4coloru.h"
9#include "llstrider.h"
10#include "llmemory.h"
11#include <set>
12#include <vector>
13
14//============================================================================
15// NOTES
16// Threading:
17// All constructors should take an 'create' paramater which should only be
18// 'true' when called from the main thread. Otherwise createGLBuffer() will
19// be called as soon as getVertexPointer(), etc is called (which MUST ONLY be
20// called from the main (i.e OpenGL) thread)
21
22//============================================================================
23// base class
24
25class LLVertexBuffer : public LLRefCount
26{
27public:
28 static void initClass(bool use_vbo);
29 static void cleanupClass();
30 static void startRender(); //between start and stop render, no client copies will occur
31 static void stopRender(); //any buffer not copied to GL will be rendered from client memory
32 static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
33 static void unbind(); //unbind any bound vertex buffer
34
35 enum {
36 TYPE_VERTEX,
37 TYPE_NORMAL,
38 TYPE_TEXCOORD,
39 TYPE_TEXCOORD2,
40 TYPE_COLOR,
41 // These use VertexAttribPointer and should possibly be made generic
42 TYPE_BINORMAL,
43 TYPE_WEIGHT,
44 TYPE_CLOTHWEIGHT,
45 TYPE_MAX,
46 TYPE_INDEX,
47 };
48 enum {
49 MAP_VERTEX = (1<<TYPE_VERTEX),
50 MAP_NORMAL = (1<<TYPE_NORMAL),
51 MAP_TEXCOORD = (1<<TYPE_TEXCOORD),
52 MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
53 MAP_COLOR = (1<<TYPE_COLOR),
54 // These use VertexAttribPointer and should possibly be made generic
55 MAP_BINORMAL = (1<<TYPE_BINORMAL),
56 MAP_WEIGHT = (1<<TYPE_WEIGHT),
57 MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
58 MAP_DRAW = 0x2000, // Buffer is in draw (read-only) mode
59 MAP_MAPPED = 0x4000, // Indicates that buffer has been mapped, but not to any type of data
60 MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped
61 };
62
63protected:
64 virtual ~LLVertexBuffer(); // use unref()
65
66 virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
67
68 void createGLBuffer();
69 void createGLIndices();
70 void destroyGLBuffer();
71 void destroyGLIndices();
72 void updateNumVerts(S32 nverts);
73 void updateNumIndices(S32 nindices);
74 virtual BOOL useVBOs() const;
75 void unmapBuffer();
76
77public:
78 LLVertexBuffer(U32 typemask, S32 usage);
79
80 // map for data access
81 U8* mapBuffer(S32 access = -1);
82 // set for rendering
83 virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
84 // allocate buffer
85 void allocateBuffer(S32 nverts, S32 nindices, bool create);
86 virtual void resizeBuffer(S32 newnverts, S32 newnindices);
87 void makeStatic();
88
89 // Only call each getVertexPointer, etc, once before calling unmapBuffer()
90 // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
91 // example:
92 // vb->getVertexBuffer(verts);
93 // vb->getNormalStrider(norms);
94 // setVertsNorms(verts, norms);
95 // vb->unmapBuffer();
96 bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0);
97 bool getIndexStrider(LLStrider<U32>& strider, S32 index=0);
98 bool getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index=0);
99 bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0);
100 bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
101 bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
102 bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0);
103 bool getWeightStrider(LLStrider<F32>& strider, S32 index=0);
104 bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
105
106 BOOL isEmpty() const { return mEmpty; }
107 BOOL isLocked() const { return mLocked; }
108 S32 getNumVerts() const { return mNumVerts; }
109 S32 getNumIndices() const { return mNumIndices; }
110 U8* getIndicesPointer() const { return useVBOs() ? NULL : mMappedIndexData; }
111 U8* getVerticesPointer() const { return useVBOs() ? NULL : mMappedData; }
112 S32 getStride() const { return mStride; }
113 S32 getTypeMask() const { return mTypeMask; }
114 BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; }
115 S32 getSize() const { return mNumVerts*mStride; }
116 S32 getIndicesSize() const { return mNumIndices * sizeof(U32); }
117 U8* getMappedData() const { return mMappedData; }
118 U8* getMappedIndices() const { return mMappedIndexData; }
119 S32 getOffset(S32 type) const { return mOffsets[type]; }
120 S32 getUsage() const { return mUsage; }
121
122 void setStride(S32 type, S32 new_stride);
123
124 void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count);
125 void markClean();
126
127protected:
128 S32 mNumVerts; // Number of vertices
129 S32 mNumIndices; // Number of indices
130 S32 mStride;
131 U32 mTypeMask;
132 S32 mUsage; // GL usage
133 U32 mGLBuffer; // GL VBO handle
134 U32 mGLIndices; // GL IBO handle
135 U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
136 U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
137 BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory
138 BOOL mFinal; // if TRUE, buffer can not be mapped again
139 BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
140 BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
141 S32 mOffsets[TYPE_MAX];
142 BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not
143 BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
144
145 class DirtyRegion
146 {
147 public:
148 U32 mIndex;
149 U32 mCount;
150 U32 mIndicesIndex;
151 U32 mIndicesCount;
152
153 DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic)
154 : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic)
155 { }
156 };
157
158 std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild
159
160public:
161 static BOOL sRenderActive;
162 static S32 sCount;
163 static S32 sGLCount;
164 static std::vector<U32> sDeleteList;
165 typedef std::list<LLVertexBuffer*> buffer_list_t;
166 static buffer_list_t sLockedList;
167
168 static BOOL sEnableVBOs;
169 static S32 sTypeOffsets[TYPE_MAX];
170 static U32 sGLRenderBuffer;
171 static U32 sGLRenderIndices;
172 static BOOL sVBOActive;
173 static BOOL sIBOActive;
174 static U32 sLastMask;
175 static U32 sAllocatedBytes;
176};
177
178
179#endif // LL_LLVERTEXBUFFER_H
diff --git a/linden/indra/llrender/llvertexprogramgl.cpp b/linden/indra/llrender/llvertexprogramgl.cpp
index bc00a64..4ccdf01 100644
--- a/linden/indra/llrender/llvertexprogramgl.cpp
+++ b/linden/indra/llrender/llvertexprogramgl.cpp
@@ -92,13 +92,13 @@ BOOL LLVertexProgramGL::load(const char * filename)
92 line_num++; 92 line_num++;
93 next_token = strchr(next_token, '\n'); 93 next_token = strchr(next_token, '\n');
94 } 94 }
95 char output[1024];
96 char bad_code[11]; 95 char bad_code[11];
97 strncpy(bad_code, text_buffer + error_pos, 10); 96 strncpy(bad_code, text_buffer + error_pos, 10);
98 bad_code[10] = '\0'; 97 bad_code[10] = '\0';
99 98
100 sprintf(output, "%s(%d): Vertex Program Error: %s at (%s)\n", filename, line_num, program_error_string, bad_code); 99 llerrs << filename << "(" << line_num << "): Vertex Program Error: "
101 gErrorStream << output << std::endl; 100 << program_error_string << " at (" << bad_code<< ")"
101 << llendl;
102 // clean up buffer 102 // clean up buffer
103 delete[] text_buffer; 103 delete[] text_buffer;
104 return FALSE; 104 return FALSE;
diff --git a/linden/indra/llrender/text_out.cpp b/linden/indra/llrender/text_out.cpp
index f4892b2..572ed03 100644
--- a/linden/indra/llrender/text_out.cpp
+++ b/linden/indra/llrender/text_out.cpp
@@ -52,7 +52,7 @@ typedef struct s_text_line
52// const LLFontGL *font; 52// const LLFontGL *font;
53// U8 color[3]; 53// U8 color[3];
54// U8 bg_color[3]; 54// U8 bg_color[3];
55 char line[MAX_TEXT_LINE_LENGTH]; 55 char line[MAX_TEXT_LINE_LENGTH]; /* Flawfinder: ignore */
56 S32 x, y; 56 S32 x, y;
57// ETextModifiers tm; 57// ETextModifiers tm;
58// ETextColorModifiers fcm; 58// ETextColorModifiers fcm;
@@ -84,7 +84,7 @@ void add_text(S32 x, S32 y, char *text) // , ETextModifiers tm, ETextColorModifi
84 84
85 TEXT_LINE *linep = &gTextLine[gNumTextLines++]; 85 TEXT_LINE *linep = &gTextLine[gNumTextLines++];
86 86
87 strcpy(linep->line, text); 87 strcpy(linep->line, text); /* Flawfinder: ignore */
88 linep->x = x; 88 linep->x = x;
89 linep->y = y; 89 linep->y = y;
90} 90}