aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llrender/llimagegl.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-04-30 13:04:20 -0500
committerJacek Antonelli2009-04-30 13:07:16 -0500
commitca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch)
tree8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/llrender/llimagegl.cpp
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz
Second Life viewer sources 1.23.0-RC
Diffstat (limited to '')
-rw-r--r--linden/indra/llrender/llimagegl.cpp315
1 files changed, 210 insertions, 105 deletions
diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp
index 6a142a7..cdf626e 100644
--- a/linden/indra/llrender/llimagegl.cpp
+++ b/linden/indra/llrender/llimagegl.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 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 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 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -62,7 +63,6 @@ BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
62F32 LLImageGL::sLastFrameTime = 0.f; 63F32 LLImageGL::sLastFrameTime = 0.f;
63 64
64std::set<LLImageGL*> LLImageGL::sImageList; 65std::set<LLImageGL*> LLImageGL::sImageList;
65
66//************************************************************************************** 66//**************************************************************************************
67//below are functions for debug use 67//below are functions for debug use
68//do not delete them even though they are not currently being used. 68//do not delete them even though they are not currently being used.
@@ -308,21 +308,21 @@ void LLImageGL::init(BOOL usemipmaps)
308#endif 308#endif
309 309
310 mPickMask = NULL; 310 mPickMask = NULL;
311 mTextureState = NO_DELETE ;
311 mTextureMemory = 0; 312 mTextureMemory = 0;
312 mLastBindTime = 0.f; 313 mLastBindTime = 0.f;
313 314
314 mTarget = GL_TEXTURE_2D; 315 mTarget = GL_TEXTURE_2D;
315 mBindTarget = LLTexUnit::TT_TEXTURE; 316 mBindTarget = LLTexUnit::TT_TEXTURE;
316 mUseMipMaps = usemipmaps; 317 mUseMipMaps = usemipmaps;
317 mHasMipMaps = FALSE; 318 mHasMipMaps = false;
318 mAutoGenMips = FALSE; 319 mAutoGenMips = FALSE;
319 mTexName = 0; 320 mTexName = 0;
320 mIsResident = 0; 321 mIsResident = 0;
321 mClampS = FALSE; 322
322 mClampT = FALSE; 323 mTexOptionsDirty = true;
323 mClampR = FALSE; 324 mAddressMode = LLTexUnit::TAM_WRAP;
324 mMagFilterNearest = FALSE; 325 mFilterOption = LLTexUnit::TFO_ANISOTROPIC;
325 mMinFilterNearest = FALSE;
326 mWidth = 0; 326 mWidth = 0;
327 mHeight = 0; 327 mHeight = 0;
328 mComponents = 0; 328 mComponents = 0;
@@ -338,6 +338,7 @@ void LLImageGL::init(BOOL usemipmaps)
338 mHasExplicitFormat = FALSE; 338 mHasExplicitFormat = FALSE;
339 339
340 mGLTextureCreated = FALSE ; 340 mGLTextureCreated = FALSE ;
341 mIsMask = FALSE;
341} 342}
342 343
343void LLImageGL::cleanup() 344void LLImageGL::cleanup()
@@ -468,6 +469,11 @@ bool LLImageGL::bindDefaultImage(const S32 stage) const
468 return false; 469 return false;
469} 470}
470 471
472//virtual
473void LLImageGL::forceImmediateUpdate()
474{
475 return ;
476}
471 477
472void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) 478void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes )
473{ 479{
@@ -497,17 +503,15 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
497void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) 503void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
498{ 504{
499// LLFastTimer t1(LLFastTimer::FTM_TEMP1); 505// LLFastTimer t1(LLFastTimer::FTM_TEMP1);
500 506 llpushcallstacks ;
501 bool is_compressed = false; 507 bool is_compressed = false;
502 if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) 508 if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
503 { 509 {
504 is_compressed = true; 510 is_compressed = true;
505 } 511 }
506 512
507 {
508// LLFastTimer t2(LLFastTimer::FTM_TEMP2); 513// LLFastTimer t2(LLFastTimer::FTM_TEMP2);
509 llverify(gGL.getTexUnit(0)->bind(this)); 514 gGL.getTexUnit(0)->bind(this);
510 }
511 515
512 if (mUseMipMaps) 516 if (mUseMipMaps)
513 { 517 {
@@ -518,6 +522,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
518 // are stored BEFORE the largest image 522 // are stored BEFORE the largest image
519 for (S32 d=mCurrentDiscardLevel; d<=mMaxDiscardLevel; d++) 523 for (S32 d=mCurrentDiscardLevel; d<=mMaxDiscardLevel; d++)
520 { 524 {
525
521 S32 w = getWidth(d); 526 S32 w = getWidth(d);
522 S32 h = getHeight(d); 527 S32 h = getHeight(d);
523 S32 gl_level = d-mCurrentDiscardLevel; 528 S32 gl_level = d-mCurrentDiscardLevel;
@@ -528,7 +533,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
528 if (is_compressed) 533 if (is_compressed)
529 { 534 {
530// LLFastTimer t2(LLFastTimer::FTM_TEMP4); 535// LLFastTimer t2(LLFastTimer::FTM_TEMP4);
531 S32 tex_size = dataFormatBytes(mFormatPrimary, w, h); 536 S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
532 glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in); 537 glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
533 stop_glerror(); 538 stop_glerror();
534 } 539 }
@@ -542,7 +547,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
542 stop_glerror(); 547 stop_glerror();
543 } 548 }
544 549
545 glTexImage2D(mTarget, gl_level, mFormatInternal, w, h, 0, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in); 550 LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
551 if (gl_level == 0)
552 {
553 analyzeAlpha(data_in, w, h);
554 }
546 updatePickMask(w, h, data_in); 555 updatePickMask(w, h, data_in);
547 556
548 if(mFormatSwapBytes) 557 if(mFormatSwapBytes)
@@ -574,10 +583,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
574 S32 w = getWidth(mCurrentDiscardLevel); 583 S32 w = getWidth(mCurrentDiscardLevel);
575 S32 h = getHeight(mCurrentDiscardLevel); 584 S32 h = getHeight(mCurrentDiscardLevel);
576 585
577 glTexImage2D(mTarget, 0, mFormatInternal, 586 LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
578 w, h, 0, 587 w, h,
579 mFormatPrimary, mFormatType, 588 mFormatPrimary, mFormatType,
580 data_in); 589 data_in);
590 analyzeAlpha(data_in, w, h);
581 stop_glerror(); 591 stop_glerror();
582 592
583 updatePickMask(w, h, data_in); 593 updatePickMask(w, h, data_in);
@@ -629,7 +639,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
629 stop_glerror(); 639 stop_glerror();
630 } 640 }
631 641
632 glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data); 642 LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
643 if (m == 0)
644 {
645 analyzeAlpha(data_in, w, h);
646 }
633 stop_glerror(); 647 stop_glerror();
634 if (m == 0) 648 if (m == 0)
635 { 649 {
@@ -662,7 +676,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
662 { 676 {
663 llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; 677 llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;
664 } 678 }
665 mHasMipMaps = TRUE; 679 mHasMipMaps = true;
666 } 680 }
667 else 681 else
668 { 682 {
@@ -683,8 +697,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
683 stop_glerror(); 697 stop_glerror();
684 } 698 }
685 699
686 glTexImage2D(mTarget, 0, mFormatInternal, w, h, 0, 700 LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
687 mFormatPrimary, mFormatType, (GLvoid *)data_in); 701 mFormatPrimary, mFormatType, (GLvoid *)data_in);
702 analyzeAlpha(data_in, w, h);
703
688 updatePickMask(w, h, data_in); 704 updatePickMask(w, h, data_in);
689 705
690 stop_glerror(); 706 stop_glerror();
@@ -696,14 +712,16 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
696 } 712 }
697 713
698 } 714 }
699 mHasMipMaps = FALSE; 715 mHasMipMaps = false;
700 } 716 }
701 stop_glerror(); 717 stop_glerror();
702 mGLTextureCreated = true; 718 mGLTextureCreated = true;
719 llpushcallstacks ;
703} 720}
704 721
705BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) 722BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
706{ 723{
724 llpushcallstacks ;
707 if (!width || !height) 725 if (!width || !height)
708 { 726 {
709 return TRUE; 727 return TRUE;
@@ -779,6 +797,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
779 797
780 glTexSubImage2D(mTarget, 0, x_pos, y_pos, 798 glTexSubImage2D(mTarget, 0, x_pos, y_pos,
781 width, height, mFormatPrimary, mFormatType, datap); 799 width, height, mFormatPrimary, mFormatType, datap);
800 gGL.getTexUnit(0)->disable();
782 stop_glerror(); 801 stop_glerror();
783 802
784 if(mFormatSwapBytes) 803 if(mFormatSwapBytes)
@@ -791,6 +810,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
791 stop_glerror(); 810 stop_glerror();
792 mGLTextureCreated = true; 811 mGLTextureCreated = true;
793 } 812 }
813 llpushcallstacks ;
794 return TRUE; 814 return TRUE;
795} 815}
796 816
@@ -815,6 +835,24 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
815 } 835 }
816} 836}
817 837
838// static
839void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
840{
841 glGenTextures(numTextures, (GLuint*)textures);
842}
843
844// static
845void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
846{
847 glDeleteTextures(numTextures, (GLuint*)textures);
848}
849
850// static
851void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
852{
853 glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
854}
855
818//create an empty GL texture: just create a texture name 856//create an empty GL texture: just create a texture name
819//the texture is assiciate with some image by calling glTexImage outside LLImageGL 857//the texture is assiciate with some image by calling glTexImage outside LLImageGL
820BOOL LLImageGL::createGLTexture() 858BOOL LLImageGL::createGLTexture()
@@ -847,6 +885,7 @@ BOOL LLImageGL::createGLTexture()
847 885
848BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/) 886BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/)
849{ 887{
888 llpushcallstacks ;
850 if (gGLManager.mIsDisabled) 889 if (gGLManager.mIsDisabled)
851 { 890 {
852 llwarns << "Trying to create a texture while GL is disabled!" << llendl; 891 llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -907,6 +946,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
907 946
908BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) 947BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
909{ 948{
949 llpushcallstacks ;
910 llassert(data_in); 950 llassert(data_in);
911 951
912 if (discard_level < 0) 952 if (discard_level < 0)
@@ -923,7 +963,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
923 return TRUE; 963 return TRUE;
924 } 964 }
925 965
926 GLuint old_name = mTexName; 966 U32 old_name = mTexName;
927// S32 old_discard = mCurrentDiscardLevel; 967// S32 old_discard = mCurrentDiscardLevel;
928 968
929 if (usename != 0) 969 if (usename != 0)
@@ -932,7 +972,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
932 } 972 }
933 else 973 else
934 { 974 {
935 glGenTextures(1, (GLuint*)&mTexName); 975 LLImageGL::generateTextures(1, &mTexName);
936 stop_glerror(); 976 stop_glerror();
937 { 977 {
938// LLFastTimer t1(LLFastTimer::FTM_TEMP6); 978// LLFastTimer t1(LLFastTimer::FTM_TEMP6);
@@ -962,9 +1002,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
962 1002
963 setImage(data_in, data_hasmips); 1003 setImage(data_in, data_hasmips);
964 1004
965 setClamp(mClampS, mClampT); 1005 // Set texture options to our defaults.
966 setMipFilterNearest(mMagFilterNearest); 1006 gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
967 1007 gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
1008 gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
1009
968 // things will break if we don't unbind after creation 1010 // things will break if we don't unbind after creation
969 gGL.getTexUnit(0)->unbind(mBindTarget); 1011 gGL.getTexUnit(0)->unbind(mBindTarget);
970 stop_glerror(); 1012 stop_glerror();
@@ -972,16 +1014,18 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
972 if (old_name != 0) 1014 if (old_name != 0)
973 { 1015 {
974 sGlobalTextureMemory -= mTextureMemory; 1016 sGlobalTextureMemory -= mTextureMemory;
975 glDeleteTextures(1, &old_name); 1017 LLImageGL::deleteTextures(1, &old_name);
976 stop_glerror(); 1018 stop_glerror();
977 } 1019 }
978 1020
979 mTextureMemory = getMipBytes(discard_level); 1021 mTextureMemory = getMipBytes(discard_level);
980 sGlobalTextureMemory += mTextureMemory; 1022 sGlobalTextureMemory += mTextureMemory;
981 1023 setActive() ;
1024
982 // mark this as bound at this point, so we don't throw it out immediately 1025 // mark this as bound at this point, so we don't throw it out immediately
983 mLastBindTime = sLastFrameTime; 1026 mLastBindTime = sLastFrameTime;
984 1027
1028 llpushcallstacks ;
985 return TRUE; 1029 return TRUE;
986} 1030}
987 1031
@@ -1054,6 +1098,7 @@ BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_h
1054 1098
1055BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) 1099BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok)
1056{ 1100{
1101 llpushcallstacks ;
1057 if (discard_level < 0) 1102 if (discard_level < 0)
1058 { 1103 {
1059 discard_level = mCurrentDiscardLevel; 1104 discard_level = mCurrentDiscardLevel;
@@ -1068,7 +1113,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1068 1113
1069 //explicitly unbind texture 1114 //explicitly unbind texture
1070 gGL.getTexUnit(0)->unbind(mBindTarget); 1115 gGL.getTexUnit(0)->unbind(mBindTarget);
1071 llverify(gGL.getTexUnit(0)->bind(this)); 1116 llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName));
1072 1117
1073 //debug code, leave it there commented. 1118 //debug code, leave it there commented.
1074 //checkTexSize() ; 1119 //checkTexSize() ;
@@ -1156,7 +1201,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
1156 return FALSE ; 1201 return FALSE ;
1157 } 1202 }
1158 //----------------------------------------------------------------------------------------------- 1203 //-----------------------------------------------------------------------------------------------
1159 1204 llpushcallstacks ;
1160 return TRUE ; 1205 return TRUE ;
1161} 1206}
1162 1207
@@ -1178,8 +1223,10 @@ void LLImageGL::destroyGLTexture()
1178 sGlobalTextureMemory -= mTextureMemory; 1223 sGlobalTextureMemory -= mTextureMemory;
1179 mTextureMemory = 0; 1224 mTextureMemory = 0;
1180 1225
1181 glDeleteTextures(1, (GLuint*)&mTexName); 1226 LLImageGL::deleteTextures(1, &mTexName);
1227 mTextureState = DELETED ;
1182 mTexName = 0; 1228 mTexName = 0;
1229 mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
1183 mGLTextureCreated = FALSE ; 1230 mGLTextureCreated = FALSE ;
1184 stop_glerror(); 1231 stop_glerror();
1185 } 1232 }
@@ -1187,89 +1234,35 @@ void LLImageGL::destroyGLTexture()
1187 1234
1188//---------------------------------------------------------------------------- 1235//----------------------------------------------------------------------------
1189 1236
1190void LLImageGL::glClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr) 1237void LLImageGL::setAddressMode(LLTexUnit::eTextureAddressMode mode)
1191{ 1238{
1192 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); 1239 if (mAddressMode != mode)
1193 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1194 glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT);
1195}
1196
1197void LLImageGL::glClamp (BOOL clamps, BOOL clampt)
1198{
1199 if (mTexName != 0)
1200 { 1240 {
1201 glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_S, clamps ? GL_CLAMP_TO_EDGE : GL_REPEAT); 1241 mTexOptionsDirty = true;
1202 glTexParameteri (LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_WRAP_T, clampt ? GL_CLAMP_TO_EDGE : GL_REPEAT); 1242 mAddressMode = mode;
1203 } 1243 }
1204}
1205
1206void LLImageGL::setClampCubemap (BOOL clamps, BOOL clampt, BOOL clampr)
1207{
1208 mClampS = clamps;
1209 mClampT = clampt;
1210 mClampR = clampr;
1211 glClampCubemap (clamps, clampt, clampr);
1212}
1213 1244
1214void LLImageGL::setClamp(BOOL clamps, BOOL clampt) 1245 if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
1215{ 1246 {
1216 mClampS = clamps; 1247 gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureAddressMode(mode);
1217 mClampT = clampt; 1248 mTexOptionsDirty = false;
1218 glClamp (clamps, clampt); 1249 }
1219}
1220
1221void LLImageGL::overrideClamp (BOOL clamps, BOOL clampt)
1222{
1223 glClamp (clamps, clampt);
1224}
1225
1226void LLImageGL::restoreClamp (void)
1227{
1228 glClamp (mClampS, mClampT);
1229} 1250}
1230 1251
1231void LLImageGL::setMipFilterNearest(BOOL mag_nearest, BOOL min_nearest) 1252void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
1232{ 1253{
1233 mMagFilterNearest = mag_nearest; 1254 if (mFilterOption != option)
1234 mMinFilterNearest = min_nearest; 1255 {
1256 mTexOptionsDirty = true;
1257 mFilterOption = option;
1258 }
1235 1259
1236 if (mTexName != 0) 1260 if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
1237 { 1261 {
1238 if (mMinFilterNearest) 1262 gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option);
1239 { 1263 mTexOptionsDirty = false;
1240 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1264 }
1241 } 1265 stop_glerror();
1242 else if (mHasMipMaps)
1243 {
1244 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1245 }
1246 else
1247 {
1248 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1249 }
1250 if (mMagFilterNearest)
1251 {
1252 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1253 }
1254 else
1255 {
1256 glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1257 }
1258 if (gGLManager.mHasAnisotropic)
1259 {
1260 if (sGlobalUseAnisotropic && !mMagFilterNearest)
1261 {
1262 F32 largest_anisotropy;
1263 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_anisotropy);
1264 glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_anisotropy);
1265 }
1266 else
1267 {
1268 glTexParameterf(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
1269 }
1270 }
1271 stop_glerror();
1272 }
1273} 1266}
1274 1267
1275BOOL LLImageGL::getIsResident(BOOL test_now) 1268BOOL LLImageGL::getIsResident(BOOL test_now)
@@ -1356,6 +1349,118 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b
1356 mBindTarget = bind_target; 1349 mBindTarget = bind_target;
1357} 1350}
1358 1351
1352void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
1353{
1354 if (mFormatType != GL_UNSIGNED_BYTE)
1355 {
1356 llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl;
1357 }
1358
1359 U32 stride = 0;
1360 switch (mFormatPrimary)
1361 {
1362 case GL_LUMINANCE:
1363 case GL_ALPHA:
1364 stride = 1;
1365 break;
1366 case GL_LUMINANCE_ALPHA:
1367 stride = 2;
1368 break;
1369 case GL_RGB:
1370 //no alpha
1371 mIsMask = FALSE;
1372 return;
1373 case GL_RGBA:
1374 stride = 4;
1375 break;
1376 case GL_BGRA_EXT:
1377 stride = 4;
1378 break;
1379 default:
1380 llwarns << "Cannot analyze alpha of image with primary format " << std::hex << mFormatPrimary << std::dec << llendl;
1381 return;
1382 }
1383
1384 U32 length = w * h;
1385 const GLubyte* current = ((const GLubyte*) data_in)+stride-1;
1386
1387 S32 sample[16];
1388 memset(sample, 0, sizeof(S32)*16);
1389
1390 for (U32 i = 0; i < length; i++)
1391 {
1392 ++sample[*current/16];
1393 current += stride;
1394 }
1395
1396 U32 total = 0;
1397 for (U32 i = 4; i < 11; i++)
1398 {
1399 total += sample[i];
1400 }
1401
1402 if (total > length/16)
1403 {
1404 mIsMask = FALSE;
1405 }
1406 else
1407 {
1408 mIsMask = TRUE;
1409 }
1410}
1411
1412BOOL LLImageGL::isDeleted()
1413{
1414 return mTextureState == DELETED ;
1415}
1416
1417BOOL LLImageGL::isInactive()
1418{
1419 return mTextureState == INACTIVE ;
1420}
1421
1422BOOL LLImageGL::isDeletionCandidate()
1423{
1424 return mTextureState == DELETION_CANDIDATE ;
1425}
1426
1427void LLImageGL::setDeletionCandidate()
1428{
1429 if(mTexName && (mTextureState == INACTIVE))
1430 {
1431 mTextureState = DELETION_CANDIDATE ;
1432 }
1433}
1434
1435void LLImageGL::forceActive()
1436{
1437 mTextureState = ACTIVE ;
1438}
1439
1440void LLImageGL::setActive()
1441{
1442 if(mTextureState != NO_DELETE)
1443 {
1444 mTextureState = ACTIVE ;
1445 }
1446}
1447
1448//set the texture inactive
1449void LLImageGL::setInactive()
1450{
1451 if(mTexName && (mTextureState == ACTIVE) && !getBoundRecently())
1452 {
1453 mTextureState = INACTIVE ;
1454 }
1455}
1456
1457//set the texture to stay in memory
1458void LLImageGL::setNoDelete()
1459{
1460 mTextureState = NO_DELETE ;
1461}
1462
1463//----------------------------------------------------------------------------
1359void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) 1464void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
1360{ 1465{
1361 if (mFormatType != GL_UNSIGNED_BYTE || 1466 if (mFormatType != GL_UNSIGNED_BYTE ||
@@ -1468,7 +1573,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
1468 llassert(w > 0 && h > 0 && cur_mip_data); 1573 llassert(w > 0 && h > 0 && cur_mip_data);
1469 U8 test = cur_mip_data[w*h*mComponents-1]; 1574 U8 test = cur_mip_data[w*h*mComponents-1];
1470 { 1575 {
1471 glTexImage2D(mTarget, m, mFormatInternal, w, h, 0, mFormatPrimary, mFormatType, cur_mip_data); 1576 LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
1472 stop_glerror(); 1577 stop_glerror();
1473 } 1578 }
1474 if (prev_mip_data && prev_mip_data != rawdata) 1579 if (prev_mip_data && prev_mip_data != rawdata)