summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-10-22 22:07:00 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-10-22 22:22:17 +0300
commit0bf11e45ea34a21b980c36c99be476613552d560 (patch)
treeda1709b074febd1c92f768c8fd70d3665818c575 /indra/newview
parent83600bb16ac305542de9bb9fd8eba1bec90dc1b0 (diff)
SL-14150 Handle more cases of corrupted cache
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/lltexturecache.cpp9
-rw-r--r--indra/newview/llviewertexture.cpp20
2 files changed, 26 insertions, 3 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 2e52414d71..649a994648 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -52,7 +52,8 @@ const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024;
const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit
const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate)
const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level
-const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
+const S32 TEXTURE_FAST_CACHE_DATA_SIZE = 16 * 16 * 4;
+const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = TEXTURE_FAST_CACHE_DATA_SIZE + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
const F32 TEXTURE_LAZY_PURGE_TIME_LIMIT = .004f; // 4ms. Would be better to autoadjust, but there is a major cache rework in progress.
class LLTextureCacheWorker : public LLWorkerClass
@@ -2065,7 +2066,9 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
}
S32 image_size = head[0] * head[1] * head[2];
- if(!image_size) //invalid
+ if(image_size <= 0
+ || image_size > TEXTURE_FAST_CACHE_DATA_SIZE
+ || head[3] < 0) //invalid
{
closeFastCache();
return NULL;
@@ -2144,7 +2147,7 @@ bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImage
S32 i = 0 ;
- while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
+ while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_DATA_SIZE)
{
++i ;
}
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index a2cec9a613..b64e576ad7 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1541,6 +1541,26 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
return FALSE;
}
+ if (mGLTexturep->getHasEplixitFormat())
+ {
+ LLGLenum format = mGLTexturep->getPrimaryFormat();
+ S8 components = mRawImage->getComponents();
+ if ((format == GL_RGBA && components < 4)
+ || (format == GL_RGB && components < 3))
+ {
+ LL_WARNS() << "Can't create a texture " << mID << ": invalid image format " << std::hex << format << " vs components " << (U32)components << LL_ENDL;
+ // Was expecting specific format but raw texture has insufficient components for
+ // such format, using such texture will result in crash or will display wrongly
+ // if we change format. Texture might be corrupted server side, so just set as
+ // missing and clear cashed texture (do not cause reload loop, will retry&recover
+ // during new session)
+ setIsMissingAsset();
+ destroyRawImage();
+ LLAppViewer::getTextureCache()->removeFromCache(mID);
+ return FALSE;
+ }
+ }
+
res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
notifyAboutCreatingTexture();