示例#1
0
void LLTextureCache::writeEntryAndClose(S32 idx, Entry& entry)
{
	if (idx >= 0)
	{
		if (!mReadOnly)
		{
			entry.mTime = time(NULL);
			if(entry.mImageSize < entry.mBodySize)
			{
				// Just say no, due to my messing around to cache discards other than 0 we can end up here
				// after recalling an image from cache at a lower discard than cached. RC
				return;
			}

			llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize);
			if (entry.mBodySize > 0)
			{
				mTexturesSizeMap[entry.mID] = entry.mBodySize;
			}
// 			llinfos << "Updating TE: " << idx << ": " << id << " Size: " << entry.mBodySize << " Time: " << entry.mTime << llendl;
			S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
			LLAPRFile* aprfile = openHeaderEntriesFile(false, offset);
			S32 bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry));
			llassert_always(bytes_written == sizeof(Entry));
			mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx);
			closeHeaderEntriesFile();
		}
	}
}
示例#2
0
void LLTextureCache::writeEntriesAndClose(const std::vector<Entry>& entries)
{
	S32 num_entries = entries.size();
	llassert_always(num_entries == mHeaderEntriesInfo.mEntries);
	
	if (!mReadOnly)
	{
		LLAPRFile* aprfile = openHeaderEntriesFile(false, (S32)sizeof(EntriesInfo));
		for (S32 idx=0; idx<num_entries; idx++)
		{
			S32 bytes_written = aprfile->write((void*)(&entries[idx]), (S32)sizeof(Entry));
			llassert_always(bytes_written == sizeof(Entry));
		}
		mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, num_entries-1);
		closeHeaderEntriesFile();
	}
}
示例#3
0
U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries)
{
	U32 num_entries = mHeaderEntriesInfo.mEntries;

	mHeaderIDMap.clear();
	mTexturesSizeMap.clear();
	mFreeList.clear();
	mTexturesSizeTotal = 0;

	LLAPRFile* aprfile = openHeaderEntriesFile(false, (S32)sizeof(EntriesInfo));
	for (U32 idx=0; idx<num_entries; idx++)
	{
		Entry entry;
		S32 bytes_read = aprfile->read((void*)(&entry), (S32)sizeof(Entry));
		if (bytes_read < sizeof(Entry))
		{
			llwarns << "Corrupted header entries, failed at " << idx << " / " << num_entries << llendl;
			closeHeaderEntriesFile();
			purgeAllTextures(false);
			return 0;
		}
		entries.push_back(entry);
// 		llinfos << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << llendl;
		if (entry.mImageSize < 0)
		{
			mFreeList.insert(idx);
		}
		else
		{
			mHeaderIDMap[entry.mID] = idx;
			if (entry.mBodySize > 0)
			{
				mTexturesSizeMap[entry.mID] = entry.mBodySize;
				mTexturesSizeTotal += entry.mBodySize;
			}
			llassert_always(entry.mImageSize == 0 || entry.mImageSize > entry.mBodySize);
		}
	}
	closeHeaderEntriesFile();
	return num_entries;
}
示例#4
0
void LLTextureCache::writeEntryAndClose(S32 idx, Entry& entry)
{
	if (idx >= 0)
	{
		if (!mReadOnly)
		{
			entry.mTime = time(NULL);
			llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize);
			if (entry.mBodySize > 0)
			{
				mTexturesSizeMap[entry.mID] = entry.mBodySize;
			}
// 			llinfos << "Updating TE: " << idx << ": " << id << " Size: " << entry.mBodySize << " Time: " << entry.mTime << llendl;
			S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
			LLAPRFile* aprfile = openHeaderEntriesFile(false, offset);
			S32 bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry));
			llassert_always(bytes_written == sizeof(Entry));
			mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx);
			closeHeaderEntriesFile();
		}
	}
}
示例#5
0
S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create)
{
	S32 idx = -1;
	
	id_map_t::iterator iter1 = mHeaderIDMap.find(id);
	if (iter1 != mHeaderIDMap.end())
	{
		idx = iter1->second;
	}

	if (idx < 0)
	{
		if (create && !mReadOnly)
		{
			if (mHeaderEntriesInfo.mEntries < sCacheMaxEntries)
			{
				// Add an entry to the end of the list
				idx = mHeaderEntriesInfo.mEntries++;

			}
			else if (!mFreeList.empty())
			{
				idx = *(mFreeList.begin());
				mFreeList.erase(mFreeList.begin());
			}
			else
			{
				// Look for a still valid entry in the LRU
				for (std::set<LLUUID>::iterator iter2 = mLRU.begin(); iter2 != mLRU.end();)
				{
					std::set<LLUUID>::iterator curiter2 = iter2++;
					LLUUID oldid = *curiter2;
					// Erase entry from LRU regardless
					mLRU.erase(curiter2);
					// Look up entry and use it if it is valid
					id_map_t::iterator iter3 = mHeaderIDMap.find(oldid);
					if (iter3 != mHeaderIDMap.end() && iter3->second >= 0)
					{
						idx = iter3->second;
						mHeaderIDMap.erase(oldid);
						mTexturesSizeMap.erase(oldid);
						break;
					}
				}
				// if (idx < 0) at this point, we will rebuild the LRU 
				//  and retry if called from setHeaderCacheEntry(),
				//  otherwise this shouldn't happen and will trigger an error
			}
			if (idx >= 0)
			{
				// Set the header index
				mHeaderIDMap[id] = idx;
				llassert_always(mTexturesSizeMap.erase(id) == 0);
				// Initialize the entry (will get written later)
				entry.init(id, time(NULL));
				// Update Header
				writeEntriesHeader();
				// Write Entry
				S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
				LLAPRFile* aprfile = openHeaderEntriesFile(false, offset);
				S32 bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry));
				llassert_always(bytes_written == sizeof(Entry));
				mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx);
				closeHeaderEntriesFile();
			}
		}
	}
	else
	{
		// Remove this entry from the LRU if it exists
		mLRU.erase(id);
		// Read the entry
		S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry);
		LLAPRFile* aprfile = openHeaderEntriesFile(true, offset);
		S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry));
		llassert_always(bytes_read == sizeof(Entry));
		llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize);
		closeHeaderEntriesFile();
	}
	return idx;
}