aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender/llimagegl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llrender/llimagegl.cpp')
-rw-r--r--linden/indra/llrender/llimagegl.cpp451
1 files changed, 260 insertions, 191 deletions
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/*