summaryrefslogtreecommitdiff
path: root/indra/newview/llviewertexture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewertexture.cpp')
-rw-r--r--indra/newview/llviewertexture.cpp366
1 files changed, 241 insertions, 125 deletions
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 075588d577..e3ac56d0d3 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -182,6 +182,7 @@ void LLViewerTextureManager::findFetchedTextures(const LLUUID& id, std::vector<L
void LLViewerTextureManager::findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
std::vector<LLViewerFetchedTexture*> fetched_output;
gTextureList.findTexturesByID(id, fetched_output);
std::vector<LLViewerFetchedTexture*>::iterator iter = fetched_output.begin();
@@ -206,6 +207,7 @@ void LLViewerTextureManager::findTextures(const LLUUID& id, std::vector<LLViewe
LLViewerFetchedTexture* LLViewerTextureManager::findFetchedTexture(const LLUUID& id, S32 tex_type)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
return gTextureList.findImage(id, (ETexListType)tex_type);
}
@@ -477,11 +479,10 @@ const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f;
F32 texmem_lower_bound_scale = 0.85f;
F32 texmem_middle_bound_scale = 0.925f;
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check");
-
//static
bool LLViewerTexture::isMemoryForTextureLow()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Note: we need to figure out a better source for 'min' values,
// what is free for low end at minimal settings is 'nothing left'
// for higher end gpus at high settings.
@@ -498,6 +499,7 @@ bool LLViewerTexture::isMemoryForTextureLow()
//static
bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50);
const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200);
@@ -511,10 +513,12 @@ bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
//static
void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static LLFrameTimer timer;
+
static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
static S32Megabytes physical_res = S32Megabytes(S32_MAX);
-
+
if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
{
gpu = gpu_res;
@@ -523,48 +527,31 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
}
timer.reset();
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
-
- if (gGLManager.mHasATIMemInfo)
{
- S32 meminfo[4];
- glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
- gpu_res = (S32Megabytes)meminfo[0];
-
+ gpu_res = (S32Megabytes) LLImageGLThread::getFreeVRAMMegabytes();
+
//check main memory, only works for windows.
LLMemory::updateMemoryInfo();
physical_res = LLMemory::getAvailableMemKB();
- }
- else if (gGLManager.mHasNVXMemInfo)
- {
- S32 free_memory;
- glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
- gpu_res = (S32Megabytes)(free_memory / 1024);
- }
- gpu = gpu_res;
- physical = physical_res;
+ gpu = gpu_res;
+ physical = physical_res;
+ }
}
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media");
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_TEST("Test");
-
//static
-void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
+void LLViewerTexture::updateClass()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
sCurrentTime = gFrameTimeSeconds;
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
if (tester)
{
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_UPDATE_TEST);
tester->update();
}
- {
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_UPDATE_MEDIA);
- LLViewerMediaTexture::updateClass();
- }
+ LLViewerMediaTexture::updateClass();
sBoundTextureMemory = LLImageGL::sBoundTextureMemory;
sTotalTextureMemory = LLImageGL::sGlobalTextureMemory;
@@ -680,6 +667,9 @@ void LLViewerTexture::init(bool firstinit)
mVolumeList[LLRender::LIGHT_TEX].clear();
mVolumeList[LLRender::SCULPT_TEX].clear();
+
+ mMainQueue = LL::WorkQueue::getInstance("mainloop");
+ mImageQueue = LL::WorkQueue::getInstance("LLImageGL");
}
//virtual
@@ -701,6 +691,7 @@ void LLViewerTexture::cleanup()
void LLViewerTexture::notifyAboutCreatingTexture()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
for(U32 f = 0; f < mNumFaces[ch]; f++)
@@ -712,6 +703,7 @@ void LLViewerTexture::notifyAboutCreatingTexture()
void LLViewerTexture::notifyAboutMissingAsset()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
{
for(U32 f = 0; f < mNumFaces[ch]; f++)
@@ -724,6 +716,7 @@ void LLViewerTexture::notifyAboutMissingAsset()
// virtual
void LLViewerTexture::dump()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLGLTexture::dump();
LL_INFOS() << "LLViewerTexture"
@@ -759,6 +752,7 @@ bool LLViewerTexture::isActiveFetching()
bool LLViewerTexture::bindDebugImage(const S32 stage)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (stage < 0) return false;
bool res = true;
@@ -777,6 +771,7 @@ bool LLViewerTexture::bindDebugImage(const S32 stage)
bool LLViewerTexture::bindDefaultImage(S32 stage)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (stage < 0) return false;
bool res = true;
@@ -819,6 +814,7 @@ void LLViewerTexture::forceImmediateUpdate()
void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if(needs_gltexture)
{
mNeedsGLTexture = TRUE;
@@ -829,14 +825,14 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
{
//flag to reset the values because the old values are used.
resetMaxVirtualSizeResetCounter();
- mMaxVirtualSize = virtual_size;
- mAdditionalDecodePriority = 0.f;
+ mMaxVirtualSize = virtual_size;
+ mAdditionalDecodePriority = 0.f;
mNeedsGLTexture = needs_gltexture;
}
else if (virtual_size > mMaxVirtualSize)
{
mMaxVirtualSize = virtual_size;
- }
+ }
}
void LLViewerTexture::resetTextureStats()
@@ -861,6 +857,7 @@ void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
//virtual
void LLViewerTexture::addFace(U32 ch, LLFace* facep)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mNumFaces[ch] >= mFaceList[ch].size())
@@ -876,6 +873,7 @@ void LLViewerTexture::addFace(U32 ch, LLFace* facep)
//virtual
void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
if(mNumFaces[ch] > 1)
@@ -916,6 +914,7 @@ S32 LLViewerTexture::getNumFaces(U32 ch) const
//virtual
void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (mNumVolumes[ch] >= mVolumeList[ch].size())
{
mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1);
@@ -929,6 +928,7 @@ void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
//virtual
void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (mNumVolumes[ch] > 1)
{
S32 index = volumep->getIndexInTex(ch);
@@ -952,6 +952,7 @@ S32 LLViewerTexture::getNumVolumes(U32 ch) const
void LLViewerTexture::reorganizeFaceList()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
@@ -975,6 +976,7 @@ void LLViewerTexture::reorganizeFaceList()
void LLViewerTexture::reorganizeVolumeList()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static const F32 MAX_WAIT_TIME = 20.f; // seconds
static const U32 MAX_EXTRA_BUFFER_SIZE = 4;
@@ -1177,6 +1179,7 @@ FTType LLViewerFetchedTexture::getFTType() const
void LLViewerFetchedTexture::cleanup()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
iter != mLoadedCallbackList.end(); )
{
@@ -1202,6 +1205,7 @@ void LLViewerFetchedTexture::cleanup()
//access the fast cache
void LLViewerFetchedTexture::loadFromFastCache()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if(!mInFastCacheList)
{
return; //no need to access the fast cache.
@@ -1347,6 +1351,7 @@ void LLViewerFetchedTexture::dump()
// ONLY called from LLViewerFetchedTextureList
void LLViewerFetchedTexture::destroyTexture()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory.
{
return ;
@@ -1363,6 +1368,7 @@ void LLViewerFetchedTexture::destroyTexture()
void LLViewerFetchedTexture::addToCreateTexture()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
bool force_update = false;
if (getComponents() != mRawImage->getComponents())
{
@@ -1404,6 +1410,7 @@ void LLViewerFetchedTexture::addToCreateTexture()
}
else
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
#if 1
//
//if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up,
@@ -1448,99 +1455,104 @@ void LLViewerFetchedTexture::addToCreateTexture()
}
}
#endif
- mNeedsCreateTexture = TRUE;
- gTextureList.mCreateTextureList.insert(this);
- }
+ scheduleCreateTexture();
+ }
return;
}
// ONLY called from LLViewerTextureList
-BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
+BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/)
{
- if (!mNeedsCreateTexture)
- {
- destroyRawImage();
- return FALSE;
- }
- mNeedsCreateTexture = FALSE;
- if (mRawImage.isNull())
- {
- LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL;
- }
- if (mRawImage->isBufferInvalid())
- {
- LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL;
- destroyRawImage();
- return FALSE;
- }
-// LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
-// mRawDiscardLevel,
-// mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
-// << mID.getString() << LL_ENDL;
- BOOL res = TRUE;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+#if LL_IMAGEGL_THREAD_CHECK
+ mGLTexturep->checkActiveThread();
+#endif
- // store original size only for locally-sourced images
- if (mUrl.compare(0, 7, "file://") == 0)
- {
- mOrigWidth = mRawImage->getWidth();
- mOrigHeight = mRawImage->getHeight();
+ if (!mNeedsCreateTexture)
+ {
+ destroyRawImage();
+ return FALSE;
+ }
+ mNeedsCreateTexture = FALSE;
+
+ if (mRawImage.isNull())
+ {
+ LL_ERRS() << "LLViewerTexture trying to create texture with no Raw Image" << LL_ENDL;
+ }
+ if (mRawImage->isBufferInvalid())
+ {
+ LL_WARNS() << "Can't create a texture: invalid image data" << LL_ENDL;
+ destroyRawImage();
+ return FALSE;
+ }
+ // LL_INFOS() << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
+ // mRawDiscardLevel,
+ // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
+ // << mID.getString() << LL_ENDL;
+ BOOL res = TRUE;
+
+ // store original size only for locally-sourced images
+ if (mUrl.compare(0, 7, "file://") == 0)
+ {
+ mOrigWidth = mRawImage->getWidth();
+ mOrigHeight = mRawImage->getHeight();
// This is only safe because it's a local image and fetcher doesn't use raw data
// from local images, but this might become unsafe in case of changes to fetcher
- if (mBoostLevel == BOOST_PREVIEW)
- {
- mRawImage->biasedScaleToPowerOfTwo(1024);
- }
- else
- { // leave black border, do not scale image content
- mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
- }
-
- mFullWidth = mRawImage->getWidth();
- mFullHeight = mRawImage->getHeight();
- setTexelsPerImage();
- }
- else
- {
- mOrigWidth = mFullWidth;
- mOrigHeight = mFullHeight;
- }
+ if (mBoostLevel == BOOST_PREVIEW)
+ {
+ mRawImage->biasedScaleToPowerOfTwo(1024);
+ }
+ else
+ { // leave black border, do not scale image content
+ mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
+ }
- bool size_okay = true;
+ mFullWidth = mRawImage->getWidth();
+ mFullHeight = mRawImage->getHeight();
+ setTexelsPerImage();
+ }
+ else
+ {
+ mOrigWidth = mFullWidth;
+ mOrigHeight = mFullHeight;
+ }
- S32 discard_level = mRawDiscardLevel;
- if (mRawDiscardLevel < 0)
- {
- LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
- discard_level = 0;
- }
+ bool size_okay = true;
- U32 raw_width = mRawImage->getWidth() << discard_level;
- U32 raw_height = mRawImage->getHeight() << discard_level;
+ S32 discard_level = mRawDiscardLevel;
+ if (mRawDiscardLevel < 0)
+ {
+ LL_DEBUGS() << "Negative raw discard level when creating image: " << mRawDiscardLevel << LL_ENDL;
+ discard_level = 0;
+ }
- if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
- {
- LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL;
- size_okay = false;
- }
-
- if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
- {
- // A non power-of-two image was uploaded (through a non standard client)
- LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL;
- size_okay = false;
- }
-
- if( !size_okay )
- {
- // An inappropriately-sized image was uploaded (through a non standard client)
- // We treat these images as missing assets which causes them to
- // be renderd as 'missing image' and to stop requesting data
- LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL;
- setIsMissingAsset();
- destroyRawImage();
- return FALSE;
- }
+ U32 raw_width = mRawImage->getWidth() << discard_level;
+ U32 raw_height = mRawImage->getHeight() << discard_level;
+
+ if (raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE)
+ {
+ LL_INFOS() << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << LL_ENDL;
+ size_okay = false;
+ }
+
+ if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
+ {
+ // A non power-of-two image was uploaded (through a non standard client)
+ LL_INFOS() << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << LL_ENDL;
+ size_okay = false;
+ }
+
+ if (!size_okay)
+ {
+ // An inappropriately-sized image was uploaded (through a non standard client)
+ // We treat these images as missing assets which causes them to
+ // be renderd as 'missing image' and to stop requesting data
+ LL_WARNS() << "!size_ok, setting as missing" << LL_ENDL;
+ setIsMissingAsset();
+ destroyRawImage();
+ return FALSE;
+ }
if (mGLTexturep->getHasExplicitFormat())
{
@@ -1562,19 +1574,116 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
}
}
- res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+ return res;
+}
- notifyAboutCreatingTexture();
+BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
+{
+ if (!mNeedsCreateTexture)
+ {
+ return FALSE;
+ }
- setActive();
+ BOOL res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
+
+ return res;
+}
- if (!needsToSaveRawImage())
- {
- mNeedsAux = FALSE;
- destroyRawImage();
- }
+void LLViewerFetchedTexture::postCreateTexture()
+{
+ if (!mNeedsCreateTexture)
+ {
+ return;
+ }
+#if LL_IMAGEGL_THREAD_CHECK
+ mGLTexturep->checkActiveThread();
+#endif
- return res;
+ notifyAboutCreatingTexture();
+
+ setActive();
+
+ if (!needsToSaveRawImage())
+ {
+ mNeedsAux = FALSE;
+ destroyRawImage();
+ }
+
+ mNeedsCreateTexture = FALSE;
+}
+
+void LLViewerFetchedTexture::scheduleCreateTexture()
+{
+ if (!mNeedsCreateTexture)
+ {
+ mNeedsCreateTexture = TRUE;
+ if (preCreateTexture())
+ {
+#if LL_IMAGEGL_THREAD_CHECK
+ //grab a copy of the raw image data to make sure it isn't modified pending texture creation
+ U8* data = mRawImage->getData();
+ U8* data_copy = nullptr;
+ S32 size = mRawImage->getDataSize();
+ if (data != nullptr && size > 0)
+ {
+ data_copy = new U8[size];
+ memcpy(data_copy, data, size);
+ }
+#endif
+ mNeedsCreateTexture = TRUE;
+ auto mainq = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
+ if (mainq)
+ {
+ ref();
+ mainq->postTo(
+ mImageQueue,
+ // work to be done on LLImageGL worker thread
+#if LL_IMAGEGL_THREAD_CHECK
+ [this, data, data_copy, size]()
+ {
+ mGLTexturep->mActiveThread = LLThread::currentID();
+ //verify data is unmodified
+ llassert(data == mRawImage->getData());
+ llassert(mRawImage->getDataSize() == size);
+ llassert(memcmp(data, data_copy, size) == 0);
+#else
+ [this]()
+ {
+#endif
+ //actually create the texture on a background thread
+ createTexture();
+
+#if LL_IMAGEGL_THREAD_CHECK
+ //verify data is unmodified
+ llassert(data == mRawImage->getData());
+ llassert(mRawImage->getDataSize() == size);
+ llassert(memcmp(data, data_copy, size) == 0);
+#endif
+ },
+ // callback to be run on main thread
+#if LL_IMAGEGL_THREAD_CHECK
+ [this, data, data_copy, size]()
+ {
+ mGLTexturep->mActiveThread = LLThread::currentID();
+ llassert(data == mRawImage->getData());
+ llassert(mRawImage->getDataSize() == size);
+ llassert(memcmp(data, data_copy, size) == 0);
+ delete[] data_copy;
+#else
+ [this]()
+ {
+#endif
+ //finalize on main thread
+ postCreateTexture();
+ unref();
+ });
+ }
+ else
+ {
+ gTextureList.mCreateTextureList.insert(this);
+ }
+ }
+ }
}
// Call with 0,0 to turn this feature off.
@@ -1866,6 +1975,7 @@ void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
void LLViewerFetchedTexture::updateVirtualSize()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if(!mMaxVirtualSizeResetCounter)
{
addTextureStats(0.f, FALSE);//reset
@@ -1957,6 +2067,7 @@ bool LLViewerFetchedTexture::isActiveFetching()
bool LLViewerFetchedTexture::updateFetch()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2);
static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3);
@@ -2059,7 +2170,7 @@ bool LLViewerFetchedTexture::updateFetch()
}
else
{
- mIsRawImageValid = TRUE;
+ mIsRawImageValid = TRUE;
addToCreateTexture();
}
@@ -2537,6 +2648,7 @@ void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::s
bool LLViewerFetchedTexture::doLoadedCallbacks()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds
static const F32 MAX_IDLE_WAIT_TIME = 5.f ; //seconds
@@ -2887,7 +2999,9 @@ void LLViewerFetchedTexture::destroyRawImage()
//virtual
void LLViewerFetchedTexture::switchToCachedImage()
{
- if(mCachedRawImage.notNull())
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ if(mCachedRawImage.notNull() &&
+ !mNeedsCreateTexture) // <--- texture creation is pending, don't step on it
{
mRawImage = mCachedRawImage;
@@ -2898,12 +3012,12 @@ void LLViewerFetchedTexture::switchToCachedImage()
mComponents = mRawImage->getComponents();
mGLTexturep->setComponents(mComponents);
gTextureList.dirtyImage(this);
- }
+ }
mIsRawImageValid = TRUE;
mRawDiscardLevel = mCachedRawDiscardLevel;
- gTextureList.mCreateTextureList.insert(this);
- mNeedsCreateTexture = TRUE;
+
+ scheduleCreateTexture();
}
}
@@ -3177,6 +3291,7 @@ bool LLViewerLODTexture::isUpdateFrozen()
//virtual
void LLViewerLODTexture::processTextureStats()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
updateVirtualSize();
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
@@ -3340,6 +3455,7 @@ bool LLViewerLODTexture::scaleDown()
//static
void LLViewerMediaTexture::updateClass()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static const F32 MAX_INACTIVE_TIME = 30.f;
#if 0