aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender
diff options
context:
space:
mode:
authorArmin Weatherwax2010-09-07 13:41:02 +0200
committerArmin Weatherwax2010-09-23 15:42:40 +0200
commit087e15e89930d51c3964329befb273ae3b2d330d (patch)
tree684c49a772b0097ed88a25660e1fd3dd10b264cc /linden/indra/llrender
parentRobin Cornelius: fixes for building plugins on Linux 64bit (diff)
downloadmeta-impy-087e15e89930d51c3964329befb273ae3b2d330d.zip
meta-impy-087e15e89930d51c3964329befb273ae3b2d330d.tar.gz
meta-impy-087e15e89930d51c3964329befb273ae3b2d330d.tar.bz2
meta-impy-087e15e89930d51c3964329befb273ae3b2d330d.tar.xz
port of LL renderpipeline/Kirstens S19 pipeline for bridging to Viewer 2 texture system
Diffstat (limited to 'linden/indra/llrender')
-rw-r--r--linden/indra/llrender/CMakeLists.txt6
-rw-r--r--linden/indra/llrender/llcubemap.cpp17
-rw-r--r--linden/indra/llrender/llfont.cpp2
-rw-r--r--linden/indra/llrender/llfontgl.cpp6
-rw-r--r--linden/indra/llrender/llgl.cpp8
-rw-r--r--linden/indra/llrender/llgl.h31
-rw-r--r--linden/indra/llrender/llglslshader.cpp2
-rw-r--r--linden/indra/llrender/llimagegl.cpp451
-rw-r--r--linden/indra/llrender/llimagegl.h117
-rw-r--r--linden/indra/llrender/llrender.cpp64
-rw-r--r--linden/indra/llrender/llrendertarget.cpp57
-rw-r--r--linden/indra/llrender/llrendertarget.h1
-rw-r--r--linden/indra/llrender/lltextureatlas.cpp411
-rw-r--r--linden/indra/llrender/lltextureatlas.h92
-rw-r--r--linden/indra/llrender/llvertexbuffer.cpp72
15 files changed, 981 insertions, 356 deletions
diff --git a/linden/indra/llrender/CMakeLists.txt b/linden/indra/llrender/CMakeLists.txt
index 0bdb55f..e42f9ab 100644
--- a/linden/indra/llrender/CMakeLists.txt
+++ b/linden/indra/llrender/CMakeLists.txt
@@ -32,9 +32,9 @@ set(llrender_SOURCE_FILES
32 llgldbg.cpp 32 llgldbg.cpp
33 llglslshader.cpp 33 llglslshader.cpp
34 llimagegl.cpp 34 llimagegl.cpp
35 llpostprocess.cpp
36 llrendersphere.cpp 35 llrendersphere.cpp
37 llshadermgr.cpp 36 llshadermgr.cpp
37 lltextureatlas.cpp
38 llvertexbuffer.cpp 38 llvertexbuffer.cpp
39 ) 39 )
40 40
@@ -53,10 +53,10 @@ set(llrender_HEADER_FILES
53 llglstates.h 53 llglstates.h
54 llgltypes.h 54 llgltypes.h
55 llimagegl.h 55 llimagegl.h
56 llpostprocess.h
57 llrender.h 56 llrender.h
58 llrendersphere.h 57 llrendersphere.h
59 llshadermgr.h 58 llshadermgr.h
59 lltextureatlas.h
60 llvertexbuffer.h 60 llvertexbuffer.h
61 ) 61 )
62 62
@@ -81,6 +81,7 @@ if (SERVER AND NOT WINDOWS AND NOT DARWIN)
81 ${llrender_SOURCE_FILES} 81 ${llrender_SOURCE_FILES}
82 ${server_SOURCE_FILES} 82 ${server_SOURCE_FILES}
83 ) 83 )
84 add_dependencies(llrenderheadless prepare)
84else (SERVER AND NOT WINDOWS AND NOT DARWIN) 85else (SERVER AND NOT WINDOWS AND NOT DARWIN)
85 list(APPEND llrender_SOURCE_FILES 86 list(APPEND llrender_SOURCE_FILES
86 llgl.cpp 87 llgl.cpp
@@ -89,3 +90,4 @@ else (SERVER AND NOT WINDOWS AND NOT DARWIN)
89 ) 90 )
90endif (SERVER AND NOT WINDOWS AND NOT DARWIN) 91endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
91add_library (llrender ${llrender_SOURCE_FILES}) 92add_library (llrender ${llrender_SOURCE_FILES})
93add_dependencies(llrender prepare)
diff --git a/linden/indra/llrender/llcubemap.cpp b/linden/indra/llrender/llcubemap.cpp
index a5c677d..e0923e4 100644
--- a/linden/indra/llrender/llcubemap.cpp
+++ b/linden/indra/llrender/llcubemap.cpp
@@ -4,7 +4,7 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2002&license=viewergpl$ 5 * $LicenseInfo:firstyear=2002&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2002-2009, Linden Research, Inc. 7 * Copyright (c) 2002-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -63,6 +63,12 @@ LLCubeMap::LLCubeMap()
63 mTextureCoordStage(0), 63 mTextureCoordStage(0),
64 mMatrixStage(0) 64 mMatrixStage(0)
65{ 65{
66 mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
67 mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
68 mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
69 mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
70 mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
71 mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
66} 72}
67 73
68LLCubeMap::~LLCubeMap() 74LLCubeMap::~LLCubeMap()
@@ -75,13 +81,6 @@ void LLCubeMap::initGL()
75 81
76 if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) 82 if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
77 { 83 {
78 mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
79 mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
80 mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
81 mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
82 mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
83 mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
84
85 // Not initialized, do stuff. 84 // Not initialized, do stuff.
86 if (mImages[0].isNull()) 85 if (mImages[0].isNull())
87 { 86 {
@@ -94,7 +93,7 @@ void LLCubeMap::initGL()
94 mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE)); 93 mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE));
95 mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP); 94 mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
96 mRawImages[i] = new LLImageRaw(64, 64, 4); 95 mRawImages[i] = new LLImageRaw(64, 64, 4);
97 mImages[i]->createGLTexture(0, mRawImages[i], texname, TRUE); 96 mImages[i]->createGLTexture(0, mRawImages[i], texname);
98 97
99 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname); 98 gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
100 mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP); 99 mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
diff --git a/linden/indra/llrender/llfont.cpp b/linden/indra/llrender/llfont.cpp
index dd33128..da5eda0 100644
--- a/linden/indra/llrender/llfont.cpp
+++ b/linden/indra/llrender/llfont.cpp
@@ -81,7 +81,7 @@ LLFontManager::LLFontManager()
81 if (error) 81 if (error)
82 { 82 {
83 // Clean up freetype libs. 83 // Clean up freetype libs.
84 llerrs << "Freetype initialization failure!" << llendl; 84 llwarns << "Freetype initialization failure!" << llendl;
85 FT_Done_FreeType(gFTLibrary); 85 FT_Done_FreeType(gFTLibrary);
86 } 86 }
87} 87}
diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp
index 5d3d6a7..9d1f1d4 100644
--- a/linden/indra/llrender/llfontgl.cpp
+++ b/linden/indra/llrender/llfontgl.cpp
@@ -121,7 +121,7 @@ LLFontGL::LLFontGL()
121 121
122LLFontGL::LLFontGL(const LLFontGL &source) 122LLFontGL::LLFontGL(const LLFontGL &source)
123{ 123{
124 llerrs << "Not implemented!" << llendl; 124 llwarns << "Not implemented!" << llendl;
125} 125}
126 126
127LLFontGL::~LLFontGL() 127LLFontGL::~LLFontGL()
@@ -278,7 +278,7 @@ void LLFontGL::destroyGL()
278 278
279LLFontGL &LLFontGL::operator=(const LLFontGL &source) 279LLFontGL &LLFontGL::operator=(const LLFontGL &source)
280{ 280{
281 llerrs << "Not implemented" << llendl; 281 llwarns << "Not implemented" << llendl;
282 return *this; 282 return *this;
283} 283}
284 284
@@ -584,7 +584,7 @@ S32 LLFontGL::render(const LLWString &wstr,
584 const LLFontGlyphInfo* fgi= getGlyphInfo(wch); 584 const LLFontGlyphInfo* fgi= getGlyphInfo(wch);
585 if (!fgi) 585 if (!fgi)
586 { 586 {
587 llerrs << "Missing Glyph Info" << llendl; 587 llwarns << "Missing Glyph Info" << llendl;
588 break; 588 break;
589 } 589 }
590 // Per-glyph bitmap texture. 590 // Per-glyph bitmap texture.
diff --git a/linden/indra/llrender/llgl.cpp b/linden/indra/llrender/llgl.cpp
index 61194c4..be3ed96 100644
--- a/linden/indra/llrender/llgl.cpp
+++ b/linden/indra/llrender/llgl.cpp
@@ -59,11 +59,13 @@
59BOOL gDebugGL = FALSE; 59BOOL gDebugGL = FALSE;
60BOOL gClothRipple = FALSE; 60BOOL gClothRipple = FALSE;
61BOOL gNoRender = FALSE; 61BOOL gNoRender = FALSE;
62BOOL gGLActive = FALSE;
62LLMatrix4 gGLObliqueProjectionInverse; 63LLMatrix4 gGLObliqueProjectionInverse;
63 64
64#define LL_GL_NAME_POOLING 0 65#define LL_GL_NAME_POOLING 0
65 66
66LLGLNamePool::pool_list_t LLGLNamePool::sInstances; 67LLGLNamePool::pool_list_t LLGLNamePool::sInstances;
68std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
67 69
68#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS 70#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
69// ATI prototypes 71// ATI prototypes
@@ -1001,7 +1003,7 @@ void assert_glerror()
1001 1003
1002 if (quit) 1004 if (quit)
1003 { 1005 {
1004 llerrs << "One or more unhandled GL errors." << llendl; 1006 llwarns << "One or more unhandled GL errors." << llendl;
1005 } 1007 }
1006} 1008}
1007 1009
@@ -1695,11 +1697,11 @@ void LLGLNamePool::release(GLuint name)
1695 } 1697 }
1696 else 1698 else
1697 { 1699 {
1698 llerrs << "Attempted to release a pooled name that is not in use!" << llendl; 1700 llwarns << "Attempted to release a pooled name that is not in use!" << llendl;
1699 } 1701 }
1700 } 1702 }
1701 } 1703 }
1702 llerrs << "Attempted to release a non pooled name!" << llendl; 1704 llwarns << "Attempted to release a non pooled name!" << llendl;
1703#else 1705#else
1704 releaseName(name); 1706 releaseName(name);
1705#endif 1707#endif
diff --git a/linden/indra/llrender/llgl.h b/linden/indra/llrender/llgl.h
index 00ff1e2..88552ce 100644
--- a/linden/indra/llrender/llgl.h
+++ b/linden/indra/llrender/llgl.h
@@ -358,6 +358,35 @@ protected:
358 virtual void releaseName(GLuint name) = 0; 358 virtual void releaseName(GLuint name) = 0;
359}; 359};
360 360
361/*
362 Interface for objects that need periodic GL updates applied to them.
363 Used to synchronize GL updates with GL thread.
364*/
365class LLGLUpdate
366{
367public:
368
369 static std::list<LLGLUpdate*> sGLQ;
370
371 BOOL mInQ;
372 LLGLUpdate()
373 : mInQ(FALSE)
374 {
375 }
376 virtual ~LLGLUpdate()
377 {
378 if (mInQ)
379 {
380 std::list<LLGLUpdate*>::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this);
381 if (iter != sGLQ.end())
382 {
383 sGLQ.erase(iter);
384 }
385 }
386 }
387 virtual void updateGL() = 0;
388};
389
361extern LLMatrix4 gGLObliqueProjectionInverse; 390extern LLMatrix4 gGLObliqueProjectionInverse;
362 391
363#include "llglstates.h" 392#include "llglstates.h"
@@ -376,4 +405,6 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
376 405
377extern BOOL gClothRipple; 406extern BOOL gClothRipple;
378extern BOOL gNoRender; 407extern BOOL gNoRender;
408extern BOOL gGLActive;
409
379#endif // LL_LLGL_H 410#endif // LL_LLGL_H
diff --git a/linden/indra/llrender/llglslshader.cpp b/linden/indra/llrender/llglslshader.cpp
index 08d6548..18974a7 100644
--- a/linden/indra/llrender/llglslshader.cpp
+++ b/linden/indra/llrender/llglslshader.cpp
@@ -408,7 +408,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
408 { 408 {
409 if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode) 409 if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
410 { 410 {
411 llerrs << "Texture channel " << index << " texture type corrupted." << llendl; 411 llwarns << "Texture channel " << index << " texture type corrupted." << llendl;
412 } 412 }
413 gGL.getTexUnit(index)->disable(); 413 gGL.getTexUnit(index)->disable();
414 } 414 }
diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp
index 7cd4dd7..1bddd49 100644
--- a/linden/indra/llrender/llimagegl.cpp
+++ b/linden/indra/llrender/llimagegl.cpp
@@ -43,6 +43,8 @@
43#include "llmath.h" 43#include "llmath.h"
44#include "llgl.h" 44#include "llgl.h"
45#include "llrender.h" 45#include "llrender.h"
46#include "lltextureatlas.h"
47
46//---------------------------------------------------------------------------- 48//----------------------------------------------------------------------------
47 49
48const F32 MIN_TEXTURE_LIFETIME = 10.f; 50const F32 MIN_TEXTURE_LIFETIME = 10.f;
@@ -56,19 +58,17 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
56S32 LLImageGL::sBoundTextureMemoryInBytes = 0; 58S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
57S32 LLImageGL::sCurBoundTextureMemory = 0; 59S32 LLImageGL::sCurBoundTextureMemory = 0;
58S32 LLImageGL::sCount = 0; 60S32 LLImageGL::sCount = 0;
61std::list<U32> LLImageGL::sDeadTextureList;
59 62
60BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; 63BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
61F32 LLImageGL::sLastFrameTime = 0.f; 64F32 LLImageGL::sLastFrameTime = 0.f;
62BOOL LLImageGL::sAllowReadBackRaw = FALSE ; 65BOOL LLImageGL::sUseTextureAtlas = FALSE ; // render-pipeline KL
63 66
64std::set<LLImageGL*> LLImageGL::sImageList; 67std::set<LLImageGL*> LLImageGL::sImageList;
65 68
66//**************************************************************************************************** 69#if !LL_RELEASE_FOR_DOWNLOAD
67//The below for texture auditing use only
68//****************************************************************************************************
69//----------------------- 70//-----------------------
70//debug use 71//debug use
71BOOL gAuditTexture = FALSE ;
72#define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048 72#define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048
73std::vector<S32> LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ; 73std::vector<S32> LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
74std::vector<S32> LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ; 74std::vector<S32> LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
@@ -76,15 +76,8 @@ std::vector<S32> LLImageGL::sTextureCurBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
76S32 LLImageGL::sCurTexSizeBar = -1 ; 76S32 LLImageGL::sCurTexSizeBar = -1 ;
77S32 LLImageGL::sCurTexPickSize = -1 ; 77S32 LLImageGL::sCurTexPickSize = -1 ;
78LLPointer<LLImageGL> LLImageGL::sDefaultTexturep = NULL; 78LLPointer<LLImageGL> LLImageGL::sDefaultTexturep = NULL;
79S32 LLImageGL::sMaxCatagories = 1 ;
80
81std::vector<S32> LLImageGL::sTextureMemByCategory;
82std::vector<S32> LLImageGL::sTextureMemByCategoryBound ;
83std::vector<S32> LLImageGL::sTextureCurMemByCategoryBound ;
84//------------------------ 79//------------------------
85//**************************************************************************************************** 80#endif
86//End for texture auditing use only
87//****************************************************************************************************
88 81
89//************************************************************************************** 82//**************************************************************************************
90//below are functions for debug use 83//below are functions for debug use
@@ -110,9 +103,12 @@ void LLImageGL::checkTexSize() const
110 { 103 {
111 GLint texname; 104 GLint texname;
112 glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname); 105 glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
106 BOOL error = FALSE;
113 if (texname != mTexName) 107 if (texname != mTexName)
114 { 108 {
115 llerrs << "Invalid texture bound!" << llendl; 109
110 llwarns << "Invalid texture bound!" << llendl;
111
116 } 112 }
117 stop_glerror() ; 113 stop_glerror() ;
118 LLGLint x = 0, y = 0 ; 114 LLGLint x = 0, y = 0 ;
@@ -125,7 +121,15 @@ void LLImageGL::checkTexSize() const
125 } 121 }
126 if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel)) 122 if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
127 { 123 {
128 llerrs << "wrong texture size and discard level!" << llendl ; 124 error = TRUE;
125
126 llwarns << "wrong texture size and discard level!" << llendl;
127
128 }
129
130 if (error)
131 {
132 llwarns << "LLImageGL::checkTexSize failed." << llendl;
129 } 133 }
130 } 134 }
131} 135}
@@ -133,20 +137,6 @@ void LLImageGL::checkTexSize() const
133//************************************************************************************** 137//**************************************************************************************
134 138
135//---------------------------------------------------------------------------- 139//----------------------------------------------------------------------------
136//static
137void LLImageGL::initClass(S32 num_catagories)
138{
139 sMaxCatagories = num_catagories ;
140
141 sTextureMemByCategory.resize(sMaxCatagories);
142 sTextureMemByCategoryBound.resize(sMaxCatagories) ;
143 sTextureCurMemByCategoryBound.resize(sMaxCatagories) ;
144}
145
146//static
147void LLImageGL::cleanupClass()
148{
149}
150 140
151//static 141//static
152S32 LLImageGL::dataFormatBits(S32 dataformat) 142S32 LLImageGL::dataFormatBits(S32 dataformat)
@@ -165,7 +155,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
165 case GL_RGBA: return 32; 155 case GL_RGBA: return 32;
166 case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac 156 case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
167 default: 157 default:
168 llerrs << "LLImageGL::Unknown format: " << dataformat << llendl; 158 llwarns << "LLImageGL::Unknown format: " << dataformat << llendl;
169 return 0; 159 return 0;
170 } 160 }
171} 161}
@@ -200,7 +190,7 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
200 case GL_RGBA: return 4; 190 case GL_RGBA: return 4;
201 case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac 191 case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac
202 default: 192 default:
203 llerrs << "LLImageGL::Unknown format: " << dataformat << llendl; 193 llwarns << "LLImageGL::Unknown format: " << dataformat << llendl;
204 return 0; 194 return 0;
205 } 195 }
206} 196}
@@ -214,43 +204,25 @@ void LLImageGL::updateStats(F32 current_time)
214 sBoundTextureMemoryInBytes = sCurBoundTextureMemory; 204 sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
215 sCurBoundTextureMemory = 0; 205 sCurBoundTextureMemory = 0;
216 206
217 if(gAuditTexture) 207#if !LL_RELEASE_FOR_DOWNLOAD
208 for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++)
218 { 209 {
219 for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++) 210 sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ;
220 { 211 sTextureCurBoundCounter[i] = 0 ;
221 sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ;
222 sTextureCurBoundCounter[i] = 0 ;
223 }
224 for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++)
225 {
226 sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ;
227 sTextureCurMemByCategoryBound[i] = 0 ;
228 }
229 } 212 }
213#endif
230} 214}
231 215
232//static 216//static
233S32 LLImageGL::updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) 217//#if !LL_RELEASE_FOR_DOWNLOAD
234{ 218//S32 LLImageGL::updateBoundTexMem(const S32 delta, const S32 size)
235 if(gAuditTexture) 219//{
236 { 220// sTextureCurBoundCounter[getTextureCounterIndex(size)]++ ;
237 sTextureCurBoundCounter[getTextureCounterIndex(size)]++ ; 221//#else
238 sTextureCurMemByCategoryBound[category] += delta ; 222S32 LLImageGL::updateBoundTexMem(const S32 delta)
239 } 223{
240 224//#endif
241 LLImageGL::sCurBoundTextureMemory += delta ; 225 LLImageGL::sCurBoundTextureMemory += delta;
242 return LLImageGL::sCurBoundTextureMemory;
243}
244
245S32 LLImageGL::updateBoundTexMem()const
246{
247 if(gAuditTexture)
248 {
249 sTextureCurBoundCounter[getTextureCounterIndex(mTextureMemory / mComponents)]++ ;
250 sTextureCurMemByCategoryBound[mCategory] += mTextureMemory ;
251 }
252
253 LLImageGL::sCurBoundTextureMemory += mTextureMemory ;
254 return LLImageGL::sCurBoundTextureMemory; 226 return LLImageGL::sCurBoundTextureMemory;
255} 227}
256 228
@@ -264,7 +236,6 @@ void LLImageGL::destroyGL(BOOL save_state)
264 gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); 236 gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
265 } 237 }
266 238
267 sAllowReadBackRaw = true ;
268 for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); 239 for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
269 iter != sImageList.end(); iter++) 240 iter != sImageList.end(); iter++)
270 { 241 {
@@ -284,7 +255,7 @@ void LLImageGL::destroyGL(BOOL save_state)
284 stop_glerror(); 255 stop_glerror();
285 } 256 }
286 } 257 }
287 sAllowReadBackRaw = false ; 258// sAllowReadBackRaw = false ;
288} 259}
289 260
290//static 261//static
@@ -296,13 +267,13 @@ void LLImageGL::restoreGL()
296 LLImageGL* glimage = *iter; 267 LLImageGL* glimage = *iter;
297 if(glimage->getTexName()) 268 if(glimage->getTexName())
298 { 269 {
299 llerrs << "tex name is not 0." << llendl ; 270 llwarns << "tex name is not 0." << llendl ;
300 } 271 }
301 if (glimage->mSaveData.notNull()) 272 if (glimage->mSaveData.notNull())
302 { 273 {
303 if (glimage->getComponents() && glimage->mSaveData->getComponents()) 274 if (glimage->getComponents() && glimage->mSaveData->getComponents())
304 { 275 {
305 glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory()); 276 glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData);
306 stop_glerror(); 277 stop_glerror();
307 } 278 }
308 glimage->mSaveData = NULL; // deletes data 279 glimage->mSaveData = NULL; // deletes data
@@ -384,7 +355,7 @@ void LLImageGL::init(BOOL usemipmaps)
384 mTextureState = NO_DELETE ; 355 mTextureState = NO_DELETE ;
385 mTextureMemory = 0; 356 mTextureMemory = 0;
386 mLastBindTime = 0.f; 357 mLastBindTime = 0.f;
387 358
388 mTarget = GL_TEXTURE_2D; 359 mTarget = GL_TEXTURE_2D;
389 mBindTarget = LLTexUnit::TT_TEXTURE; 360 mBindTarget = LLTexUnit::TT_TEXTURE;
390 mUseMipMaps = usemipmaps; 361 mUseMipMaps = usemipmaps;
@@ -411,9 +382,12 @@ void LLImageGL::init(BOOL usemipmaps)
411 mHasExplicitFormat = FALSE; 382 mHasExplicitFormat = FALSE;
412 383
413 mGLTextureCreated = FALSE ; 384 mGLTextureCreated = FALSE ;
414
415 mIsMask = FALSE; 385 mIsMask = FALSE;
416 mCategory = -1 ; 386// mCategory = -1 ;
387 mCanAddToAtlas = TRUE ;
388 mDiscardLevelInAtlas = -1 ;
389 mTexelsInAtlas = 0 ;
390 mTexelsInGLTexture = 0 ;
417} 391}
418 392
419void LLImageGL::cleanup() 393void LLImageGL::cleanup()
@@ -455,7 +429,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
455 // Check if dimensions are a power of two! 429 // Check if dimensions are a power of two!
456 if (!checkSize(width,height)) 430 if (!checkSize(width,height))
457 { 431 {
458 llerrs << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl; 432 llwarns << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl;
459 } 433 }
460 434
461 if (mTexName) 435 if (mTexName)
@@ -513,10 +487,6 @@ void LLImageGL::dump()
513} 487}
514 488
515//---------------------------------------------------------------------------- 489//----------------------------------------------------------------------------
516void LLImageGL::forceUpdateBindStats(void) const
517{
518 mLastBindTime = sLastFrameTime;
519}
520 490
521void LLImageGL::updateBindStats(void) const 491void LLImageGL::updateBindStats(void) const
522{ 492{
@@ -530,8 +500,12 @@ void LLImageGL::updateBindStats(void) const
530 { 500 {
531 // we haven't accounted for this texture yet this frame 501 // we haven't accounted for this texture yet this frame
532 sUniqueCount++; 502 sUniqueCount++;
533 503
534 updateBoundTexMem(); 504//#if !LL_RELEASE_FOR_DOWNLOAD
505// updateBoundTexMem(mTextureMemory, getWidth(mCurrentDiscardLevel) * getHeight(mCurrentDiscardLevel)) ;
506//#else
507 updateBoundTexMem(mTextureMemory);
508//#endif
535 mLastBindTime = sLastFrameTime; 509 mLastBindTime = sLastFrameTime;
536 } 510 }
537 } 511 }
@@ -544,7 +518,7 @@ bool LLImageGL::bindError(const S32 stage) const
544} 518}
545 519
546//virtual 520//virtual
547bool LLImageGL::bindDefaultImage(const S32 stage) 521bool LLImageGL::bindDefaultImage(const S32 stage) const
548{ 522{
549 return false; 523 return false;
550} 524}
@@ -583,6 +557,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
583void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) 557void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
584{ 558{
585// LLFastTimer t1(LLFastTimer::FTM_TEMP1); 559// LLFastTimer t1(LLFastTimer::FTM_TEMP1);
560 llpushcallstacks ;
586 bool is_compressed = false; 561 bool is_compressed = false;
587 if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) 562 if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
588 { 563 {
@@ -590,7 +565,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
590 } 565 }
591 566
592// LLFastTimer t2(LLFastTimer::FTM_TEMP2); 567// LLFastTimer t2(LLFastTimer::FTM_TEMP2);
593 gGL.getTexUnit(0)->bind(this); 568 llverify(gGL.getTexUnit(0)->bind(this, false, true));
594 569
595 if (mUseMipMaps) 570 if (mUseMipMaps)
596 { 571 {
@@ -753,7 +728,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
753 } 728 }
754 else 729 else
755 { 730 {
756 llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; 731 llwarns << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;
757 } 732 }
758 mHasMipMaps = true; 733 mHasMipMaps = true;
759 } 734 }
@@ -795,10 +770,63 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
795 } 770 }
796 stop_glerror(); 771 stop_glerror();
797 mGLTextureCreated = true; 772 mGLTextureCreated = true;
773 llpushcallstacks ;
774}
775
776BOOL LLImageGL::canAddToAtlas()
777{
778 return sUseTextureAtlas && mCanAddToAtlas ;
779}
780
781BOOL LLImageGL::addToAtlas(const LLImageRaw* raw_image, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row)
782{
783 if(!atlasp)
784 {
785 return FALSE ;
786 }
787
788 preAddToAtlas(raw_image->getWidth()) ;
789 LLGLuint tex_name = atlasp->insertSubTexture(raw_image, slot_col, slot_row);
790 postAddToAtlas() ;
791
792 if(tex_name > 0) //successfully added to atlas
793 {
794 //gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
795 //gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
796 gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
797 return TRUE ;
798 }
799
800 return FALSE ;
801}
802
803void LLImageGL::preAddToAtlas(S32 data_width)
804{
805 glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width);
806 stop_glerror();
807
808 if(mFormatSwapBytes)
809 {
810 glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
811 stop_glerror();
812 }
798} 813}
799 814
800BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) 815void LLImageGL::postAddToAtlas()
801{ 816{
817 if(mFormatSwapBytes)
818 {
819 glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
820 stop_glerror();
821 }
822
823 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
824 stop_glerror();
825}
826
827BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
828{
829 llpushcallstacks ;
802 if (!width || !height) 830 if (!width || !height)
803 { 831 {
804 return TRUE; 832 return TRUE;
@@ -814,8 +842,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
814 return FALSE; 842 return FALSE;
815 } 843 }
816 844
817 // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture. 845 if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
818 if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
819 { 846 {
820 setImage(datap, FALSE); 847 setImage(datap, FALSE);
821 } 848 }
@@ -824,7 +851,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
824 if (mUseMipMaps) 851 if (mUseMipMaps)
825 { 852 {
826 dump(); 853 dump();
827 llerrs << "setSubImage called with mipmapped image (not supported)" << llendl; 854 llwarns << "setSubImage called with mipmapped image (not supported)" << llendl;
828 } 855 }
829 llassert_always(mCurrentDiscardLevel == 0); 856 llassert_always(mCurrentDiscardLevel == 0);
830 llassert_always(x_pos >= 0 && y_pos >= 0); 857 llassert_always(x_pos >= 0 && y_pos >= 0);
@@ -833,7 +860,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
833 (y_pos + height) > getHeight()) 860 (y_pos + height) > getHeight())
834 { 861 {
835 dump(); 862 dump();
836 llerrs << "Subimage not wholly in target image!" 863 llwarns << "Subimage not wholly in target image!"
837 << " x_pos " << x_pos 864 << " x_pos " << x_pos
838 << " y_pos " << y_pos 865 << " y_pos " << y_pos
839 << " width " << width 866 << " width " << width
@@ -847,7 +874,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
847 (y_pos + height) > data_height) 874 (y_pos + height) > data_height)
848 { 875 {
849 dump(); 876 dump();
850 llerrs << "Subimage not wholly in source image!" 877 llwarns << "Subimage not wholly in source image!"
851 << " x_pos " << x_pos 878 << " x_pos " << x_pos
852 << " y_pos " << y_pos 879 << " y_pos " << y_pos
853 << " width " << width 880 << " width " << width
@@ -870,7 +897,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
870 datap += (y_pos * data_width + x_pos) * getComponents(); 897 datap += (y_pos * data_width + x_pos) * getComponents();
871 // Update the GL texture 898 // Update the GL texture
872 BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName); 899 BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName);
873 if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl; 900 if (!res) llwarns << "LLImageGL::setSubImage(): bindTexture failed" << llendl;
874 stop_glerror(); 901 stop_glerror();
875 902
876 glTexSubImage2D(mTarget, 0, x_pos, y_pos, 903 glTexSubImage2D(mTarget, 0, x_pos, y_pos,
@@ -888,12 +915,13 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
888 stop_glerror(); 915 stop_glerror();
889 mGLTextureCreated = true; 916 mGLTextureCreated = true;
890 } 917 }
918 llpushcallstacks ;
891 return TRUE; 919 return TRUE;
892} 920}
893 921
894BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) 922BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
895{ 923{
896 return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update); 924 return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height);
897} 925}
898 926
899// Copy sub image from frame buffer 927// Copy sub image from frame buffer
@@ -901,7 +929,6 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
901{ 929{
902 if (gGL.getTexUnit(0)->bind(this, false, true)) 930 if (gGL.getTexUnit(0)->bind(this, false, true))
903 { 931 {
904 //checkTexSize() ;
905 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); 932 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
906 mGLTextureCreated = true; 933 mGLTextureCreated = true;
907 stop_glerror(); 934 stop_glerror();
@@ -922,13 +949,17 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
922// static 949// static
923void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) 950void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
924{ 951{
925 glDeleteTextures(numTextures, (GLuint*)textures); 952 for (S32 i = 0; i < numTextures; i++)
953 {
954 sDeadTextureList.push_back(textures[i]);
955 }
926} 956}
927 957
928// static 958// static
929void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels) 959void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
930{ 960{
931 glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels); 961 glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
962 stop_glerror();
932} 963}
933 964
934//create an empty GL texture: just create a texture name 965//create an empty GL texture: just create a texture name
@@ -955,21 +986,26 @@ BOOL LLImageGL::createGLTexture()
955 stop_glerror(); 986 stop_glerror();
956 if (!mTexName) 987 if (!mTexName)
957 { 988 {
958 llerrs << "LLImageGL::createGLTexture failed to make an empty texture" << llendl; 989 llwarns << "LLImageGL::createGLTexture failed to make an empty texture" << llendl;
959 } 990 }
960 991
961 return TRUE ; 992 return TRUE ;
962} 993}
963 994
964BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category) 995BOOL LLImageGL::createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imageraw, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row)
965{ 996{
997 if(!sUseTextureAtlas)
998 {
999 return FALSE ;
1000 }
1001
966 if (gGLManager.mIsDisabled) 1002 if (gGLManager.mIsDisabled)
967 { 1003 {
968 llwarns << "Trying to create a texture while GL is disabled!" << llendl; 1004 llwarns << "Trying to create a texture while GL is disabled!" << llendl;
969 return FALSE; 1005 return FALSE;
970 } 1006 }
971 1007
972 mGLTextureCreated = false ; 1008 // mGLTextureCreated = false ; // KL not in SD
973 llassert(gGLManager.mInited); 1009 llassert(gGLManager.mInited);
974 stop_glerror(); 1010 stop_glerror();
975 1011
@@ -981,10 +1017,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
981 discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); 1017 discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
982 1018
983 // Actual image width/height = raw image width/height * 2^discard_level 1019 // Actual image width/height = raw image width/height * 2^discard_level
984 S32 raw_w = imageraw->getWidth() ; 1020 S32 w = imageraw->getWidth() << discard_level;
985 S32 raw_h = imageraw->getHeight() ; 1021 S32 h = imageraw->getHeight() << discard_level;
986 S32 w = raw_w << discard_level;
987 S32 h = raw_h << discard_level;
988 1022
989 // setSize may call destroyGLTexture if the size does not match 1023 // setSize may call destroyGLTexture if the size does not match
990 setSize(w, h, imageraw->getComponents()); 1024 setSize(w, h, imageraw->getComponents());
@@ -1016,27 +1050,87 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
1016 mFormatType = GL_UNSIGNED_BYTE; 1050 mFormatType = GL_UNSIGNED_BYTE;
1017 break; 1051 break;
1018 default: 1052 default:
1019 LL_DEBUGS("Openjpeg") << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL; 1053 llwarns << "Bad number of components for texture: " << (U32)getComponents() << llendl;
1020 to_create = false;
1021 break;
1022 } 1054 }
1023 } 1055 }
1024 1056
1025 if(!to_create) //not create a gl texture 1057 if(addToAtlas(imageraw, atlasp, slot_col, slot_row))
1026 { 1058 {
1027 destroyGLTexture(); 1059 // destroyGLTexture();
1028 mCurrentDiscardLevel = discard_level; 1060 mCurrentDiscardLevel = discard_level;
1061 mDiscardLevelInAtlas = discard_level;
1062 mTexelsInAtlas = imageraw->getWidth() * imageraw->getHeight() ;
1029 mLastBindTime = sLastFrameTime; 1063 mLastBindTime = sLastFrameTime;
1064 mGLTextureCreated = false ;
1030 return TRUE ; 1065 return TRUE ;
1031 } 1066 }
1067 return FALSE ;
1068}
1069
1070BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/)
1071{
1072 if (gGLManager.mIsDisabled)
1073 {
1074 llwarns << "Trying to create a texture while GL is disabled!" << llendl;
1075 return FALSE;
1076 }
1077
1078 mGLTextureCreated = false ;
1079 llassert(gGLManager.mInited);
1080 stop_glerror();
1081
1082 if (discard_level < 0)
1083 {
1084 llassert(mCurrentDiscardLevel >= 0);
1085 discard_level = mCurrentDiscardLevel;
1086 }
1087 discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
1088
1089 // Actual image width/height = raw image width/height * 2^discard_level
1090 S32 w = imageraw->getWidth() << discard_level;
1091 S32 h = imageraw->getHeight() << discard_level;
1092
1093 // setSize may call destroyGLTexture if the size does not match
1094 setSize(w, h, imageraw->getComponents());
1095
1096 if( !mHasExplicitFormat )
1097 {
1098 switch (mComponents)
1099 {
1100 case 1:
1101 // Use luminance alpha (for fonts)
1102 mFormatInternal = GL_LUMINANCE8;
1103 mFormatPrimary = GL_LUMINANCE;
1104 mFormatType = GL_UNSIGNED_BYTE;
1105 break;
1106 case 2:
1107 // Use luminance alpha (for fonts)
1108 mFormatInternal = GL_LUMINANCE8_ALPHA8;
1109 mFormatPrimary = GL_LUMINANCE_ALPHA;
1110 mFormatType = GL_UNSIGNED_BYTE;
1111 break;
1112 case 3:
1113 mFormatInternal = GL_RGB8;
1114 mFormatPrimary = GL_RGB;
1115 mFormatType = GL_UNSIGNED_BYTE;
1116 break;
1117 case 4:
1118 mFormatInternal = GL_RGBA8;
1119 mFormatPrimary = GL_RGBA;
1120 mFormatType = GL_UNSIGNED_BYTE;
1121 break;
1122 default:
1123 llwarns << "Bad number of components for texture: " << (U32)getComponents() << llendl;
1124 }
1125 }
1032 1126
1033 mCategory = category ;
1034 const U8* rawdata = imageraw->getData(); 1127 const U8* rawdata = imageraw->getData();
1035 return createGLTexture(discard_level, rawdata, FALSE, usename); 1128 return createGLTexture(discard_level, rawdata, FALSE, usename);
1036} 1129}
1037 1130
1038BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) 1131BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
1039{ 1132{
1133 llpushcallstacks ;
1040 llassert(data_in); 1134 llassert(data_in);
1041 1135
1042 if (discard_level < 0) 1136 if (discard_level < 0)
@@ -1073,7 +1167,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
1073 } 1167 }
1074 if (!mTexName) 1168 if (!mTexName)
1075 { 1169 {
1076 llerrs << "LLImageGL::createGLTexture failed to make texture" << llendl; 1170 llwarns << "LLImageGL::createGLTexture failed to make texture" << llendl;
1077 } 1171 }
1078 1172
1079 if (mUseMipMaps) 1173 if (mUseMipMaps)
@@ -1104,30 +1198,30 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
1104 if (old_name != 0) 1198 if (old_name != 0)
1105 { 1199 {
1106 sGlobalTextureMemoryInBytes -= mTextureMemory; 1200 sGlobalTextureMemoryInBytes -= mTextureMemory;
1107 1201#if !LL_RELEASE_FOR_DOWNLOAD
1108 if(gAuditTexture) 1202 decTextureCounter(mTextureMemory / mComponents) ;
1109 { 1203#endif
1110 decTextureCounter() ;
1111 }
1112 1204
1113 LLImageGL::deleteTextures(1, &old_name); 1205 LLImageGL::deleteTextures(1, &old_name);
1114
1115 stop_glerror(); 1206 stop_glerror();
1116 } 1207 }
1117 1208
1118 mTextureMemory = getMipBytes(discard_level); 1209 mTextureMemory = getMipBytes(discard_level);
1119 sGlobalTextureMemoryInBytes += mTextureMemory; 1210 sGlobalTextureMemoryInBytes += mTextureMemory;
1211 mTexelsInGLTexture = getWidth() * getHeight() ;
1212
1213#if !LL_RELEASE_FOR_DOWNLOAD
1214 incTextureCounter(mTextureMemory / mComponents) ;
1215#endif
1120 setActive() ; 1216 setActive() ;
1121 1217
1122 if(gAuditTexture)
1123 {
1124 incTextureCounter() ;
1125 }
1126 // mark this as bound at this point, so we don't throw it out immediately 1218 // mark this as bound at this point, so we don't throw it out immediately
1127 mLastBindTime = sLastFrameTime; 1219 mLastBindTime = sLastFrameTime;
1220
1221 llpushcallstacks ;
1128 return TRUE; 1222 return TRUE;
1129} 1223}
1130#if 0 1224
1131BOOL LLImageGL::setDiscardLevel(S32 discard_level) 1225BOOL LLImageGL::setDiscardLevel(S32 discard_level)
1132{ 1226{
1133 llassert(discard_level >= 0); 1227 llassert(discard_level >= 0);
@@ -1149,7 +1243,7 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level)
1149 { 1243 {
1150 // larger image 1244 // larger image
1151 dump(); 1245 dump();
1152 llerrs << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl; 1246 llwarns << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl;
1153 return FALSE; 1247 return FALSE;
1154 } 1248 }
1155 else if (mUseMipMaps) 1249 else if (mUseMipMaps)
@@ -1174,19 +1268,30 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level)
1174 { 1268 {
1175#if !LL_LINUX && !LL_SOLARIS 1269#if !LL_LINUX && !LL_SOLARIS
1176 // *FIX: This should not be skipped for the linux client. 1270 // *FIX: This should not be skipped for the linux client.
1177 llerrs << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl; 1271 llwarns << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl;
1178#endif 1272#endif
1179 return FALSE; 1273 return FALSE;
1180 } 1274 }
1181} 1275}
1182#endif 1276
1277BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents)
1278{
1279 assert_glerror();
1280 S32 gl_discard = discard_level - mCurrentDiscardLevel;
1281 LLGLint glwidth = 0;
1282 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth);
1283 LLGLint glheight = 0;
1284 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_HEIGHT, (GLint*)&glheight);
1285 LLGLint glcomponents = 0 ;
1286 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&glcomponents);
1287 assert_glerror();
1288
1289 return glwidth >= image_width && glheight >= image_height && (GL_RGB8 == glcomponents || GL_RGBA8 == glcomponents) ;
1290}
1183 1291
1184BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) 1292BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok)
1185{ 1293{
1186 // VWR-13505 : Merov : Allow gl texture read back so save texture works again (temporary) 1294 llpushcallstacks ;
1187 //llassert_always(sAllowReadBackRaw) ;
1188 //llerrs << "should not call this function!" << llendl ;
1189
1190 if (discard_level < 0) 1295 if (discard_level < 0)
1191 { 1296 {
1192 discard_level = mCurrentDiscardLevel; 1297 discard_level = mCurrentDiscardLevel;
@@ -1291,41 +1396,48 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1291 return FALSE ; 1396 return FALSE ;
1292 } 1397 }
1293 //----------------------------------------------------------------------------------------------- 1398 //-----------------------------------------------------------------------------------------------
1294 1399 llpushcallstacks ;
1295 return TRUE ; 1400 return TRUE ;
1296} 1401}
1297 1402
1298void LLImageGL::destroyGLTexture() 1403void LLImageGL::deleteDeadTextures()
1299{ 1404{
1300 if (mTexName != 0) 1405 while (!sDeadTextureList.empty())
1301 { 1406 {
1302 stop_glerror(); 1407 GLuint tex = sDeadTextureList.front();
1303 1408 sDeadTextureList.pop_front();
1304 for (int i = 0; i < gGLManager.mNumTextureUnits; i++) 1409 for (int i = 0; i < gGLManager.mNumTextureUnits; i++)
1305 { 1410 {
1306 if (sCurrentBoundTextures[i] == mTexName) 1411 if (sCurrentBoundTextures[i] == tex)
1307 { 1412 {
1308 gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE); 1413 gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE);
1309 stop_glerror(); 1414 stop_glerror();
1310 } 1415 }
1311 } 1416 }
1312 1417
1418 glDeleteTextures(1, &tex);
1419 stop_glerror();
1420 }
1421}
1422
1423void LLImageGL::destroyGLTexture()
1424{
1425 if (mTexName != 0)
1426 {
1313 if(mTextureMemory) 1427 if(mTextureMemory)
1314 { 1428 {
1315 if(gAuditTexture) 1429#if !LL_RELEASE_FOR_DOWNLOAD
1316 { 1430 decTextureCounter(mTextureMemory / mComponents) ;
1317 decTextureCounter() ; 1431#endif
1318 }
1319 sGlobalTextureMemoryInBytes -= mTextureMemory; 1432 sGlobalTextureMemoryInBytes -= mTextureMemory;
1320 mTextureMemory = 0; 1433 mTextureMemory = 0;
1321 } 1434 }
1322 1435
1323 LLImageGL::deleteTextures(1, &mTexName); 1436 LLImageGL::deleteTextures(1, &mTexName);
1324 mTextureState = DELETED ; 1437 mTextureState = DELETED ;
1325 mTexName = 0; 1438 mTexName = 0;
1326 mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. 1439 mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
1327 mGLTextureCreated = FALSE ; 1440 mGLTextureCreated = FALSE ;
1328 stop_glerror();
1329 } 1441 }
1330} 1442}
1331 1443
@@ -1354,12 +1466,12 @@ void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
1354 mFilterOption = option; 1466 mFilterOption = option;
1355 } 1467 }
1356 1468
1357 if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) 1469 if (mTexName != 0 && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
1358 { 1470 {
1359 gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option); 1471 gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option);
1360 mTexOptionsDirty = false; 1472 mTexOptionsDirty = false;
1473 stop_glerror();
1361 } 1474 }
1362 stop_glerror();
1363} 1475}
1364 1476
1365BOOL LLImageGL::getIsResident(BOOL test_now) 1477BOOL LLImageGL::getIsResident(BOOL test_now)
@@ -1435,11 +1547,6 @@ S32 LLImageGL::getMipBytes(S32 discard_level) const
1435 return res; 1547 return res;
1436} 1548}
1437 1549
1438BOOL LLImageGL::isJustBound() const
1439{
1440 return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f);
1441}
1442
1443BOOL LLImageGL::getBoundRecently() const 1550BOOL LLImageGL::getBoundRecently() const
1444{ 1551{
1445 return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME); 1552 return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
@@ -1601,7 +1708,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
1601 U32 pick_offset = pick_bit%8; 1708 U32 pick_offset = pick_bit%8;
1602 if (pick_idx >= mPickMaskSize) 1709 if (pick_idx >= mPickMaskSize)
1603 { 1710 {
1604 llerrs << "WTF?" << llendl; 1711 llwarns << "WTF?" << llendl;
1605 } 1712 }
1606 1713
1607 mPickMask[pick_idx] |= 1 << pick_offset; 1714 mPickMask[pick_idx] |= 1 << pick_offset;
@@ -1627,7 +1734,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
1627 if (u < 0.f || u > 1.f || 1734 if (u < 0.f || u > 1.f ||
1628 v < 0.f || v > 1.f) 1735 v < 0.f || v > 1.f)
1629 { 1736 {
1630 llerrs << "WTF?" << llendl; 1737 llwarns << "WTF?" << llendl; // WTF really useful info NOT
1631 } 1738 }
1632 1739
1633 S32 x = (S32)(u * width); 1740 S32 x = (S32)(u * width);
@@ -1650,24 +1757,8 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
1650 return res; 1757 return res;
1651} 1758}
1652 1759
1653void LLImageGL::setCategory(S32 category) 1760//----------------------------------------------------------------------------
1654{ 1761#if !LL_RELEASE_FOR_DOWNLOAD
1655 if(!gAuditTexture)
1656 {
1657 return ;
1658 }
1659 if(mCategory != category)
1660 {
1661 if(mCategory > -1)
1662 {
1663 sTextureMemByCategory[mCategory] -= mTextureMemory ;
1664 }
1665 sTextureMemByCategory[category] += mTextureMemory ;
1666
1667 mCategory = category;
1668 }
1669}
1670
1671//for debug use 1762//for debug use
1672//val is a "power of two" number 1763//val is a "power of two" number
1673S32 LLImageGL::getTextureCounterIndex(U32 val) 1764S32 LLImageGL::getTextureCounterIndex(U32 val)
@@ -1691,38 +1782,18 @@ S32 LLImageGL::getTextureCounterIndex(U32 val)
1691 return ret ; 1782 return ret ;
1692 } 1783 }
1693} 1784}
1694void LLImageGL::incTextureCounterStatic(U32 val, S32 ncomponents, S32 category) 1785void LLImageGL::incTextureCounter(U32 val)
1695{ 1786{
1696 sTextureLoadedCounter[getTextureCounterIndex(val)]++ ; 1787 sTextureLoadedCounter[getTextureCounterIndex(val)]++ ;
1697 sTextureMemByCategory[category] += (S32)val * ncomponents ;
1698} 1788}
1699void LLImageGL::decTextureCounterStatic(U32 val, S32 ncomponents, S32 category) 1789void LLImageGL::decTextureCounter(U32 val)
1700{ 1790{
1701 sTextureLoadedCounter[getTextureCounterIndex(val)]-- ; 1791 sTextureLoadedCounter[getTextureCounterIndex(val)]-- ;
1702 sTextureMemByCategory[category] += (S32)val * ncomponents ;
1703}
1704void LLImageGL::incTextureCounter()
1705{
1706 sTextureLoadedCounter[getTextureCounterIndex(mTextureMemory / mComponents)]++ ;
1707 sTextureMemByCategory[mCategory] += mTextureMemory ;
1708}
1709void LLImageGL::decTextureCounter()
1710{
1711 sTextureLoadedCounter[getTextureCounterIndex(mTextureMemory / mComponents)]-- ;
1712 sTextureMemByCategory[mCategory] -= mTextureMemory ;
1713} 1792}
1714void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size) 1793void LLImageGL::setCurTexSizebar(S32 index)
1715{ 1794{
1716 sCurTexSizeBar = index ; 1795 sCurTexSizeBar = index ;
1717 1796 sCurTexPickSize = (1 << index) ;
1718 if(set_pick_size)
1719 {
1720 sCurTexPickSize = (1 << index) ;
1721 }
1722 else
1723 {
1724 sCurTexPickSize = -1 ;
1725 }
1726} 1797}
1727void LLImageGL::resetCurTexSizebar() 1798void LLImageGL::resetCurTexSizebar()
1728{ 1799{
@@ -1730,9 +1801,7 @@ void LLImageGL::resetCurTexSizebar()
1730 sCurTexPickSize = -1 ; 1801 sCurTexPickSize = -1 ;
1731} 1802}
1732//---------------------------------------------------------------------------- 1803//----------------------------------------------------------------------------
1733 1804#endif
1734//----------------------------------------------------------------------------
1735
1736 1805
1737// Manual Mip Generation 1806// Manual Mip Generation
1738/* 1807/*
diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h
index c7114c3..56f79ff 100644
--- a/linden/indra/llrender/llimagegl.h
+++ b/linden/indra/llrender/llimagegl.h
@@ -45,18 +45,23 @@
45#define BYTES_TO_MEGA_BYTES(x) ((x) >> 20) 45#define BYTES_TO_MEGA_BYTES(x) ((x) >> 20)
46#define MEGA_BYTES_TO_BYTES(x) ((x) << 20) 46#define MEGA_BYTES_TO_BYTES(x) ((x) << 20)
47 47
48class LLTextureAtlas ;
48//============================================================================ 49//============================================================================
50
49class LLImageGL : public LLRefCount 51class LLImageGL : public LLRefCount
50{ 52{
51 friend class LLTexUnit; 53 friend class LLTexUnit;
52public: 54public:
55 static std::list<U32> sDeadTextureList;
56
57 static void deleteDeadTextures();
58
53 // Size calculation 59 // Size calculation
54 static S32 dataFormatBits(S32 dataformat); 60 static S32 dataFormatBits(S32 dataformat);
55 static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); 61 static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height);
56 static S32 dataFormatComponents(S32 dataformat); 62 static S32 dataFormatComponents(S32 dataformat);
57 63
58 void updateBindStats(void) const; 64 void updateBindStats(void) const;
59 void forceUpdateBindStats(void) const;
60 65
61 // needs to be called every frame 66 // needs to be called every frame
62 static void updateStats(F32 current_time); 67 static void updateStats(F32 current_time);
@@ -65,10 +70,12 @@ public:
65 static void destroyGL(BOOL save_state = TRUE); 70 static void destroyGL(BOOL save_state = TRUE);
66 static void restoreGL(); 71 static void restoreGL();
67 72
68 // Sometimes called externally for textures not using LLImageGL (should go away...) 73 // Sometimes called externally for textures not using LLImageGL (should go away...)
69 static S32 updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) ; 74//#if !LL_RELEASE_FOR_DOWNLOAD
70 S32 updateBoundTexMem()const; 75// static S32 updateBoundTexMem(const S32 delta, const S32 size) ;
71 76//#else
77 static S32 updateBoundTexMem(const S32 delta);
78//#endif
72 static bool checkSize(S32 width, S32 height); 79 static bool checkSize(S32 width, S32 height);
73 80
74 // Not currently necessary for LLImageGL, but required in some derived classes, 81 // Not currently necessary for LLImageGL, but required in some derived classes,
@@ -90,7 +97,7 @@ protected:
90public: 97public:
91 virtual void dump(); // debugging info to llinfos 98 virtual void dump(); // debugging info to llinfos
92 virtual bool bindError(const S32 stage = 0) const; 99 virtual bool bindError(const S32 stage = 0) const;
93 virtual bool bindDefaultImage(const S32 stage = 0) ; 100 virtual bool bindDefaultImage(const S32 stage = 0) const;
94 virtual void forceImmediateUpdate() ; 101 virtual void forceImmediateUpdate() ;
95 102
96 void setSize(S32 width, S32 height, S32 ncomponents); 103 void setSize(S32 width, S32 height, S32 ncomponents);
@@ -102,15 +109,14 @@ public:
102 static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels); 109 static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
103 110
104 BOOL createGLTexture() ; 111 BOOL createGLTexture() ;
105 BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, 112 BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0);
106 S32 category = sMaxCatagories - 1);
107 BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0); 113 BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0);
108 void setImage(const LLImageRaw* imageraw); 114 void setImage(const LLImageRaw* imageraw);
109 void setImage(const U8* data_in, BOOL data_hasmips = FALSE); 115 void setImage(const U8* data_in, BOOL data_hasmips = FALSE);
110 BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); 116 BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
111 BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); 117 BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
112 BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height); 118 BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
113 119 BOOL setDiscardLevel(S32 discard_level);
114 // Read back a raw image for this discard level, if it exists 120 // Read back a raw image for this discard level, if it exists
115 BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok); 121 BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok);
116 void destroyGLTexture(); 122 void destroyGLTexture();
@@ -130,7 +136,7 @@ public:
130 S32 getBytes(S32 discard_level = -1) const; 136 S32 getBytes(S32 discard_level = -1) const;
131 S32 getMipBytes(S32 discard_level = -1) const; 137 S32 getMipBytes(S32 discard_level = -1) const;
132 BOOL getBoundRecently() const; 138 BOOL getBoundRecently() const;
133 BOOL isJustBound() const; 139 //BOOL isJustBound() const;
134 LLGLenum getPrimaryFormat() const { return mFormatPrimary; } 140 LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
135 141
136 BOOL getHasGLTexture() const { return mTexName != 0; } 142 BOOL getHasGLTexture() const { return mTexName != 0; }
@@ -151,6 +157,8 @@ public:
151 BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } 157 BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; }
152 BOOL getDontDiscard() const { return mDontDiscard; } 158 BOOL getDontDiscard() const { return mDontDiscard; }
153 159
160 BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ;
161
154 void updatePickMask(S32 width, S32 height, const U8* data_in); 162 void updatePickMask(S32 width, S32 height, const U8* data_in);
155 BOOL getMask(const LLVector2 &tc); 163 BOOL getMask(const LLVector2 &tc);
156 164
@@ -176,8 +184,20 @@ public:
176 void setActive() ; 184 void setActive() ;
177 void forceActive() ; 185 void forceActive() ;
178 void setNoDelete() ; 186 void setNoDelete() ;
187
188 BOOL canAddToAtlas() ;
189 BOOL createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imageraw, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row);
190 BOOL addToAtlas(const LLImageRaw* raw_image, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) ;
191
192 LLGLenum getTexTarget()const { return mTarget ;}
193 S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;}
194 U32 getTexelsInAtlas()const { return mTexelsInAtlas ;}
195 U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;}
179 196
180 void setTextureSize(S32 size) {mTextureMemory = size;} 197private:
198 void preAddToAtlas(S32 data_width) ;
199 void postAddToAtlas() ;
200
181protected: 201protected:
182 void init(BOOL usemipmaps); 202 void init(BOOL usemipmaps);
183 virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors 203 virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors
@@ -186,7 +206,7 @@ public:
186 // Various GL/Rendering options 206 // Various GL/Rendering options
187 S32 mTextureMemory; 207 S32 mTextureMemory;
188 mutable F32 mLastBindTime; // last time this was bound, by discard level 208 mutable F32 mLastBindTime; // last time this was bound, by discard level
189 209
190private: 210private:
191 LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL 211 LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
192 U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel 212 U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
@@ -202,8 +222,15 @@ private:
202 U16 mWidth; 222 U16 mWidth;
203 U16 mHeight; 223 U16 mHeight;
204 S8 mCurrentDiscardLevel; 224 S8 mCurrentDiscardLevel;
205 225
226 S8 mDiscardLevelInAtlas;
227 U32 mTexelsInAtlas ;
228 U32 mTexelsInGLTexture;
229
206protected: 230protected:
231
232 BOOL mCanAddToAtlas ;
233
207 LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps) 234 LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
208 LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps) 235 LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
209 bool mHasMipMaps; 236 bool mHasMipMaps;
@@ -241,42 +268,18 @@ public:
241 static S32 sCount; 268 static S32 sCount;
242 269
243 static F32 sLastFrameTime; 270 static F32 sLastFrameTime;
244 271
245 static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID 272 static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID
246 273
247 // Global memory statistics 274 // Global memory statistics
248 static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem 275 static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem
249 static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame 276 static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame
250 static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame 277 static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame
251 static U32 sBindCount; // Tracks number of texture binds for current frame 278 static U32 sBindCount; // Tracks number of texture binds for current frame
252 static U32 sUniqueCount; // Tracks number of unique texture binds for current frame 279 static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
253 static BOOL sGlobalUseAnisotropic; 280 static BOOL sGlobalUseAnisotropic;
254#if DEBUG_MISS 281 static BOOL sUseTextureAtlas ;
255 BOOL mMissed; // Missed on last bind? 282#if !LL_RELEASE_FOR_DOWNLOAD
256 BOOL getMissed() const { return mMissed; };
257#else
258 BOOL getMissed() const { return FALSE; };
259#endif
260
261public:
262 static void initClass(S32 num_catagories) ;
263 static void cleanupClass() ;
264private:
265 static S32 sMaxCatagories ;
266
267 //the flag to allow to call readBackRaw(...).
268 //can be removed if we do not use that function at all.
269 static BOOL sAllowReadBackRaw ;
270//
271//****************************************************************************************************
272//The below for texture auditing use only
273//****************************************************************************************************
274private:
275 S32 mCategory ;
276public:
277 void setCategory(S32 category) ;
278 S32 getCategory()const {return mCategory ;}
279
280 //for debug use: show texture size distribution 283 //for debug use: show texture size distribution
281 //---------------------------------------- 284 //----------------------------------------
282 static LLPointer<LLImageGL> sDefaultTexturep; //default texture to replace normal textures 285 static LLPointer<LLImageGL> sDefaultTexturep; //default texture to replace normal textures
@@ -287,27 +290,19 @@ public:
287 static S32 sCurTexPickSize ; 290 static S32 sCurTexPickSize ;
288 291
289 static S32 getTextureCounterIndex(U32 val) ; 292 static S32 getTextureCounterIndex(U32 val) ;
290 static void incTextureCounterStatic(U32 val, S32 ncomponents, S32 category) ; 293 static void incTextureCounter(U32 val) ;
291 static void decTextureCounterStatic(U32 val, S32 ncomponents, S32 category) ; 294 static void decTextureCounter(U32 val) ;
292 static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ; 295 static void setCurTexSizebar(S32 index) ;
293 static void resetCurTexSizebar(); 296 static void resetCurTexSizebar();
294
295 void incTextureCounter() ;
296 void decTextureCounter() ;
297 //---------------------------------------- 297 //----------------------------------------
298#endif
298 299
299 //for debug use: show texture category distribution 300#if DEBUG_MISS
300 //---------------------------------------- 301 BOOL mMissed; // Missed on last bind?
301 302 BOOL getMissed() const { return mMissed; };
302 static std::vector<S32> sTextureMemByCategory; 303#else
303 static std::vector<S32> sTextureMemByCategoryBound ; 304 BOOL getMissed() const { return FALSE; };
304 static std::vector<S32> sTextureCurMemByCategoryBound ; 305#endif
305 //----------------------------------------
306//****************************************************************************************************
307//End of definitions for texture auditing use only
308//****************************************************************************************************
309
310}; 306};
311 307
312extern BOOL gAuditTexture;
313#endif // LL_LLIMAGEGL_H 308#endif // LL_LLIMAGEGL_H
diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp
index b1fe153..07ba9f1 100644
--- a/linden/indra/llrender/llrender.cpp
+++ b/linden/indra/llrender/llrender.cpp
@@ -47,7 +47,7 @@ F64 gGLLastModelView[16];
47F64 gGLProjection[16]; 47F64 gGLProjection[16];
48S32 gGLViewport[4]; 48S32 gGLViewport[4];
49 49
50static const U32 LL_NUM_TEXTURE_LAYERS = 8; 50static const U32 LL_NUM_TEXTURE_LAYERS = 16; // KL was 8 ( keep a track on this ) 16 in render-pipeline
51 51
52static GLenum sGLTextureType[] = 52static GLenum sGLTextureType[] =
53{ 53{
@@ -192,24 +192,25 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
192 192
193 if (!texture->getTexName()) //if texture does not exist 193 if (!texture->getTexName()) //if texture does not exist
194 { 194 {
195 if (texture->isDeleted()) 195 //if deleted, will re-generate it immediately
196 { 196 texture->forceImmediateUpdate() ;
197 // This will re-generate the texture immediately.
198 texture->forceImmediateUpdate() ;
199 }
200 197
201 texture->forceUpdateBindStats() ;
202 return texture->bindDefaultImage(mIndex); 198 return texture->bindDefaultImage(mIndex);
203 } 199 }
204 200
205 if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0) 201#if !LL_RELEASE_FOR_DOWNLOAD
202 if(for_rendering)
206 { 203 {
207 if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize) 204 int w = texture->getWidth(texture->getDiscardLevel()) ;
205 int h = texture->getHeight(texture->getDiscardLevel()) ;
206
207 if(w * h == LLImageGL::sCurTexPickSize)
208 { 208 {
209 texture->updateBindStats(); 209 texture->updateBindStats();
210 return bind(LLImageGL::sDefaultTexturep.get()); 210 return bind(LLImageGL::sDefaultTexturep.get());
211 } 211 }
212 } 212 }
213#endif
213 214
214 if ((mCurrTexture != texture->getTexName()) || forceBind) 215 if ((mCurrTexture != texture->getTexName()) || forceBind)
215 { 216 {
@@ -227,7 +228,6 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind)
227 setTextureFilteringOption(texture->mFilterOption); 228 setTextureFilteringOption(texture->mFilterOption);
228 } 229 }
229 } 230 }
230
231 return true; 231 return true;
232} 232}
233 233
@@ -280,6 +280,11 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
280 280
281 if (bindDepth) 281 if (bindDepth)
282 { 282 {
283 if (renderTarget->hasStencil())
284 {
285 llwarns << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << llendl;
286 }
287
283 bindManual(renderTarget->getUsage(), renderTarget->getDepth()); 288 bindManual(renderTarget->getUsage(), renderTarget->getDepth());
284 } 289 }
285 else 290 else
@@ -293,15 +298,18 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
293 298
294bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) 299bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
295{ 300{
296 if (mIndex < 0 || mCurrTexture == texture) return false; 301 if (mIndex < 0) return false;
297
298 gGL.flush();
299 302
300 activate(); 303 if(mCurrTexture != texture)
301 enable(type); 304 {
302 mCurrTexture = texture; 305 gGL.flush();
303 glBindTexture(sGLTextureType[type], texture); 306
304 mHasMipMaps = hasMips; 307 activate();
308 enable(type);
309 mCurrTexture = texture;
310 glBindTexture(sGLTextureType[type], texture);
311 mHasMipMaps = hasMips;
312 }
305 return true; 313 return true;
306} 314}
307 315
@@ -414,7 +422,7 @@ void LLTexUnit::setTextureBlendType(eTextureBlendType type)
414 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); 422 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
415 break; 423 break;
416 default: 424 default:
417 llerrs << "Unknown Texture Blend Type: " << type << llendl; 425 llwarns << "Unknown Texture Blend Type: " << type << llendl;
418 break; 426 break;
419 } 427 }
420 setColorScale(scale_amount); 428 setColorScale(scale_amount);
@@ -809,7 +817,7 @@ void LLRender::setSceneBlendType(eBlendType type)
809 glBlendFunc(GL_ONE, GL_ZERO); 817 glBlendFunc(GL_ONE, GL_ZERO);
810 break; 818 break;
811 default: 819 default:
812 llerrs << "Unknown Scene Blend Type: " << type << llendl; 820 llwarns << "Unknown Scene Blend Type: " << type << llendl;
813 break; 821 break;
814 } 822 }
815} 823}
@@ -883,7 +891,7 @@ void LLRender::begin(const GLuint& mode)
883 } 891 }
884 else if (mCount != 0) 892 else if (mCount != 0)
885 { 893 {
886 llerrs << "gGL.begin() called redundantly." << llendl; 894 llwarns << "gGL.begin() called redundantly." << llendl;
887 } 895 }
888 896
889 mMode = mode; 897 mMode = mode;
@@ -914,22 +922,22 @@ void LLRender::flush()
914#if 0 922#if 0
915 if (!glIsEnabled(GL_VERTEX_ARRAY)) 923 if (!glIsEnabled(GL_VERTEX_ARRAY))
916 { 924 {
917 llerrs << "foo 1" << llendl; 925 llwarns << "foo 1" << llendl;
918 } 926 }
919 927
920 if (!glIsEnabled(GL_COLOR_ARRAY)) 928 if (!glIsEnabled(GL_COLOR_ARRAY))
921 { 929 {
922 llerrs << "foo 2" << llendl; 930 llwarns << "foo 2" << llendl;
923 } 931 }
924 932
925 if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY)) 933 if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY))
926 { 934 {
927 llerrs << "foo 3" << llendl; 935 llwarns << "foo 3" << llendl;
928 } 936 }
929 937
930 if (glIsEnabled(GL_NORMAL_ARRAY)) 938 if (glIsEnabled(GL_NORMAL_ARRAY))
931 { 939 {
932 llerrs << "foo 7" << llendl; 940 llwarns << "foo 7" << llendl;
933 } 941 }
934 942
935 GLvoid* pointer; 943 GLvoid* pointer;
@@ -937,19 +945,19 @@ void LLRender::flush()
937 glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer); 945 glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer);
938 if (pointer != &(mBuffer[0].v)) 946 if (pointer != &(mBuffer[0].v))
939 { 947 {
940 llerrs << "foo 4" << llendl; 948 llwarns << "foo 4" << llendl;
941 } 949 }
942 950
943 glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer); 951 glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer);
944 if (pointer != &(mBuffer[0].c)) 952 if (pointer != &(mBuffer[0].c))
945 { 953 {
946 llerrs << "foo 5" << llendl; 954 llwarns << "foo 5" << llendl;
947 } 955 }
948 956
949 glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer); 957 glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer);
950 if (pointer != &(mBuffer[0].uv)) 958 if (pointer != &(mBuffer[0].uv))
951 { 959 {
952 llerrs << "foo 6" << llendl; 960 llwarns << "foo 6" << llendl;
953 } 961 }
954#endif 962#endif
955 963
diff --git a/linden/indra/llrender/llrendertarget.cpp b/linden/indra/llrender/llrendertarget.cpp
index 4cf8451..151b761 100644
--- a/linden/indra/llrender/llrendertarget.cpp
+++ b/linden/indra/llrender/llrendertarget.cpp
@@ -47,10 +47,10 @@ void check_framebuffer_status()
47 case GL_FRAMEBUFFER_COMPLETE_EXT: 47 case GL_FRAMEBUFFER_COMPLETE_EXT:
48 break; 48 break;
49 case GL_FRAMEBUFFER_UNSUPPORTED_EXT: 49 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
50 llerrs << "WTF?" << llendl; 50 llwarns << "WTF?" << llendl;
51 break; 51 break;
52 default: 52 default:
53 llerrs << "WTF?" << llendl; 53 llwarns << "WTF?" << llendl;
54 } 54 }
55 } 55 }
56} 56}
@@ -139,9 +139,9 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt)
139 139
140 U32 offset = mTex.size(); 140 U32 offset = mTex.size();
141 if (offset >= 4 || 141 if (offset >= 4 ||
142 (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) 142 offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))
143 { 143 {
144 llerrs << "Too many color attachments!" << llendl; 144 llwarns << "Too many color attachments!" << llendl; // KL
145 } 145 }
146 146
147 U32 tex; 147 U32 tex;
@@ -203,7 +203,7 @@ void LLRenderTarget::allocateDepth()
203 gGL.getTexUnit(0)->bindManual(mUsage, mDepth); 203 gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
204 U32 internal_type = LLTexUnit::getInternalType(mUsage); 204 U32 internal_type = LLTexUnit::getInternalType(mUsage);
205 gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); 205 gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
206 LLImageGL::setManualImage(internal_type, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL); 206 LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
207 } 207 }
208} 208}
209 209
@@ -211,7 +211,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
211{ 211{
212 if (!mFBO || !target.mFBO) 212 if (!mFBO || !target.mFBO)
213 { 213 {
214 llerrs << "Cannot share depth buffer between non FBO render targets." << llendl; 214 llwarns << "Cannot share depth buffer between non FBO render targets." << llendl;
215 } 215 }
216 216
217 if (mDepth) 217 if (mDepth)
@@ -349,16 +349,16 @@ U32 LLRenderTarget::getTexture(U32 attachment) const
349{ 349{
350 if (attachment > mTex.size()-1) 350 if (attachment > mTex.size()-1)
351 { 351 {
352 llerrs << "Invalid attachment index." << llendl; 352 llwarns << "Invalid attachment index [getTexture]." << llendl; // lets not crash KL its a pain in the ass!
353 } 353 }
354 return mTex[attachment]; 354 return mTex[attachment];
355} 355}
356 356
357void LLRenderTarget::bindTexture(U32 index, S32 channel) 357void LLRenderTarget::bindTexture(U32 index, S32 channel)
358{ 358{
359 if (index > mTex.size()-1) 359 if (index > 6)//mTex.size()-1) // KL yeah i know its a bit arbitary but make the number big enough as some unused render defer elements cause this to go wild
360 { 360 {
361 llerrs << "Invalid attachment index." << llendl; 361 llwarns << "Invalid attachment index [bindtexture]." << llendl;
362 } 362 }
363 gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]); 363 gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]);
364} 364}
@@ -440,7 +440,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
440#if !LL_DARWIN 440#if !LL_DARWIN
441 if (!source.mFBO || !mFBO) 441 if (!source.mFBO || !mFBO)
442 { 442 {
443 llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; 443 llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
444 } 444 }
445 445
446 if (mSampleBuffer) 446 if (mSampleBuffer)
@@ -449,12 +449,27 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
449 } 449 }
450 else 450 else
451 { 451 {
452 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); 452 if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)
453 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); 453 {
454 454 source.bindTarget();
455 glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 455 gGL.getTexUnit(0)->bind(this, true);
456 456
457 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 457 glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
458 source.flush();
459 }
460 else
461 {
462 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO);
463 stop_glerror();
464 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO);
465 stop_glerror();
466 check_framebuffer_status();
467 stop_glerror();
468 glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
469 stop_glerror();
470 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
471 stop_glerror();
472 }
458 } 473 }
459#endif 474#endif
460} 475}
@@ -553,14 +568,14 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
553 568
554 if (!gGLManager.mHasFramebufferMultisample) 569 if (!gGLManager.mHasFramebufferMultisample)
555 { 570 {
556 llerrs << "Attempting to allocate unsupported render target type!" << llendl; 571 llwarns << "Attempting to allocate unsupported render target type!" << llendl;
557 } 572 }
558 573
559 mSamples = samples; 574 mSamples = samples;
560 575
561 if (mSamples <= 1) 576 if (mSamples <= 1)
562 { 577 {
563 llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl; 578 llwarns << "Cannot create a multisample buffer with less than 2 samples." << llendl;
564 } 579 }
565 580
566 stop_glerror(); 581 stop_glerror();
@@ -608,9 +623,9 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
608 623
609 U32 offset = mTex.size(); 624 U32 offset = mTex.size();
610 if (offset >= 4 || 625 if (offset >= 4 ||
611 (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) 626 offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))
612 { 627 {
613 llerrs << "Too many color attachments!" << llendl; 628 llwarns << "Too many color attachments!" << llendl;
614 } 629 }
615 630
616 U32 tex; 631 U32 tex;
@@ -631,10 +646,10 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
631 case GL_FRAMEBUFFER_COMPLETE_EXT: 646 case GL_FRAMEBUFFER_COMPLETE_EXT:
632 break; 647 break;
633 case GL_FRAMEBUFFER_UNSUPPORTED_EXT: 648 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
634 llerrs << "WTF?" << llendl; 649 llwarns << "WTF?" << llendl;
635 break; 650 break;
636 default: 651 default:
637 llerrs << "WTF?" << llendl; 652 llwarns << "WTF?" << llendl;
638 } 653 }
639 654
640 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 655 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
diff --git a/linden/indra/llrender/llrendertarget.h b/linden/indra/llrender/llrendertarget.h
index d5d809b..69af1ea 100644
--- a/linden/indra/llrender/llrendertarget.h
+++ b/linden/indra/llrender/llrendertarget.h
@@ -121,6 +121,7 @@ public:
121 U32 getTexture(U32 attachment = 0) const; 121 U32 getTexture(U32 attachment = 0) const;
122 122
123 U32 getDepth(void) const { return mDepth; } 123 U32 getDepth(void) const { return mDepth; }
124 BOOL hasStencil() const { return mStencil; }
124 125
125 void bindTexture(U32 index, S32 channel); 126 void bindTexture(U32 index, S32 channel);
126 127
diff --git a/linden/indra/llrender/lltextureatlas.cpp b/linden/indra/llrender/lltextureatlas.cpp
new file mode 100644
index 0000000..c0f5419
--- /dev/null
+++ b/linden/indra/llrender/lltextureatlas.cpp
@@ -0,0 +1,411 @@
1/**
2 * @file lltextureatlas.cpp
3 * @brief LLTextureAtlas class implementation.
4 *
5 * $LicenseInfo:firstyear=2002&license=viewergpl$
6 *
7 * Copyright (c) 2002-2009, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 *
23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations.
26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE.
30 * $/LicenseInfo$
31 */
32#include "linden_common.h"
33#include "llerror.h"
34#include "llimage.h"
35#include "llmath.h"
36#include "llgl.h"
37#include "llrender.h"
38#include "lltextureatlas.h"
39
40//-------------------
41S16 LLTextureAtlas::sMaxSubTextureSize = 64 ;
42S16 LLTextureAtlas::sSlotSize = 32 ;
43
44#ifndef DEBUG_ATLAS
45#define DEBUG_ATLAS 0
46#endif
47
48#ifndef DEBUG_USAGE_BITS
49#define DEBUG_USAGE_BITS 0
50#endif
51//**************************************************************************************************************
52LLTextureAtlas::LLTextureAtlas(U8 ncomponents, S16 atlas_dim) : LLImageGL(),
53 mAtlasDim(atlas_dim)
54{
55 setComponents(ncomponents) ;
56
57 mCanAddToAtlas = FALSE ;//do not add one atlas to another.
58 mNumSlotsReserved = 0 ;
59 mMaxSlotsInAtlas = mAtlasDim * mAtlasDim ;
60
61 generateEmptyUsageBits() ;
62
63 //generate an empty texture
64 S32 dim = mAtlasDim * sSlotSize ; //number of pixels per dimension
65 LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim, dim, getComponents());
66 createGLTexture(0, image_raw, 0);
67 image_raw = NULL;
68 dontDiscard();
69}
70
71LLTextureAtlas::~LLTextureAtlas()
72{
73 if(mSpatialGroupList.size() > 0)
74 {
75 llwarns << "Not clean up the spatial groups!" << llendl ;
76 }
77 releaseUsageBits() ;
78}
79
80void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset)
81{
82#if !DEBUG_ATLAS
83 xoffset = (F32)col / mAtlasDim ;
84 yoffset = (F32)row / mAtlasDim ;
85#endif
86}
87
88void LLTextureAtlas::getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale)
89{
90#if !DEBUG_ATLAS
91 xscale = (F32)w / (mAtlasDim * sSlotSize) ;
92 yscale = (F32)h / (mAtlasDim * sSlotSize) ;
93#endif
94}
95
96//insert a texture piece into the atlas
97LLGLuint LLTextureAtlas::insertSubTexture(const LLImageRaw* raw_image, S16 slot_col, S16 slot_row)
98{
99 S32 w = raw_image->getWidth() ;
100 S32 h = raw_image->getHeight() ;
101 if(w < 8 || w > sMaxSubTextureSize || h < 8 || h > sMaxSubTextureSize)
102 {
103 //size overflow
104 return 0 ;
105 }
106
107 BOOL res = gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getTexName());
108 if (!res) llwarns << "bindTexture failed" << llendl;
109 stop_glerror();
110
111 GLint xoffset = sSlotSize * slot_col ;
112 GLint yoffset = sSlotSize * slot_row ;
113
114 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE);
115 glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset,
116 w, h, mFormatPrimary, mFormatType, raw_image->getData());
117
118 return getTexName();
119}
120
121//release a sub-texture slot from the atlas
122void LLTextureAtlas::releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width)
123{
124 unmarkUsageBits(slot_width, slot_col, slot_row) ;
125 mNumSlotsReserved -= slot_width * slot_width ;
126}
127
128BOOL LLTextureAtlas::isEmpty() const
129{
130 return !mNumSlotsReserved ;
131}
132
133BOOL LLTextureAtlas::isFull(S8 to_be_reserved) const
134{
135 return mNumSlotsReserved + to_be_reserved > mMaxSlotsInAtlas ;
136}
137F32 LLTextureAtlas::getFullness() const
138{
139 return (F32)mNumSlotsReserved / mMaxSlotsInAtlas ;
140}
141
142void LLTextureAtlas::addSpatialGroup(LLSpatialGroup* groupp)
143{
144 if(groupp && !hasSpatialGroup(groupp))
145 {
146 mSpatialGroupList.push_back(groupp);
147 }
148}
149
150void LLTextureAtlas::removeSpatialGroup(LLSpatialGroup* groupp)
151{
152 if(groupp)
153 {
154 mSpatialGroupList.remove(groupp);
155 }
156}
157
158void LLTextureAtlas::clearSpatialGroup()
159{
160 mSpatialGroupList.clear();
161}
162void LLTextureAtlas::removeLastSpatialGroup()
163{
164 mSpatialGroupList.pop_back() ;
165}
166
167LLSpatialGroup* LLTextureAtlas::getLastSpatialGroup()
168{
169 if(mSpatialGroupList.size() > 0)
170 {
171 return mSpatialGroupList.back() ;
172 }
173 return NULL ;
174}
175
176BOOL LLTextureAtlas::hasSpatialGroup(LLSpatialGroup* groupp)
177{
178 for(std::list<LLSpatialGroup*>::iterator iter = mSpatialGroupList.begin(); iter != mSpatialGroupList.end() ; ++iter)
179 {
180 if(*iter == groupp)
181 {
182 return TRUE ;
183 }
184 }
185 return FALSE ;
186}
187
188//--------------------------------------------------------------------------------------
189//private
190void LLTextureAtlas::generateEmptyUsageBits()
191{
192 S32 col_len = (mAtlasDim + 7) >> 3 ;
193 mUsageBits = new U8*[mAtlasDim] ;
194 *mUsageBits = new U8[mAtlasDim * col_len] ;
195
196 mUsageBits[0] = *mUsageBits ;
197 for(S32 i = 1 ; i < mAtlasDim ; i++)
198 {
199 mUsageBits[i] = mUsageBits[i-1] + col_len ;
200
201 for(S32 j = 0 ; j < col_len ; j++)
202 {
203 //init by 0 for all bits.
204 mUsageBits[i][j] = 0 ;
205 }
206 }
207
208 //do not forget mUsageBits[0]!
209 for(S32 j = 0 ; j < col_len ; j++)
210 {
211 //init by 0 for all bits.
212 mUsageBits[0][j] = 0 ;
213 }
214
215 mTestBits = NULL ;
216#if DEBUG_USAGE_BITS
217 //------------
218 //test
219 mTestBits = new U8*[mAtlasDim] ;
220 *mTestBits = new U8[mAtlasDim * mAtlasDim] ;
221 mTestBits[0] = *mTestBits ;
222 for(S32 i = 1 ; i < mAtlasDim ; i++)
223 {
224 mTestBits[i] = mTestBits[i-1] + mAtlasDim ;
225
226 for(S32 j = 0 ; j < mAtlasDim ; j++)
227 {
228 //init by 0 for all bits.
229 mTestBits[i][j] = 0 ;
230 }
231 }
232
233 for(S32 j = 0 ; j < mAtlasDim ; j++)
234 {
235 //init by 0 for all bits.
236 mTestBits[0][j] = 0 ;
237 }
238#endif
239}
240
241void LLTextureAtlas::releaseUsageBits()
242{
243 if(mUsageBits)
244 {
245 delete[] *mUsageBits ;
246 delete[] mUsageBits ;
247 }
248 mUsageBits = NULL ;
249
250 //test
251 if( mTestBits)
252 {
253 delete[] *mTestBits;
254 delete[] mTestBits;
255 }
256 mTestBits = NULL ;
257}
258
259void LLTextureAtlas::markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row)
260{
261 S16 x = col >> 3 ;
262
263 for(S8 i = 0 ; i < bits_len ; i++)
264 {
265 mUsageBits[row + i][x] |= mask ;
266 }
267
268#if DEBUG_USAGE_BITS
269 //test
270 for(S8 i = row ; i < row + bits_len ; i++)
271 {
272 for(S8 j = col ; j < col + bits_len ; j++)
273 {
274 mTestBits[i][j] = 1 ;
275 }
276 }
277#endif
278}
279
280void LLTextureAtlas::unmarkUsageBits(S8 bits_len, S16 col, S16 row)
281{
282 S16 x = col >> 3 ;
283 U8 mask = 1 ;
284 for(S8 i = 1 ; i < bits_len ; i++)
285 {
286 mask |= (1 << i) ;
287 }
288 mask <<= (col & 7) ;
289 mask = ~mask ;
290
291 for(S8 i = 0 ; i < bits_len ; i++)
292 {
293 mUsageBits[row + i][x] &= mask ;
294 }
295
296#if DEBUG_USAGE_BITS
297 //test
298 for(S8 i = row ; i < row + bits_len ; i++)
299 {
300 for(S8 j = col ; j < col + bits_len ; j++)
301 {
302 mTestBits[i][j] = 0 ;
303 }
304 }
305#endif
306}
307
308//return true if any of bits in the range marked.
309BOOL LLTextureAtlas::areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row)
310{
311 BOOL ret = FALSE ;
312 S16 x = col >> 3 ;
313
314 for(S8 i = 0 ; i < bits_len ; i++)
315 {
316 if(mUsageBits[row + i][x] & mask)
317 {
318 ret = TRUE ;
319 break ;
320 //return TRUE ;
321 }
322 }
323
324#if DEBUG_USAGE_BITS
325 //test
326 BOOL ret2 = FALSE ;
327 for(S8 i = row ; i < row + bits_len ; i++)
328 {
329 for(S8 j = col ; j < col + bits_len ; j++)
330 {
331 if(mTestBits[i][j])
332 {
333 ret2 = TRUE ;
334 }
335 }
336 }
337
338 if(ret != ret2)
339 {
340 llwarns << "bits map corrupted." << llendl ;
341 }
342#endif
343 return ret ;//FALSE ;
344}
345
346//----------------------------------------------------------------------
347//
348//index order: Z order, i.e.:
349// |-----|-----|-----|-----|
350// | 10 | 11 | 14 | 15 |
351// |-----|-----|-----|-----|
352// | 8 | 9 | 12 | 13 |
353// |-----|-----|-----|-----|
354// | 2 | 3 | 6 | 7 |
355// |-----|-----|-----|-----|
356// | 0 | 1 | 4 | 5 |
357// |-----|-----|-----|-----|
358void LLTextureAtlas::getPositionFromIndex(S16 index, S16& col, S16& row)
359{
360 col = 0 ;
361 row = 0 ;
362
363 S16 index_copy = index ;
364 for(S16 i = 0 ; index_copy && i < 16 ; i += 2)
365 {
366 col |= ((index & (1 << i)) >> i) << (i >> 1) ;
367 row |= ((index & (1 << (i + 1))) >> (i + 1)) << (i >> 1) ;
368 index_copy >>= 2 ;
369 }
370}
371void LLTextureAtlas::getIndexFromPosition(S16 col, S16 row, S16& index)
372{
373 index = 0 ;
374 S16 col_copy = col ;
375 S16 row_copy = row ;
376 for(S16 i = 0 ; (col_copy || row_copy) && i < 16 ; i++)
377 {
378 index |= ((col & 1 << i) << i) | ((row & 1 << i) << ( i + 1)) ;
379 col_copy >>= 1 ;
380 row_copy >>= 1 ;
381 }
382}
383//----------------------------------------------------------------------
384//return TRUE if succeeds.
385BOOL LLTextureAtlas::getNextAvailableSlot(S8 bits_len, S16& col, S16& row)
386{
387 S16 index_step = bits_len * bits_len ;
388
389 U8 mask = 1 ;
390 for(S8 i = 1 ; i < bits_len ; i++)
391 {
392 mask |= (1 << i) ;
393 }
394
395 U8 cur_mask ;
396 for(S16 index = 0 ; index < mMaxSlotsInAtlas ; index += index_step)
397 {
398 getPositionFromIndex(index, col, row) ;
399
400 cur_mask = mask << (col & 7) ;
401 if(!areUsageBitsMarked(bits_len, cur_mask, col, row))
402 {
403 markUsageBits(bits_len, cur_mask, col, row) ;
404 mNumSlotsReserved += bits_len * bits_len ;
405
406 return TRUE ;
407 }
408 }
409
410 return FALSE ;
411}
diff --git a/linden/indra/llrender/lltextureatlas.h b/linden/indra/llrender/lltextureatlas.h
new file mode 100644
index 0000000..4922175
--- /dev/null
+++ b/linden/indra/llrender/lltextureatlas.h
@@ -0,0 +1,92 @@
1/**
2 * @file lltextureatlas.h
3 * @brief LLTextureAtlas base class.
4 *
5 * $LicenseInfo:firstyear=2002&license=viewergpl$
6 *
7 * Copyright (c) 2002-2009, Linden Research, Inc.
8 *
9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab
11 * to you under the terms of the GNU General Public License, version 2.0
12 * ("GPL"), unless you have obtained a separate licensing agreement
13 * ("Other License"), formally executed by you and Linden Lab. Terms of
14 * the GPL can be found in doc/GPL-license.txt in this distribution, or
15 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
16 *
17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 *
23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations.
26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE.
30 * $/LicenseInfo$
31 */
32
33
34#ifndef LL_TEXTUREATLAS_H
35#define LL_TEXTUREATLAS_H
36
37#include "llimagegl.h"
38class LLSpatialGroup ;
39
40class LLTextureAtlas : public LLImageGL
41{
42public:
43 LLTextureAtlas(U8 ncomponents, S16 atlas_dim = 16) ;
44 ~LLTextureAtlas() ;
45
46 LLGLuint insertSubTexture(const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) ;
47 void releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width);
48
49 BOOL getNextAvailableSlot(S8 bits_len, S16& col, S16& row) ;
50 void getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yOffset) ;
51 void getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) ;
52
53 BOOL isEmpty() const ;
54 BOOL isFull(S8 to_be_reserved = 1) const ;
55 F32 getFullness() const ;
56
57 void addSpatialGroup(LLSpatialGroup* groupp) ;
58 void removeSpatialGroup(LLSpatialGroup* groupp) ;
59 LLSpatialGroup* getLastSpatialGroup() ;
60 void removeLastSpatialGroup() ;
61 BOOL hasSpatialGroup(LLSpatialGroup* groupp) ;
62 void clearSpatialGroup() ;
63 std::list<LLSpatialGroup*>* getSpatialGroupList() {return &mSpatialGroupList;}
64private:
65 void generateEmptyUsageBits() ;
66 void releaseUsageBits() ;
67
68 void markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) ;
69 void unmarkUsageBits(S8 bits_len, S16 col, S16 row) ;
70
71 void getPositionFromIndex(S16 index, S16& col, S16& row) ;
72 void getIndexFromPosition(S16 col, S16 row, S16& index) ;
73 BOOL areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) ;
74
75private:
76 S16 mAtlasDim ; //number of slots per edge, i.e, there are "mAtlasDim * mAtlasDim" total slots in the atlas.
77 S16 mNumSlotsReserved ;
78 S16 mMaxSlotsInAtlas ;
79 U8 **mUsageBits ;
80 std::list<LLSpatialGroup*> mSpatialGroupList ;
81
82public:
83 //debug use only
84 U8 **mTestBits ;
85
86public:
87 static S16 sMaxSubTextureSize ;
88 static S16 sSlotSize ;
89};
90
91#endif
92
diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp
index 461edbe..31c2d75 100644
--- a/linden/indra/llrender/llvertexbuffer.cpp
+++ b/linden/indra/llrender/llvertexbuffer.cpp
@@ -96,7 +96,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
96{ 96{
97 /*if (LLGLImmediate::sStarted) 97 /*if (LLGLImmediate::sStarted)
98 { 98 {
99 llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; 99 llwarns << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl;
100 }*/ 100 }*/
101 101
102 if (sLastMask != data_mask) 102 if (sLastMask != data_mask)
@@ -129,7 +129,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
129 { //needs to be enabled, make sure it was (DEBUG TEMPORARY) 129 { //needs to be enabled, make sure it was (DEBUG TEMPORARY)
130 if (i > 0 && !glIsEnabled(array[i])) 130 if (i > 0 && !glIsEnabled(array[i]))
131 { 131 {
132 llerrs << "Bad client state! " << array[i] << " disabled." << llendl; 132 llwarns << "Bad client state! " << array[i] << " disabled." << llendl;
133 } 133 }
134 } 134 }
135 } 135 }
@@ -141,7 +141,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
141 } 141 }
142 else if (gDebugGL && glIsEnabled(array[i])) 142 else if (gDebugGL && glIsEnabled(array[i]))
143 { //needs to be disabled, make sure it was (DEBUG TEMPORARY) 143 { //needs to be disabled, make sure it was (DEBUG TEMPORARY)
144 llerrs << "Bad client state! " << array[i] << " enabled." << llendl; 144 llwarns << "Bad client state! " << array[i] << " enabled." << llendl;
145 } 145 }
146 } 146 }
147 } 147 }
@@ -197,28 +197,28 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
197 if (start >= (U32) mRequestedNumVerts || 197 if (start >= (U32) mRequestedNumVerts ||
198 end >= (U32) mRequestedNumVerts) 198 end >= (U32) mRequestedNumVerts)
199 { 199 {
200 llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; 200 llwarns << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl;
201 } 201 }
202 202
203 if (indices_offset >= (U32) mRequestedNumIndices || 203 if (indices_offset >= (U32) mRequestedNumIndices ||
204 indices_offset + count > (U32) mRequestedNumIndices) 204 indices_offset + count > (U32) mRequestedNumIndices)
205 { 205 {
206 llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; 206 llwarns << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
207 } 207 }
208 208
209 if (mGLIndices != sGLRenderIndices) 209 if (mGLIndices != sGLRenderIndices)
210 { 210 {
211 llerrs << "Wrong index buffer bound." << llendl; 211 llwarns << "Wrong index buffer bound." << llendl;
212 } 212 }
213 213
214 if (mGLBuffer != sGLRenderBuffer) 214 if (mGLBuffer != sGLRenderBuffer)
215 { 215 {
216 llerrs << "Wrong vertex buffer bound." << llendl; 216 llwarns << "Wrong vertex buffer bound." << llendl;
217 } 217 }
218 218
219 if (mode > LLRender::NUM_MODES) 219 if (mode > LLRender::NUM_MODES)
220 { 220 {
221 llerrs << "Invalid draw mode: " << mode << llendl; 221 llwarns << "Invalid draw mode: " << mode << llendl;
222 return; 222 return;
223 } 223 }
224 224
@@ -233,22 +233,22 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
233 if (indices_offset >= (U32) mRequestedNumIndices || 233 if (indices_offset >= (U32) mRequestedNumIndices ||
234 indices_offset + count > (U32) mRequestedNumIndices) 234 indices_offset + count > (U32) mRequestedNumIndices)
235 { 235 {
236 llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; 236 llwarns << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
237 } 237 }
238 238
239 if (mGLIndices != sGLRenderIndices) 239 if (mGLIndices != sGLRenderIndices)
240 { 240 {
241 llerrs << "Wrong index buffer bound." << llendl; 241 llwarns << "Wrong index buffer bound." << llendl;
242 } 242 }
243 243
244 if (mGLBuffer != sGLRenderBuffer) 244 if (mGLBuffer != sGLRenderBuffer)
245 { 245 {
246 llerrs << "Wrong vertex buffer bound." << llendl; 246 llwarns << "Wrong vertex buffer bound." << llendl;
247 } 247 }
248 248
249 if (mode > LLRender::NUM_MODES) 249 if (mode > LLRender::NUM_MODES)
250 { 250 {
251 llerrs << "Invalid draw mode: " << mode << llendl; 251 llwarns << "Invalid draw mode: " << mode << llendl;
252 return; 252 return;
253 } 253 }
254 254
@@ -263,17 +263,17 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
263 if (first >= (U32) mRequestedNumVerts || 263 if (first >= (U32) mRequestedNumVerts ||
264 first + count > (U32) mRequestedNumVerts) 264 first + count > (U32) mRequestedNumVerts)
265 { 265 {
266 llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; 266 llwarns << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl;
267 } 267 }
268 268
269 if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) 269 if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
270 { 270 {
271 llerrs << "Wrong vertex buffer bound." << llendl; 271 llwarns << "Wrong vertex buffer bound." << llendl;
272 } 272 }
273 273
274 if (mode > LLRender::NUM_MODES) 274 if (mode > LLRender::NUM_MODES)
275 { 275 {
276 llerrs << "Invalid draw mode: " << mode << llendl; 276 llwarns << "Invalid draw mode: " << mode << llendl;
277 return; 277 return;
278 } 278 }
279 279
@@ -530,7 +530,7 @@ void LLVertexBuffer::destroyGLBuffer()
530 { 530 {
531 if (mMappedData || mMappedIndexData) 531 if (mMappedData || mMappedIndexData)
532 { 532 {
533 llerrs << "Vertex buffer destroyed while mapped!" << llendl; 533 llwarns << "Vertex buffer destroyed while mapped!" << llendl;
534 } 534 }
535 releaseBuffer(); 535 releaseBuffer();
536 } 536 }
@@ -557,7 +557,7 @@ void LLVertexBuffer::destroyGLIndices()
557 { 557 {
558 if (mMappedData || mMappedIndexData) 558 if (mMappedData || mMappedIndexData)
559 { 559 {
560 llerrs << "Vertex buffer destroyed while mapped." << llendl; 560 llwarns << "Vertex buffer destroyed while mapped." << llendl;
561 } 561 }
562 releaseIndices(); 562 releaseIndices();
563 } 563 }
@@ -634,7 +634,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
634 634
635 if (mMappedData) 635 if (mMappedData)
636 { 636 {
637 llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; 637 llwarns << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl;
638 } 638 }
639 if (create && (nverts || nindices)) 639 if (create && (nverts || nindices))
640 { 640 {
@@ -782,11 +782,11 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
782 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); 782 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
783 if (mFinal) 783 if (mFinal)
784 { 784 {
785 llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; 785 llwarns << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
786 } 786 }
787 if (!useVBOs() && !mMappedData && !mMappedIndexData) 787 if (!useVBOs() && !mMappedData && !mMappedIndexData)
788 { 788 {
789 llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; 789 llwarns << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
790 } 790 }
791 791
792 if (!mLocked && useVBOs()) 792 if (!mLocked && useVBOs())
@@ -813,11 +813,11 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
813 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); 813 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
814 if (buff != mGLBuffer) 814 if (buff != mGLBuffer)
815 { 815 {
816 llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; 816 llwarns << "Invalid GL vertex buffer bound: " << buff << llendl;
817 } 817 }
818 818
819 819
820 llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; 820 llwarns << "glMapBuffer returned NULL (no vertex data)" << llendl;
821 } 821 }
822 822
823 if (!mMappedIndexData) 823 if (!mMappedIndexData)
@@ -826,10 +826,10 @@ U8* LLVertexBuffer::mapBuffer(S32 access)
826 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); 826 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
827 if (buff != mGLIndices) 827 if (buff != mGLIndices)
828 { 828 {
829 llerrs << "Invalid GL index buffer bound: " << buff << llendl; 829 llwarns << "Invalid GL index buffer bound: " << buff << llendl;
830 } 830 }
831 831
832 llerrs << "glMapBuffer returned NULL (no index data)" << llendl; 832 llwarns << "glMapBuffer returned NULL (no index data)" << llendl;
833 } 833 }
834 834
835 sMappedCount++; 835 sMappedCount++;
@@ -908,7 +908,7 @@ template <class T,S32 type> struct VertexBufferStrider
908 } 908 }
909 else 909 else
910 { 910 {
911 llerrs << "VertexBufferStrider could not find valid vertex data." << llendl; 911 llwarns << "VertexBufferStrider could not find valid vertex data." << llendl;
912 } 912 }
913 return FALSE; 913 return FALSE;
914 } 914 }
@@ -965,7 +965,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride)
965 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); 965 LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
966 if (mNumVerts) 966 if (mNumVerts)
967 { 967 {
968 llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; 968 llwarns << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl;
969 } 969 }
970 // This code assumes that setStride() will only be called once per VBO per type. 970 // This code assumes that setStride() will only be called once per VBO per type.
971 S32 delta = new_stride - sTypeOffsets[type]; 971 S32 delta = new_stride - sTypeOffsets[type];
@@ -1020,15 +1020,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
1020 { 1020 {
1021 GLint buff; 1021 GLint buff;
1022 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); 1022 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
1023 if (buff != mGLBuffer) 1023 if ((GLuint)buff != mGLBuffer)
1024 { 1024 {
1025 llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; 1025 llwarns << "Invalid GL vertex buffer bound: " << buff << llendl;
1026 } 1026 }
1027 1027
1028 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); 1028 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
1029 if (buff != mGLIndices) 1029 if ((GLuint)buff != mGLIndices)
1030 { 1030 {
1031 llerrs << "Invalid GL index buffer bound: " << buff << llendl; 1031 llwarns << "Invalid GL index buffer bound: " << buff << llendl;
1032 } 1032 }
1033 } 1033 }
1034 1034
@@ -1038,15 +1038,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
1038 { 1038 {
1039 GLint buff; 1039 GLint buff;
1040 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); 1040 glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
1041 if (buff != mGLBuffer) 1041 if ((GLuint)buff != mGLBuffer)
1042 { 1042 {
1043 llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; 1043 llwarns << "Invalid GL vertex buffer bound: " << buff << llendl;
1044 } 1044 }
1045 1045
1046 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); 1046 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
1047 if (buff != mGLIndices) 1047 if ((GLuint)buff != mGLIndices)
1048 { 1048 {
1049 llerrs << "Invalid GL index buffer bound: " << buff << llendl; 1049 llwarns << "Invalid GL index buffer bound: " << buff << llendl;
1050 } 1050 }
1051 } 1051 }
1052 1052
@@ -1068,7 +1068,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
1068 1068
1069 if (data_mask != 0) 1069 if (data_mask != 0)
1070 { 1070 {
1071 llerrs << "Buffer set for rendering before being filled after resize." << llendl; 1071 llwarns << "Buffer set for rendering before being filled after resize." << llendl;
1072 } 1072 }
1073 } 1073 }
1074 1074
@@ -1129,7 +1129,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
1129 1129
1130 if ((data_mask & mTypeMask) != data_mask) 1130 if ((data_mask & mTypeMask) != data_mask)
1131 { 1131 {
1132 llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; 1132 llwarns << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
1133 } 1133 }
1134 1134
1135 if (data_mask & MAP_NORMAL) 1135 if (data_mask & MAP_NORMAL)