summaryrefslogtreecommitdiff
path: root/indra/llrender/llimagegl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llimagegl.cpp')
-rwxr-xr-x[-rw-r--r--]indra/llrender/llimagegl.cpp366
1 files changed, 187 insertions, 179 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index a4d7872ec2..ebed454271 100644..100755
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -32,6 +32,7 @@
#include "llimagegl.h"
#include "llerror.h"
+#include "llfasttimer.h"
#include "llimage.h"
#include "llmath.h"
@@ -50,12 +51,10 @@ U32 wpo2(U32 i);
U32 LLImageGL::sUniqueCount = 0;
U32 LLImageGL::sBindCount = 0;
-S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
-S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
-S32 LLImageGL::sCurBoundTextureMemory = 0;
+S32Bytes LLImageGL::sGlobalTextureMemory(0);
+S32Bytes LLImageGL::sBoundTextureMemory(0);
+S32Bytes LLImageGL::sCurBoundTextureMemory(0);
S32 LLImageGL::sCount = 0;
-LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
-U32 LLImageGL::sCurTexName = 1;
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
F32 LLImageGL::sLastFrameTime = 0.f;
@@ -74,6 +73,9 @@ S32 LLImageGL::sCurTexSizeBar = -1 ;
S32 LLImageGL::sCurTexPickSize = -1 ;
S32 LLImageGL::sMaxCategories = 1 ;
+//optimization for when we don't need to calculate mIsMask
+BOOL LLImageGL::sSkipAnalyzeAlpha;
+
//------------------------
//****************************************************************************************************
//End for texture auditing use only
@@ -113,7 +115,7 @@ void LLImageGL::checkTexSize(bool forced) const
BOOL error = FALSE;
if (texname != mTexName)
{
- llinfos << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << llendl;
+ LL_INFOS() << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << LL_ENDL;
error = TRUE;
if (gDebugSession)
@@ -122,7 +124,7 @@ void LLImageGL::checkTexSize(bool forced) const
}
else
{
- llerrs << "Invalid texture bound!" << llendl;
+ LL_ERRS() << "Invalid texture bound!" << LL_ENDL;
}
}
stop_glerror() ;
@@ -146,8 +148,8 @@ void LLImageGL::checkTexSize(bool forced) const
}
else
{
- llerrs << "wrong texture size and discard level: width: " <<
- mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << llendl ;
+ LL_ERRS() << "wrong texture size and discard level: width: " <<
+ mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << LL_ENDL ;
}
}
@@ -169,8 +171,9 @@ BOOL is_little_endian()
return (*c == 0x78) ;
}
//static
-void LLImageGL::initClass(S32 num_catagories)
+void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
{
+ sSkipAnalyzeAlpha = skip_analyze_alpha;
}
//static
@@ -195,7 +198,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
case GL_RGBA: return 32;
case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
default:
- llerrs << "LLImageGL::Unknown format: " << dataformat << llendl;
+ LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
return 0;
}
}
@@ -230,28 +233,28 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
case GL_RGBA: return 4;
case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac
default:
- llerrs << "LLImageGL::Unknown format: " << dataformat << llendl;
+ LL_ERRS() << "LLImageGL::Unknown format: " << dataformat << LL_ENDL;
return 0;
}
}
//----------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_STATS("Image Stats");
+static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_STATS("Image Stats");
// static
void LLImageGL::updateStats(F32 current_time)
{
- LLFastTimer t(FTM_IMAGE_UPDATE_STATS);
+ LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_STATS);
sLastFrameTime = current_time;
- sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
- sCurBoundTextureMemory = 0;
+ sBoundTextureMemory = sCurBoundTextureMemory;
+ sCurBoundTextureMemory = S32Bytes(0);
}
//static
-S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category)
+S32 LLImageGL::updateBoundTexMem(const S32Bytes mem, const S32 ncomponents, S32 category)
{
LLImageGL::sCurBoundTextureMemory += mem ;
- return LLImageGL::sCurBoundTextureMemory;
+ return LLImageGL::sCurBoundTextureMemory.value();
}
//----------------------------------------------------------------------------
@@ -274,8 +277,10 @@ void LLImageGL::destroyGL(BOOL save_state)
if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
{
glimage->mSaveData = new LLImageRaw;
+ glimage->claimMem(glimage->mSaveData);
if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
{
+ glimage->disclaimMem(glimage->mSaveData);
glimage->mSaveData = NULL ;
}
}
@@ -296,7 +301,7 @@ void LLImageGL::restoreGL()
LLImageGL* glimage = *iter;
if(glimage->getTexName())
{
- llerrs << "tex name is not 0." << llendl ;
+ LL_ERRS() << "tex name is not 0." << LL_ENDL ;
}
if (glimage->mSaveData.notNull())
{
@@ -349,7 +354,8 @@ BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, B
//----------------------------------------------------------------------------
LLImageGL::LLImageGL(BOOL usemipmaps)
- : mSaveData(0)
+: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
+ mSaveData(0)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -358,7 +364,8 @@ LLImageGL::LLImageGL(BOOL usemipmaps)
}
LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
- : mSaveData(0)
+: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
+ mSaveData(0)
{
llassert( components <= 4 );
init(usemipmaps);
@@ -368,7 +375,8 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
}
LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
- : mSaveData(0)
+: LLTrace::MemTrackable<LLImageGL>("LLImageGL"),
+ mSaveData(0)
{
init(usemipmaps);
setSize(0, 0, 0);
@@ -382,8 +390,7 @@ LLImageGL::~LLImageGL()
{
LLImageGL::cleanup();
sImageList.erase(this);
- delete [] mPickMask;
- mPickMask = NULL;
+ freePickMask();
sCount--;
}
@@ -393,7 +400,7 @@ void LLImageGL::init(BOOL usemipmaps)
// so that it is obvious by visual inspection if we forgot to
// init a field.
- mTextureMemory = 0;
+ mTextureMemory = (S32Bytes)0;
mLastBindTime = 0.f;
mPickMask = NULL;
@@ -452,6 +459,8 @@ void LLImageGL::cleanup()
{
destroyGLTexture();
}
+ freePickMask();
+
mSaveData = NULL; // deletes data
}
@@ -485,19 +494,17 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
// Check if dimensions are a power of two!
if (!checkSize(width,height))
{
- llerrs << llformat("Texture has non power of two dimension: %dx%d",width,height) << llendl;
+ LL_ERRS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL;
}
if (mTexName)
{
-// llwarns << "Setting Size of LLImageGL with existing mTexName = " << mTexName << llendl;
+// LL_WARNS() << "Setting Size of LLImageGL with existing mTexName = " << mTexName << LL_ENDL;
destroyGLTexture();
}
// pickmask validity depends on old image size, delete it
- delete [] mPickMask;
- mPickMask = NULL;
- mPickMaskWidth = mPickMaskHeight = 0;
+ freePickMask();
mWidth = width;
mHeight = height;
@@ -529,7 +536,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
// virtual
void LLImageGL::dump()
{
- llinfos << "mMaxDiscardLevel " << S32(mMaxDiscardLevel)
+ LL_INFOS() << "mMaxDiscardLevel " << S32(mMaxDiscardLevel)
<< " mLastBindTime " << mLastBindTime
<< " mTarget " << S32(mTarget)
<< " mBindTarget " << S32(mBindTarget)
@@ -544,12 +551,12 @@ void LLImageGL::dump()
#if DEBUG_MISS
<< " mMissed " << mMissed
#endif
- << llendl;
+ << LL_ENDL;
- llinfos << " mTextureMemory " << mTextureMemory
+ LL_INFOS() << " mTextureMemory " << mTextureMemory
<< " mTexNames " << mTexName
<< " mIsResident " << S32(mIsResident)
- << llendl;
+ << LL_ENDL;
}
//----------------------------------------------------------------------------
@@ -558,7 +565,7 @@ void LLImageGL::forceUpdateBindStats(void) const
mLastBindTime = sLastFrameTime;
}
-BOOL LLImageGL::updateBindStats(S32 tex_mem) const
+BOOL LLImageGL::updateBindStats(S32Bytes tex_mem) const
{
if (mTexName != 0)
{
@@ -611,14 +618,16 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
setImage(rawdata, FALSE);
}
+static LLTrace::BlockTimerStatHandle FTM_SET_IMAGE("setImage");
void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
+ LL_RECORD_BLOCK_TIME(FTM_SET_IMAGE);
bool is_compressed = false;
if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
{
is_compressed = true;
}
-
+
if (mUseMipMaps)
@@ -664,7 +673,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
else
{
-// LLFastTimer t2(FTM_TEMP4);
+// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
if(mFormatSwapBytes)
{
@@ -696,7 +705,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
stop_glerror();
{
-// LLFastTimer t2(FTM_TEMP4);
+// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
if(mFormatSwapBytes)
{
@@ -709,9 +718,14 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
mMipLevels = wpo2(llmax(w, h));
- //use legacy mipmap generation mode
- glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
-
+ //use legacy mipmap generation mode (note: making this condional can cause rendering issues)
+ // -- but making it not conditional triggers deprecation warnings when core profile is enabled
+ // (some rendering issues while core profile is enabled are acceptable at this point in time)
+ if (!LLRender::sGLCoreProfile)
+ {
+ glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
+ }
+
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
@@ -726,6 +740,12 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
stop_glerror();
}
+
+ if (LLRender::sGLCoreProfile)
+ {
+ glGenerateMipmap(mTarget);
+ }
+ stop_glerror();
}
}
else
@@ -736,11 +756,16 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
S32 height = getHeight(mCurrentDiscardLevel);
S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;
S32 w = width, h = height;
+
+
+ const U8* new_data = 0;
+ (void)new_data;
+
const U8* prev_mip_data = 0;
const U8* cur_mip_data = 0;
- S32 prev_mip_size = 0;
+#ifdef SHOW_ASSERT
S32 cur_mip_size = 0;
-
+#endif
mMipLevels = nummips;
for (int m=0; m<nummips; m++)
@@ -748,22 +773,36 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
if (m==0)
{
cur_mip_data = data_in;
+#ifdef SHOW_ASSERT
cur_mip_size = width * height * mComponents;
+#endif
}
else
{
S32 bytes = w * h * mComponents;
+#ifdef SHOW_ASSERT
llassert(prev_mip_data);
- llassert(prev_mip_size == bytes*4);
+ llassert(cur_mip_size == bytes*4);
+#endif
U8* new_data = new U8[bytes];
+
+#ifdef SHOW_ASSERT
+ llassert(prev_mip_data);
+ llassert(cur_mip_size == bytes*4);
llassert_always(new_data);
+#endif
+
LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
cur_mip_data = new_data;
+#ifdef SHOW_ASSERT
cur_mip_size = bytes;
+#endif
+
}
llassert(w > 0 && h > 0 && cur_mip_data);
+ (void)cur_mip_data;
{
-// LLFastTimer t1(FTM_TEMP4);
+// LL_RECORD_BLOCK_TIME(FTM_TEMP4);
if(mFormatSwapBytes)
{
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
@@ -792,7 +831,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
delete[] prev_mip_data;
}
prev_mip_data = cur_mip_data;
- prev_mip_size = cur_mip_size;
w >>= 1;
h >>= 1;
}
@@ -805,7 +843,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
else
{
- llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;
+ LL_ERRS() << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << LL_ENDL;
}
}
else
@@ -854,7 +892,7 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
if (gGLManager.mIsDisabled)
{
- llwarns << "Trying to create a texture while GL is disabled!" << llendl;
+ LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
return FALSE;
}
llassert(gGLManager.mInited);
@@ -900,7 +938,7 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
mFormatType = GL_UNSIGNED_BYTE;
break;
default:
- llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
+ LL_ERRS() << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL;
}
}
@@ -944,13 +982,13 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
if (mTexName == 0)
{
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
- //llwarns << "Setting subimage on image without GL texture" << llendl;
+ //LL_WARNS() << "Setting subimage on image without GL texture" << LL_ENDL;
return FALSE;
}
if (datap == NULL)
{
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
- //llwarns << "Setting subimage on image with NULL datap" << llendl;
+ //LL_WARNS() << "Setting subimage on image with NULL datap" << LL_ENDL;
return FALSE;
}
@@ -964,7 +1002,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
if (mUseMipMaps)
{
dump();
- llerrs << "setSubImage called with mipmapped image (not supported)" << llendl;
+ LL_ERRS() << "setSubImage called with mipmapped image (not supported)" << LL_ENDL;
}
llassert_always(mCurrentDiscardLevel == 0);
llassert_always(x_pos >= 0 && y_pos >= 0);
@@ -973,28 +1011,28 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
(y_pos + height) > getHeight())
{
dump();
- llerrs << "Subimage not wholly in target image!"
+ LL_ERRS() << "Subimage not wholly in target image!"
<< " x_pos " << x_pos
<< " y_pos " << y_pos
<< " width " << width
<< " height " << height
<< " getWidth() " << getWidth()
<< " getHeight() " << getHeight()
- << llendl;
+ << LL_ENDL;
}
if ((x_pos + width) > data_width ||
(y_pos + height) > data_height)
{
dump();
- llerrs << "Subimage not wholly in source image!"
+ LL_ERRS() << "Subimage not wholly in source image!"
<< " x_pos " << x_pos
<< " y_pos " << y_pos
<< " width " << width
<< " height " << height
<< " source_width " << data_width
<< " source_height " << data_height
- << llendl;
+ << LL_ENDL;
}
@@ -1010,7 +1048,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
datap += (y_pos * data_width + x_pos) * getComponents();
// Update the GL texture
BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName);
- if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl;
+ if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
stop_glerror();
glTexSubImage2D(mTarget, 0, x_pos, y_pos,
@@ -1053,70 +1091,27 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
}
// static
-void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
+static LLTrace::BlockTimerStatHandle FTM_GENERATE_TEXTURES("generate textures");
+void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
{
- bool empty = true;
-
- dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
-
- if (iter != sDeadTextureList[type].end())
- {
- empty = iter->second.empty();
- }
-
- for (S32 i = 0; i < numTextures; ++i)
- {
- if (!empty)
- {
- textures[i] = iter->second.front();
- iter->second.pop_front();
- empty = iter->second.empty();
- }
- else
- {
- textures[i] = sCurTexName++;
- }
- }
+ LL_RECORD_BLOCK_TIME(FTM_GENERATE_TEXTURES);
+ glGenTextures(numTextures, textures);
}
// static
-void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate)
+void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
{
if (gGLManager.mInited)
{
- if (format == 0 || type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
- { //unknown internal format or unknown number of mip levels, not safe to reuse
- glDeleteTextures(numTextures, textures);
- }
- else
- {
- for (S32 i = 0; i < numTextures; ++i)
- { //remove texture from VRAM by setting its size to zero
- for (S32 j = 0; j <= mip_levels; j++)
- {
- gGL.getTexUnit(0)->bindManual(type, textures[i]);
-
- glTexImage2D(LLTexUnit::getInternalType(type), j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
-
- llassert(std::find(sDeadTextureList[type][format].begin(),
- sDeadTextureList[type][format].end(), textures[i]) ==
- sDeadTextureList[type][format].end());
-
- sDeadTextureList[type][format].push_back(textures[i]);
- }
- }
+ glDeleteTextures(numTextures, textures);
}
-
- /*if (immediate)
- {
- LLImageGL::deleteDeadTextures();
- }*/
}
// static
+static LLTrace::BlockTimerStatHandle FTM_SET_MANUAL_IMAGE("setManualImage");
void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
{
+ LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE);
bool use_scratch = false;
U32* scratch = NULL;
if (LLRender::sGLCoreProfile)
@@ -1203,7 +1198,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
intformat = GL_COMPRESSED_ALPHA;
break;
default:
- llwarns << "Could not compress format: " << std::hex << intformat << llendl;
+ LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL;
break;
}
}
@@ -1220,12 +1215,13 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
//create an empty GL texture: just create a texture name
//the texture is assiciate with some image by calling glTexImage outside LLImageGL
+static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE1("createGLTexture()");
BOOL LLImageGL::createGLTexture()
{
- if (gHeadlessClient) return FALSE;
+ LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE1);
if (gGLManager.mIsDisabled)
{
- llwarns << "Trying to create a texture while GL is disabled!" << llendl;
+ LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
return FALSE;
}
@@ -1236,26 +1232,27 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
- LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ LLImageGL::deleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
}
- LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
+ LLImageGL::generateTextures(1, &mTexName);
stop_glerror();
if (!mTexName)
{
- llerrs << "LLImageGL::createGLTexture failed to make an empty texture" << llendl;
+ LL_ERRS() << "LLImageGL::createGLTexture failed to make an empty texture" << LL_ENDL;
}
return TRUE ;
}
+static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE2("createGLTexture(raw)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
{
- if (gHeadlessClient) return FALSE;
+ LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE2);
if (gGLManager.mIsDisabled)
{
- llwarns << "Trying to create a texture while GL is disabled!" << llendl;
+ LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL;
return FALSE;
}
@@ -1305,7 +1302,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
mFormatType = GL_UNSIGNED_BYTE;
break;
default:
- llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
+ LL_ERRS() << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL;
}
calcAlphaChannelOffsetAndStride() ;
@@ -1324,8 +1321,10 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
return createGLTexture(discard_level, rawdata, FALSE, usename);
}
+static LLTrace::BlockTimerStatHandle FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)");
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
{
+ LL_RECORD_BLOCK_TIME(FTM_CREATE_GL_TEXTURE3);
llassert(data_in);
stop_glerror();
@@ -1352,7 +1351,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
else
{
- LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
+ LLImageGL::generateTextures(1, &mTexName);
stop_glerror();
{
llverify(gGL.getTexUnit(0)->bind(this));
@@ -1365,7 +1364,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
if (!mTexName)
{
- llerrs << "LLImageGL::createGLTexture failed to make texture" << llendl;
+ LL_ERRS() << "LLImageGL::createGLTexture failed to make texture" << LL_ENDL;
}
if (mUseMipMaps)
@@ -1395,15 +1394,17 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
if (old_name != 0)
{
- sGlobalTextureMemoryInBytes -= mTextureMemory;
+ sGlobalTextureMemory -= mTextureMemory;
- LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name);
+ LLImageGL::deleteTextures(1, &old_name);
stop_glerror();
}
- mTextureMemory = getMipBytes(discard_level);
- sGlobalTextureMemoryInBytes += mTextureMemory;
+ disclaimMem(mTextureMemory);
+ mTextureMemory = (S32Bytes)getMipBytes(discard_level);
+ claimMem(mTextureMemory);
+ sGlobalTextureMemory += mTextureMemory;
mTexelsInGLTexture = getWidth() * getHeight() ;
// mark this as bound at this point, so we don't throw it out immediately
@@ -1414,7 +1415,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
{
llassert_always(sAllowReadBackRaw) ;
- //llerrs << "should not call this function!" << llendl ;
+ //LL_ERRS() << "should not call this function!" << LL_ENDL ;
if (discard_level < 0)
{
@@ -1452,15 +1453,15 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
}
if(width < glwidth)
{
- llwarns << "texture size is smaller than it should be." << llendl ;
- llwarns << "width: " << width << " glwidth: " << glwidth << " mWidth: " << mWidth <<
- " mCurrentDiscardLevel: " << (S32)mCurrentDiscardLevel << " discard_level: " << (S32)discard_level << llendl ;
+ LL_WARNS() << "texture size is smaller than it should be." << LL_ENDL ;
+ LL_WARNS() << "width: " << width << " glwidth: " << glwidth << " mWidth: " << mWidth <<
+ " mCurrentDiscardLevel: " << (S32)mCurrentDiscardLevel << " discard_level: " << (S32)discard_level << LL_ENDL ;
return FALSE ;
}
if (width <= 0 || width > 2048 || height <= 0 || height > 2048 || ncomponents < 1 || ncomponents > 4)
{
- llerrs << llformat("LLImageGL::readBackRaw: bogus params: %d x %d x %d",width,height,ncomponents) << llendl;
+ LL_ERRS() << llformat("LLImageGL::readBackRaw: bogus params: %d x %d x %d",width,height,ncomponents) << LL_ENDL;
}
LLGLint is_compressed = 0;
@@ -1473,7 +1474,7 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
GLenum error ;
while((error = glGetError()) != GL_NO_ERROR)
{
- llwarns << "GL Error happens before reading back texture. Error code: " << error << llendl ;
+ LL_WARNS() << "GL Error happens before reading back texture. Error code: " << error << LL_ENDL ;
}
//-----------------------------------------------------------------------------------------------
@@ -1483,8 +1484,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes);
if(!imageraw->allocateDataSize(width, height, ncomponents, glbytes))
{
- llwarns << "Memory allocation failed for reading back texture. Size is: " << glbytes << llendl ;
- llwarns << "width: " << width << "height: " << height << "components: " << ncomponents << llendl ;
+ LL_WARNS() << "Memory allocation failed for reading back texture. Size is: " << glbytes << LL_ENDL ;
+ LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
return FALSE ;
}
@@ -1495,8 +1496,8 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
{
if(!imageraw->allocateDataSize(width, height, ncomponents))
{
- llwarns << "Memory allocation failed for reading back texture." << llendl ;
- llwarns << "width: " << width << "height: " << height << "components: " << ncomponents << llendl ;
+ LL_WARNS() << "Memory allocation failed for reading back texture." << LL_ENDL ;
+ LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ;
return FALSE ;
}
@@ -1507,12 +1508,12 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
//-----------------------------------------------------------------------------------------------
if((error = glGetError()) != GL_NO_ERROR)
{
- llwarns << "GL Error happens after reading back texture. Error code: " << error << llendl ;
+ LL_WARNS() << "GL Error happens after reading back texture. Error code: " << error << LL_ENDL ;
imageraw->deleteData() ;
while((error = glGetError()) != GL_NO_ERROR)
{
- llwarns << "GL Error happens after reading back texture. Error code: " << error << llendl ;
+ LL_WARNS() << "GL Error happens after reading back texture. Error code: " << error << LL_ENDL ;
}
return FALSE ;
@@ -1526,30 +1527,6 @@ void LLImageGL::deleteDeadTextures()
{
bool reset = false;
- /*while (!sDeadTextureList.empty())
- {
- GLuint tex = sDeadTextureList.front();
- sDeadTextureList.pop_front();
- for (int i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- {
- LLTexUnit* tex_unit = gGL.getTexUnit(i);
-
- if (tex_unit && tex_unit->getCurrTexture() == tex)
- {
- tex_unit->unbind(tex_unit->getCurrType());
- stop_glerror();
-
- if (i > 0)
- {
- reset = true;
- }
- }
- }
-
- glDeleteTextures(1, &tex);
- stop_glerror();
- }*/
-
if (reset)
{
gGL.getTexUnit(0)->activate();
@@ -1560,13 +1537,14 @@ void LLImageGL::destroyGLTexture()
{
if (mTexName != 0)
{
- if(mTextureMemory)
+ if(mTextureMemory != S32Bytes(0))
{
- sGlobalTextureMemoryInBytes -= mTextureMemory;
- mTextureMemory = 0;
+ sGlobalTextureMemory -= mTextureMemory;
+ disclaimMem(mTextureMemory);
+ mTextureMemory = (S32Bytes)0;
}
- LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &mTexName);
+ LLImageGL::deleteTextures(1, &mTexName);
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mTexName = 0;
mGLTextureCreated = FALSE ;
@@ -1702,6 +1680,12 @@ BOOL LLImageGL::getBoundRecently() const
return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
}
+BOOL LLImageGL::getIsAlphaMask() const
+{
+ llassert_always(!sSkipAnalyzeAlpha);
+ return mIsMask;
+}
+
void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
{
mTarget = target;
@@ -1790,7 +1774,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
mAlphaOffset < 0 || //unsupported type
(mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation
{
- llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl;
+ LL_WARNS() << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << LL_ENDL;
mNeedsAlphaAndPickMask = FALSE ;
mIsMask = FALSE;
@@ -1799,7 +1783,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
{
- if(!mNeedsAlphaAndPickMask)
+ if(sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)
{
return ;
}
@@ -1899,6 +1883,37 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
}
//----------------------------------------------------------------------------
+U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight)
+{
+ U32 pick_width = pWidth/2 + 1;
+ U32 pick_height = pHeight/2 + 1;
+
+ U32 size = pick_width * pick_height;
+ size = (size + 7) / 8; // pixelcount-to-bits
+ mPickMask = new U8[size];
+ claimMem(size);
+ mPickMaskWidth = pick_width - 1;
+ mPickMaskHeight = pick_height - 1;
+
+ memset(mPickMask, 0, sizeof(U8) * size);
+
+ return size;
+}
+
+//----------------------------------------------------------------------------
+void LLImageGL::freePickMask()
+{
+ // pickmask validity depends on old image size, delete it
+ if (mPickMask != NULL)
+ {
+ disclaimMem((mPickMaskWidth * mPickMaskHeight + 7) / 8);
+ delete [] mPickMask;
+ }
+ mPickMask = NULL;
+ mPickMaskWidth = mPickMaskHeight = 0;
+}
+
+//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
if(!mNeedsAlphaAndPickMask)
@@ -1906,9 +1921,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
return ;
}
- delete [] mPickMask;
- mPickMask = NULL;
- mPickMaskWidth = mPickMaskHeight = 0;
+ freePickMask();
if (mFormatType != GL_UNSIGNED_BYTE ||
mFormatPrimary != GL_RGBA)
@@ -1917,16 +1930,11 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
return;
}
- U32 pick_width = width/2 + 1;
- U32 pick_height = height/2 + 1;
-
- U32 size = pick_width * pick_height;
- size = (size + 7) / 8; // pixelcount-to-bits
- mPickMask = new U8[size];
- mPickMaskWidth = pick_width - 1;
- mPickMaskHeight = pick_height - 1;
-
- memset(mPickMask, 0, sizeof(U8) * size);
+#ifdef SHOW_ASSERT
+ const U32 pickSize = createPickMask(width, height);
+#else // SHOW_ASSERT
+ createPickMask(width, height);
+#endif // SHOW_ASSERT
U32 pick_bit = 0;
@@ -1940,7 +1948,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
U32 pick_idx = pick_bit/8;
U32 pick_offset = pick_bit%8;
- llassert(pick_idx < size);
+ llassert(pick_idx < pickSize);
mPickMask[pick_idx] |= 1 << pick_offset;
}