summaryrefslogtreecommitdiff
path: root/indra/newview/lltexturecache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lltexturecache.cpp')
-rw-r--r--indra/newview/lltexturecache.cpp161
1 files changed, 95 insertions, 66 deletions
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index f0c28041d1..435d833345 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -387,22 +387,35 @@ bool LLTextureCacheRemoteWorker::doRead()
}
// Allocate read buffer
mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
- S32 bytes_read = LLAPRFile::readEx(local_filename,
- mReadData, mOffset, mDataSize, mCache->getLocalAPRFilePool());
- if (bytes_read != mDataSize)
+
+ if (mReadData)
{
- LL_WARNS() << "Error reading file from local cache: " << local_filename
- << " Bytes: " << mDataSize << " Offset: " << mOffset
+ S32 bytes_read = LLAPRFile::readEx( local_filename,
+ mReadData,
+ mOffset,
+ mDataSize,
+ mCache->getLocalAPRFilePool());
+
+ if (bytes_read != mDataSize)
+ {
+ LL_WARNS() << "Error reading file from local cache: " << local_filename
+ << " Bytes: " << mDataSize << " Offset: " << mOffset
<< " / " << mDataSize << LL_ENDL;
- mDataSize = 0;
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
- mReadData = NULL;
+ mDataSize = 0;
+ FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ mReadData = NULL;
+ }
+ else
+ {
+ mImageSize = local_size;
+ mImageLocal = TRUE;
+ }
}
else
{
- //LL_INFOS() << "texture " << mID.asString() << " found in local_assets" << LL_ENDL;
- mImageSize = local_size;
- mImageLocal = TRUE;
+ LL_WARNS() << "Error allocating memory for cache: " << local_filename
+ << " of size: " << mDataSize << LL_ENDL;
+ mDataSize = 0;
}
// We're done...
done = true;
@@ -477,44 +490,55 @@ bool LLTextureCacheRemoteWorker::doRead()
// Reserve the whole data buffer first
U8* data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
-
- // Set the data file pointers taking the read offset into account. 2 cases:
- if (mOffset < TEXTURE_CACHE_ENTRY_SIZE)
- {
- // Offset within the header record. That means we read something from the header cache.
- // Note: most common case is (mOffset = 0), so this is the "normal" code path.
- data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset; // i.e. TEXTURE_CACHE_ENTRY_SIZE if mOffset nul (common case)
- file_offset = 0;
- file_size = mDataSize - data_offset;
- // Copy the raw data we've been holding from the header cache into the new sized buffer
- llassert_always(mReadData);
- memcpy(data, mReadData, data_offset);
- FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
- mReadData = NULL;
- }
- else
+ if (data)
{
- // Offset bigger than the header record. That means we haven't read anything yet.
- data_offset = 0;
- file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE;
- file_size = mDataSize;
- // No data from header cache to copy in that case, we skipped it all
- }
+ // Set the data file pointers taking the read offset into account. 2 cases:
+ if (mOffset < TEXTURE_CACHE_ENTRY_SIZE)
+ {
+ // Offset within the header record. That means we read something from the header cache.
+ // Note: most common case is (mOffset = 0), so this is the "normal" code path.
+ data_offset = TEXTURE_CACHE_ENTRY_SIZE - mOffset; // i.e. TEXTURE_CACHE_ENTRY_SIZE if mOffset nul (common case)
+ file_offset = 0;
+ file_size = mDataSize - data_offset;
+ // Copy the raw data we've been holding from the header cache into the new sized buffer
+ llassert_always(mReadData);
+ memcpy(data, mReadData, data_offset);
+ FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ mReadData = NULL;
+ }
+ else
+ {
+ // Offset bigger than the header record. That means we haven't read anything yet.
+ data_offset = 0;
+ file_offset = mOffset - TEXTURE_CACHE_ENTRY_SIZE;
+ file_size = mDataSize;
+ // No data from header cache to copy in that case, we skipped it all
+ }
- // Now use that buffer as the object read buffer
- llassert_always(mReadData == NULL);
- mReadData = data;
+ // Now use that buffer as the object read buffer
+ llassert_always(mReadData == NULL);
+ mReadData = data;
- // Read the data at last
- S32 bytes_read = LLAPRFile::readEx(filename,
- mReadData + data_offset,
- file_offset, file_size,
- mCache->getLocalAPRFilePool());
- if (bytes_read != file_size)
+ // Read the data at last
+ S32 bytes_read = LLAPRFile::readEx(filename,
+ mReadData + data_offset,
+ file_offset, file_size,
+ mCache->getLocalAPRFilePool());
+ if (bytes_read != file_size)
+ {
+ LL_WARNS() << "LLTextureCacheWorker: " << mID
+ << " incorrect number of bytes read from body: " << bytes_read
+ << " / " << file_size << LL_ENDL;
+ FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
+ mReadData = NULL;
+ mDataSize = -1; // failed
+ done = true;
+ }
+ }
+ else
{
LL_WARNS() << "LLTextureCacheWorker: " << mID
- << " incorrect number of bytes read from body: " << bytes_read
- << " / " << file_size << LL_ENDL;
+ << " failed to allocate memory for reading: " << mDataSize << LL_ENDL;
FREE_MEM(LLImageBase::getPrivatePool(), mReadData);
mReadData = NULL;
mDataSize = -1; // failed
@@ -550,9 +574,11 @@ bool LLTextureCacheRemoteWorker::doWrite()
{
if ((mOffset != 0) // We currently do not support write offsets
|| (mDataSize <= 0) // Things will go badly wrong if mDataSize is nul or negative...
- || (mImageSize < mDataSize))
+ || (mImageSize < mDataSize)
+ || (mRawDiscardLevel < 0)
+ || (mRawImage->isBufferInvalid())) // decode failed or malfunctioned, don't write
{
- LL_WARNS() << "INIT state check failed" << LL_ENDL;
+ LL_WARNS() << "INIT state check failed for image: " << mID << " Size: " << mImageSize << " DataSize: " << mDataSize << " Discard:" << mRawDiscardLevel << LL_ENDL;
mDataSize = -1; // failed
done = true;
}
@@ -577,15 +603,12 @@ bool LLTextureCacheRemoteWorker::doWrite()
idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry.
if(idx >= 0)
{
- // (almost always) write to the fast cache.
- if (mRawImage->getDataSize())
+ // write to the fast cache.
+ if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel))
{
- if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel))
- {
- LL_WARNS() << "writeToFastCache failed" << LL_ENDL;
- mDataSize = -1; // failed
- done = true;
- }
+ LL_WARNS() << "writeToFastCache failed" << LL_ENDL;
+ mDataSize = -1; // failed
+ done = true;
}
}
}
@@ -936,7 +959,7 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)
//////////////////////////////////////////////////////////////////////////////
//static
-F32 LLTextureCache::sHeaderCacheVersion = 1.7f;
+F32 LLTextureCache::sHeaderCacheVersion = 1.71f;
U32 LLTextureCache::sCacheMaxEntries = 1024 * 1024; //~1 million textures.
S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit
std::string LLTextureCache::sHeaderCacheEncoderVersion = LLImageJ2C::getEngineInfo();
@@ -1793,24 +1816,30 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)
S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize)
{
mHeaderMutex.lock();
- S32 idx = openAndReadEntry(id, entry, true);
+ S32 idx = openAndReadEntry(id, entry, true); // read or create
mHeaderMutex.unlock();
- if (idx >= 0)
- {
- updateEntry(idx, entry, imagesize, datasize);
- }
-
- if(idx < 0) // retry
+ if(idx < 0) // retry once
{
readHeaderCache(); // We couldn't write an entry, so refresh the LRU
-
+
mHeaderMutex.lock();
- llassert_always(!mLRU.empty() || mHeaderEntriesInfo.mEntries < sCacheMaxEntries);
+ idx = openAndReadEntry(id, entry, true);
mHeaderMutex.unlock();
+ }
- idx = setHeaderCacheEntry(id, entry, imagesize, datasize); // assert above ensures no inf. recursion
+ if (idx >= 0)
+ {
+ updateEntry(idx, entry, imagesize, datasize);
+ }
+ else
+ {
+ LL_WARNS() << "Failed to set cache entry for image: " << id << LL_ENDL;
+ // We couldn't write to file, switch to read only mode and clear data
+ setReadOnly(true);
+ clearCorruptedCache(); // won't remove files due to "read only"
}
+
return idx;
}
@@ -1962,7 +1991,7 @@ 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())
+ if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())
{
LL_ERRS() << "Attempted to write NULL raw image to fastcache" << LL_ENDL;
return false;