diff options
Diffstat (limited to 'indra/newview/lltexturecache.cpp')
-rw-r--r-- | indra/newview/lltexturecache.cpp | 161 |
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; |