diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2020-10-22 22:07:00 +0300 |
---|---|---|
committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2020-10-22 22:22:17 +0300 |
commit | 0bf11e45ea34a21b980c36c99be476613552d560 (patch) | |
tree | da1709b074febd1c92f768c8fd70d3665818c575 /indra | |
parent | 83600bb16ac305542de9bb9fd8eba1bec90dc1b0 (diff) |
SL-14150 Handle more cases of corrupted cache
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llrender/llimagegl.cpp | 4 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 3 | ||||
-rw-r--r-- | indra/newview/lltexturecache.cpp | 9 | ||||
-rw-r--r-- | indra/newview/llviewertexture.cpp | 20 |
4 files changed, 30 insertions, 6 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index c85b9a890a..0151d20128 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1387,8 +1387,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S } if (mHasExplicitFormat && - (mFormatPrimary == GL_RGBA && mComponents < 4) || - (mFormatPrimary == GL_RGB && mComponents < 3)) + ((mFormatPrimary == GL_RGBA && mComponents < 4) || + (mFormatPrimary == GL_RGB && mComponents < 3))) { LL_WARNS() << "Incorrect format: " << std::hex << mFormatPrimary << " components: " << (U32)mComponents << LL_ENDL; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 4f3d7eed0a..472af75d9e 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -133,6 +133,7 @@ public: S32 getMipBytes(S32 discard_level = -1) const; BOOL getBoundRecently() const; BOOL isJustBound() const; + BOOL getHasEplixitFormat() const { return mHasExplicitFormat; } LLGLenum getPrimaryFormat() const { return mFormatPrimary; } LLGLenum getFormatType() const { return mFormatType; } @@ -197,7 +198,7 @@ private: U16 mPickMaskWidth; U16 mPickMaskHeight; S8 mUseMipMaps; - S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents) + BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents) S8 mAutoGenMips; BOOL mIsMask; 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(); |