summaryrefslogtreecommitdiff
path: root/indra/newview/lltexturecache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lltexturecache.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/lltexturecache.cpp50
1 files changed, 39 insertions, 11 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index a61e2d5c86..5bc2e971eb 100644..100755
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -568,8 +568,11 @@ bool LLTextureCacheRemoteWorker::doWrite()
idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry.
if(idx >= 0)
{
- //write to the fast cache.
- llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
+ // (almost always) write to the fast cache.
+ if (mRawImage->getDataSize())
+ {
+ llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
+ }
}
}
else
@@ -1861,7 +1864,12 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
mFastCachep->seek(APR_SET, offset);
- llassert_always(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) == TEXTURE_FAST_CACHE_ENTRY_OVERHEAD);
+ if(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) != TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
+ {
+ //cache corrupted or under thread race condition
+ closeFastCache();
+ return NULL;
+ }
S32 image_size = head[0] * head[1] * head[2];
if(!image_size) //invalid
@@ -1872,7 +1880,13 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
discardlevel = head[3];
data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size);
- llassert_always(mFastCachep->read(data, image_size) == image_size);
+ if(mFastCachep->read(data, image_size) != image_size)
+ {
+ FREE_MEM(LLImageBase::getPrivatePool(), data);
+ closeFastCache();
+ return NULL;
+ }
+
closeFastCache();
}
LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true);
@@ -1884,10 +1898,17 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
{
//rescale image if needed
+ if (raw.isNull() || !raw->getData())
+ {
+ llerrs << "Attempted to write NULL raw image to fastcache" << llendl;
+ return false;
+ }
+
S32 w, h, c;
w = raw->getWidth();
h = raw->getHeight();
c = raw->getComponents();
+
S32 i = 0 ;
while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
@@ -1901,10 +1922,10 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
h >>= i;
if(w * h *c > 0) //valid
{
- LLPointer<LLImageRaw> newraw = new LLImageRaw(raw->getData(), raw->getWidth(), raw->getHeight(), raw->getComponents());
- newraw->scale(w, h) ;
- raw = newraw;
-
+ //make a duplicate to keep the original raw image untouched.
+ raw = raw->duplicate();
+ raw->scale(w, h) ;
+
discardlevel += i ;
}
}
@@ -1914,9 +1935,12 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
memcpy(mFastCachePadBuffer + sizeof(S32), &h, sizeof(S32));
memcpy(mFastCachePadBuffer + sizeof(S32) * 2, &c, sizeof(S32));
memcpy(mFastCachePadBuffer + sizeof(S32) * 3, &discardlevel, sizeof(S32));
- if(w * h * c > 0) //valid
+
+ S32 copy_size = w * h * c;
+ if(copy_size > 0) //valid
{
- memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), w * h * c);
+ copy_size = llmin(copy_size, TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD);
+ memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), copy_size);
}
S32 offset = id * TEXTURE_FAST_CACHE_ENTRY_SIZE;
@@ -1926,7 +1950,11 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
openFastCache();
mFastCachep->seek(APR_SET, offset);
- llassert_always(mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE) == TEXTURE_FAST_CACHE_ENTRY_SIZE);
+
+ //no need to do this assertion check. When it fails, let it fail quietly.
+ //this failure could happen because other viewer removes the fast cache file when clearing cache.
+ //--> llassert_always(mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE) == TEXTURE_FAST_CACHE_ENTRY_SIZE);
+ mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE);
closeFastCache(true);
}