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.cpp148
1 files changed, 121 insertions, 27 deletions
diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp
index 9a392d7..8195eee 100644
--- a/linden/indra/llrender/llimagegl.cpp
+++ b/linden/indra/llrender/llimagegl.cpp
@@ -4,7 +4,7 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$ 5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2001-2008, Linden Research, Inc. 7 * Copyright (c) 2001-2009, 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
@@ -61,8 +61,56 @@ S32 LLImageGL::sCount = 0;
61BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; 61BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
62F32 LLImageGL::sLastFrameTime = 0.f; 62F32 LLImageGL::sLastFrameTime = 0.f;
63 63
64S32 LLImageGL::sMaxTextureSize = 0 ;
65
64std::set<LLImageGL*> LLImageGL::sImageList; 66std::set<LLImageGL*> LLImageGL::sImageList;
65 67
68//**************************************************************************************
69//below are functions for debug use
70//do not delete them even though they are not currently being used.
71void check_all_images()
72{
73 for (std::set<LLImageGL*>::iterator iter = LLImageGL::sImageList.begin();
74 iter != LLImageGL::sImageList.end(); iter++)
75 {
76 LLImageGL* glimage = *iter;
77 if (glimage->getTexName() && glimage->isGLTextureCreated())
78 {
79 gGL.getTexUnit(0)->bind(glimage) ;
80 glimage->checkTexSize() ;
81 gGL.getTexUnit(0)->unbind(glimage->getTarget()) ;
82 }
83 }
84}
85
86void LLImageGL::checkTexSize() const
87{
88 if (gDebugGL && mTarget == GL_TEXTURE_2D)
89 {
90 GLint texname;
91 glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
92 if (texname != mTexName)
93 {
94 llerrs << "Invalid texture bound!" << llendl;
95 }
96 stop_glerror() ;
97 LLGLint x = 0, y = 0 ;
98 glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_WIDTH, (GLint*)&x);
99 glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_HEIGHT, (GLint*)&y) ;
100 stop_glerror() ;
101 if(!x || !y)
102 {
103 return ;
104 }
105 if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
106 {
107 llerrs << "wrong texture size and discard level!" << llendl ;
108 }
109 }
110}
111//end of debug functions
112//**************************************************************************************
113
66//---------------------------------------------------------------------------- 114//----------------------------------------------------------------------------
67 115
68//static 116//static
@@ -148,17 +196,22 @@ void LLImageGL::destroyGL(BOOL save_state)
148 { 196 {
149 gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); 197 gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
150 } 198 }
199
151 for (std::set<LLImageGL*>::iterator iter = sImageList.begin(); 200 for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
152 iter != sImageList.end(); iter++) 201 iter != sImageList.end(); iter++)
153 { 202 {
154 LLImageGL* glimage = *iter; 203 LLImageGL* glimage = *iter;
155 if (glimage->mTexName && glimage->mComponents) 204 if (glimage->mTexName)
156 { 205 {
157 if (save_state && glimage->isInitialized()) 206 if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
158 { 207 {
159 glimage->mSaveData = new LLImageRaw; 208 glimage->mSaveData = new LLImageRaw;
160 glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false); 209 if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false))
210 {
211 glimage->mSaveData = NULL ;
212 }
161 } 213 }
214
162 glimage->destroyGLTexture(); 215 glimage->destroyGLTexture();
163 stop_glerror(); 216 stop_glerror();
164 } 217 }
@@ -172,9 +225,13 @@ void LLImageGL::restoreGL()
172 iter != sImageList.end(); iter++) 225 iter != sImageList.end(); iter++)
173 { 226 {
174 LLImageGL* glimage = *iter; 227 LLImageGL* glimage = *iter;
175 if (glimage->mSaveData.notNull() && glimage->mSaveData->getComponents()) 228 if(glimage->getTexName())
229 {
230 llerrs << "tex name is not 0." << llendl ;
231 }
232 if (glimage->mSaveData.notNull())
176 { 233 {
177 if (glimage->getComponents()) 234 if (glimage->getComponents() && glimage->mSaveData->getComponents())
178 { 235 {
179 glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData); 236 glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData);
180 stop_glerror(); 237 stop_glerror();
@@ -282,7 +339,7 @@ void LLImageGL::init(BOOL usemipmaps)
282 mFormatSwapBytes = FALSE; 339 mFormatSwapBytes = FALSE;
283 mHasExplicitFormat = FALSE; 340 mHasExplicitFormat = FALSE;
284 341
285 mInitialized = true; 342 mGLTextureCreated = FALSE ;
286} 343}
287 344
288void LLImageGL::cleanup() 345void LLImageGL::cleanup()
@@ -321,6 +378,16 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
321{ 378{
322 if (width != mWidth || height != mHeight || ncomponents != mComponents) 379 if (width != mWidth || height != mHeight || ncomponents != mComponents)
323 { 380 {
381 if(width > 1024 || height > 1024)
382 {
383 llwarns << "texture size is big: width: " << width << " height: " << height << llendl ;
384 if(!sMaxTextureSize)
385 {
386 glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&sMaxTextureSize) ;
387 }
388 llwarns << "max texture size is: " << sMaxTextureSize << llendl ;
389 }
390
324 // Check if dimensions are a power of two! 391 // Check if dimensions are a power of two!
325 if (!checkSize(width,height)) 392 if (!checkSize(width,height))
326 { 393 {
@@ -644,7 +711,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
644 mHasMipMaps = FALSE; 711 mHasMipMaps = FALSE;
645 } 712 }
646 stop_glerror(); 713 stop_glerror();
647 mInitialized = true; 714 mGLTextureCreated = true;
648} 715}
649 716
650BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) 717BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
@@ -734,9 +801,8 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
734 801
735 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 802 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
736 stop_glerror(); 803 stop_glerror();
737 mInitialized = true; 804 mGLTextureCreated = true;
738 } 805 }
739
740 return TRUE; 806 return TRUE;
741} 807}
742 808
@@ -751,7 +817,7 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
751 if (gGL.getTexUnit(0)->bind(this, true)) 817 if (gGL.getTexUnit(0)->bind(this, true))
752 { 818 {
753 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); 819 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
754 mInitialized = true; 820 mGLTextureCreated = true;
755 stop_glerror(); 821 stop_glerror();
756 return TRUE; 822 return TRUE;
757 } 823 }
@@ -761,6 +827,36 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
761 } 827 }
762} 828}
763 829
830//create an empty GL texture: just create a texture name
831//the texture is assiciate with some image by calling glTexImage outside LLImageGL
832BOOL LLImageGL::createGLTexture()
833{
834 if (gGLManager.mIsDisabled)
835 {
836 llwarns << "Trying to create a texture while GL is disabled!" << llendl;
837 return FALSE;
838 }
839
840 mGLTextureCreated = false ; //do not save this texture when gl is destroyed.
841
842 llassert(gGLManager.mInited);
843 stop_glerror();
844
845 if(mTexName)
846 {
847 glDeleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
848 }
849
850 glGenTextures(1, (GLuint*)&mTexName);
851 stop_glerror();
852 if (!mTexName)
853 {
854 llerrs << "LLImageGL::createGLTexture failed to make an empty texture" << llendl;
855 }
856
857 return TRUE ;
858}
859
764BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/) 860BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/)
765{ 861{
766 if (gGLManager.mIsDisabled) 862 if (gGLManager.mIsDisabled)
@@ -768,6 +864,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
768 llwarns << "Trying to create a texture while GL is disabled!" << llendl; 864 llwarns << "Trying to create a texture while GL is disabled!" << llendl;
769 return FALSE; 865 return FALSE;
770 } 866 }
867 mGLTextureCreated = false ;
771 llassert(gGLManager.mInited); 868 llassert(gGLManager.mInited);
772 stop_glerror(); 869 stop_glerror();
773 870
@@ -873,7 +970,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
873#endif 970#endif
874 } 971 }
875 972
876 mCurrentDiscardLevel = discard_level; 973 mCurrentDiscardLevel = discard_level;
877 974
878 setImage(data_in, data_hasmips); 975 setImage(data_in, data_hasmips);
879 976
@@ -974,7 +1071,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
974 discard_level = mCurrentDiscardLevel; 1071 discard_level = mCurrentDiscardLevel;
975 } 1072 }
976 1073
977 if (mTexName == 0 || discard_level < mCurrentDiscardLevel) 1074 if (mTexName == 0 || discard_level < mCurrentDiscardLevel || discard_level > mMaxDiscardLevel )
978 { 1075 {
979 return FALSE; 1076 return FALSE;
980 } 1077 }
@@ -985,18 +1082,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
985 gGL.getTexUnit(0)->unbind(mBindTarget); 1082 gGL.getTexUnit(0)->unbind(mBindTarget);
986 llverify(gGL.getTexUnit(0)->bind(this)); 1083 llverify(gGL.getTexUnit(0)->bind(this));
987 1084
988 if (gDebugGL) 1085 //debug code, leave it there commented.
989 { 1086 //checkTexSize() ;
990 if (mTarget == GL_TEXTURE_2D)
991 {
992 GLint texname;
993 glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
994 if (texname != mTexName)
995 {
996 llerrs << "Invalid texture bound!" << llendl;
997 }
998 }
999 }
1000 1087
1001 LLGLint glwidth = 0; 1088 LLGLint glwidth = 0;
1002 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth); 1089 glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth);
@@ -1005,7 +1092,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1005 // No mip data smaller than current discard level 1092 // No mip data smaller than current discard level
1006 return FALSE; 1093 return FALSE;
1007 } 1094 }
1008 1095
1009 S32 width = getWidth(discard_level); 1096 S32 width = getWidth(discard_level);
1010 S32 height = getHeight(discard_level); 1097 S32 height = getHeight(discard_level);
1011 S32 ncomponents = getComponents(); 1098 S32 ncomponents = getComponents();
@@ -1013,6 +1100,13 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1013 { 1100 {
1014 return FALSE; 1101 return FALSE;
1015 } 1102 }
1103 if(width < glwidth)
1104 {
1105 llwarns << "texture size is smaller than it should be." << llendl ;
1106 llwarns << "width: " << width << " glwidth: " << glwidth << " mWidth: " << mWidth <<
1107 " mCurrentDiscardLevel: " << (S32)mCurrentDiscardLevel << " discard_level: " << (S32)discard_level << llendl ;
1108 return FALSE ;
1109 }
1016 1110
1017 if (width <= 0 || width > 2048 || height <= 0 || height > 2048 || ncomponents < 1 || ncomponents > 4) 1111 if (width <= 0 || width > 2048 || height <= 0 || height > 2048 || ncomponents < 1 || ncomponents > 4)
1018 { 1112 {
@@ -1098,7 +1192,7 @@ void LLImageGL::destroyGLTexture()
1098 1192
1099 glDeleteTextures(1, (GLuint*)&mTexName); 1193 glDeleteTextures(1, (GLuint*)&mTexName);
1100 mTexName = 0; 1194 mTexName = 0;
1101 1195 mGLTextureCreated = FALSE ;
1102 stop_glerror(); 1196 stop_glerror();
1103 } 1197 }
1104} 1198}