diff options
Diffstat (limited to 'linden/indra/newview')
-rw-r--r-- | linden/indra/newview/lltexturecache.cpp | 679 | ||||
-rw-r--r-- | linden/indra/newview/lltexturecache.h | 37 | ||||
-rw-r--r-- | linden/indra/newview/lltexturefetch.cpp | 2 |
3 files changed, 229 insertions, 489 deletions
diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp index 0a76742..46c125f 100644 --- a/linden/indra/newview/lltexturecache.cpp +++ b/linden/indra/newview/lltexturecache.cpp | |||
@@ -48,11 +48,11 @@ | |||
48 | // Unordered array of Entry structs | 48 | // Unordered array of Entry structs |
49 | // cache/texture.cache | 49 | // cache/texture.cache |
50 | // First TEXTURE_CACHE_ENTRY_SIZE bytes of each texture in texture.entries in same order | 50 | // First TEXTURE_CACHE_ENTRY_SIZE bytes of each texture in texture.entries in same order |
51 | // Entry size same as header packet, so we're not 0-padding unless whole image is contained in header. | ||
51 | // cache/textures/[0-F]/UUID.texture | 52 | // cache/textures/[0-F]/UUID.texture |
52 | // Actual texture body files | 53 | // Actual texture body files |
53 | 54 | ||
54 | //note: there is no good to define 1024 for TEXTURE_CACHE_ENTRY_SIZE while FIRST_PACKET_SIZE is 600 on sim side. | 55 | const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE; |
55 | const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024; | ||
56 | const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit | 56 | const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit |
57 | const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) | 57 | const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) |
58 | 58 | ||
@@ -390,7 +390,6 @@ bool LLTextureCacheRemoteWorker::doRead() | |||
390 | } | 390 | } |
391 | else | 391 | else |
392 | { | 392 | { |
393 | //llinfos << "texture " << mID.asString() << " found in local_assets" << llendl; | ||
394 | mImageSize = local_size; | 393 | mImageSize = local_size; |
395 | mImageLocal = TRUE; | 394 | mImageLocal = TRUE; |
396 | } | 395 | } |
@@ -401,8 +400,7 @@ bool LLTextureCacheRemoteWorker::doRead() | |||
401 | // Second state / stage : identify the cache or not... | 400 | // Second state / stage : identify the cache or not... |
402 | if (!done && (mState == CACHE)) | 401 | if (!done && (mState == CACHE)) |
403 | { | 402 | { |
404 | LLTextureCache::Entry entry ; | 403 | idx = mCache->getHeaderCacheEntry(mID, mImageSize); |
405 | idx = mCache->getHeaderCacheEntry(mID, entry); | ||
406 | if (idx < 0) | 404 | if (idx < 0) |
407 | { | 405 | { |
408 | // The texture is *not* cached. We're done here... | 406 | // The texture is *not* cached. We're done here... |
@@ -411,7 +409,6 @@ bool LLTextureCacheRemoteWorker::doRead() | |||
411 | } | 409 | } |
412 | else | 410 | else |
413 | { | 411 | { |
414 | mImageSize = entry.mImageSize ; | ||
415 | // If the read offset is bigger than the header cache, we read directly from the body | 412 | // If the read offset is bigger than the header cache, we read directly from the body |
416 | // Note that currently, we *never* read with offset from the cache, so the result is *always* HEADER | 413 | // Note that currently, we *never* read with offset from the cache, so the result is *always* HEADER |
417 | mState = mOffset < TEXTURE_CACHE_ENTRY_SIZE ? HEADER : BODY; | 414 | mState = mOffset < TEXTURE_CACHE_ENTRY_SIZE ? HEADER : BODY; |
@@ -539,7 +536,6 @@ bool LLTextureCacheRemoteWorker::doWrite() | |||
539 | { | 536 | { |
540 | llassert_always(mOffset == 0); // We currently do not support write offsets | 537 | llassert_always(mOffset == 0); // We currently do not support write offsets |
541 | llassert_always(mDataSize > 0); // Things will go badly wrong if mDataSize is nul or negative... | 538 | llassert_always(mDataSize > 0); // Things will go badly wrong if mDataSize is nul or negative... |
542 | llassert_always(mImageSize >= mDataSize); | ||
543 | mState = CACHE; | 539 | mState = CACHE; |
544 | } | 540 | } |
545 | 541 | ||
@@ -549,19 +545,14 @@ bool LLTextureCacheRemoteWorker::doWrite() | |||
549 | if (!done && (mState == CACHE)) | 545 | if (!done && (mState == CACHE)) |
550 | { | 546 | { |
551 | bool alreadyCached = false; | 547 | bool alreadyCached = false; |
552 | LLTextureCache::Entry entry ; | 548 | S32 cur_imagesize = 0; |
553 | |||
554 | // Checks if this image is already in the entry list | 549 | // Checks if this image is already in the entry list |
555 | idx = mCache->getHeaderCacheEntry(mID, entry); | 550 | idx = mCache->getHeaderCacheEntry(mID, cur_imagesize); |
556 | if(idx < 0) | 551 | if (idx >= 0 && (cur_imagesize >= 0)) |
557 | { | ||
558 | idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry. | ||
559 | } | ||
560 | else | ||
561 | { | 552 | { |
562 | alreadyCached = mCache->updateEntry(idx, entry, mImageSize, mDataSize); // update the existing entry. | 553 | alreadyCached = true; // already there and non empty |
563 | } | 554 | } |
564 | 555 | idx = mCache->setHeaderCacheEntry(mID, mImageSize); // create or touch the entry | |
565 | if (idx < 0) | 556 | if (idx < 0) |
566 | { | 557 | { |
567 | llwarns << "LLTextureCacheWorker: " << mID | 558 | llwarns << "LLTextureCacheWorker: " << mID |
@@ -571,6 +562,10 @@ bool LLTextureCacheRemoteWorker::doWrite() | |||
571 | } | 562 | } |
572 | else | 563 | else |
573 | { | 564 | { |
565 | if (cur_imagesize > 0 && (mImageSize != cur_imagesize)) | ||
566 | { | ||
567 | alreadyCached = false; // re-write the header if the size changed in all cases | ||
568 | } | ||
574 | if (alreadyCached && (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE)) | 569 | if (alreadyCached && (mDataSize <= TEXTURE_CACHE_ENTRY_SIZE)) |
575 | { | 570 | { |
576 | // Small texture already cached case: we're done with writing | 571 | // Small texture already cached case: we're done with writing |
@@ -633,7 +628,7 @@ bool LLTextureCacheRemoteWorker::doWrite() | |||
633 | { | 628 | { |
634 | llassert(mDataSize > TEXTURE_CACHE_ENTRY_SIZE); // wouldn't make sense to be here otherwise... | 629 | llassert(mDataSize > TEXTURE_CACHE_ENTRY_SIZE); // wouldn't make sense to be here otherwise... |
635 | S32 file_size = mDataSize - TEXTURE_CACHE_ENTRY_SIZE; | 630 | S32 file_size = mDataSize - TEXTURE_CACHE_ENTRY_SIZE; |
636 | 631 | if ((file_size > 0) && mCache->updateTextureEntryList(mID, file_size)) | |
637 | { | 632 | { |
638 | // build the cache file name from the UUID | 633 | // build the cache file name from the UUID |
639 | std::string filename = mCache->getTextureFileName(mID); | 634 | std::string filename = mCache->getTextureFileName(mID); |
@@ -650,7 +645,10 @@ bool LLTextureCacheRemoteWorker::doWrite() | |||
650 | done = true; | 645 | done = true; |
651 | } | 646 | } |
652 | } | 647 | } |
653 | 648 | else | |
649 | { | ||
650 | mDataSize = 0; // no data written | ||
651 | } | ||
654 | // Nothing else to do at that point... | 652 | // Nothing else to do at that point... |
655 | done = true; | 653 | done = true; |
656 | } | 654 | } |
@@ -741,7 +739,7 @@ LLTextureCache::LLTextureCache(bool threaded) | |||
741 | mHeaderMutex(NULL), | 739 | mHeaderMutex(NULL), |
742 | mListMutex(NULL), | 740 | mListMutex(NULL), |
743 | mHeaderAPRFile(NULL), | 741 | mHeaderAPRFile(NULL), |
744 | mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called. | 742 | mReadOnly(FALSE), |
745 | mTexturesSizeTotal(0), | 743 | mTexturesSizeTotal(0), |
746 | mDoPurge(FALSE) | 744 | mDoPurge(FALSE) |
747 | { | 745 | { |
@@ -749,8 +747,6 @@ LLTextureCache::LLTextureCache(bool threaded) | |||
749 | 747 | ||
750 | LLTextureCache::~LLTextureCache() | 748 | LLTextureCache::~LLTextureCache() |
751 | { | 749 | { |
752 | clearDeleteList() ; | ||
753 | writeUpdatedEntries() ; | ||
754 | } | 750 | } |
755 | 751 | ||
756 | ////////////////////////////////////////////////////////////////////////////// | 752 | ////////////////////////////////////////////////////////////////////////////// |
@@ -758,9 +754,6 @@ LLTextureCache::~LLTextureCache() | |||
758 | //virtual | 754 | //virtual |
759 | S32 LLTextureCache::update(U32 max_time_ms) | 755 | S32 LLTextureCache::update(U32 max_time_ms) |
760 | { | 756 | { |
761 | static LLFrameTimer timer ; | ||
762 | static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. | ||
763 | |||
764 | S32 res; | 757 | S32 res; |
765 | res = LLWorkerThread::update(max_time_ms); | 758 | res = LLWorkerThread::update(max_time_ms); |
766 | 759 | ||
@@ -796,12 +789,6 @@ S32 LLTextureCache::update(U32 max_time_ms) | |||
796 | responder->completed(success); | 789 | responder->completed(success); |
797 | } | 790 | } |
798 | 791 | ||
799 | if(!res && timer.getElapsedTimeF32() > MAX_TIME_INTERVAL) | ||
800 | { | ||
801 | timer.reset() ; | ||
802 | writeUpdatedEntries() ; | ||
803 | } | ||
804 | |||
805 | return res; | 792 | return res; |
806 | } | 793 | } |
807 | 794 | ||
@@ -824,54 +811,58 @@ std::string LLTextureCache::getTextureFileName(const LLUUID& id) | |||
824 | return filename; | 811 | return filename; |
825 | } | 812 | } |
826 | 813 | ||
827 | //debug | 814 | bool LLTextureCache::updateTextureEntryList(const LLUUID& id, S32 bodysize) |
828 | BOOL LLTextureCache::isInCache(const LLUUID& id) | ||
829 | { | 815 | { |
830 | LLMutexLock lock(&mHeaderMutex); | 816 | bool res = false; |
831 | id_map_t::const_iterator iter = mHeaderIDMap.find(id); | 817 | bool purge = false; |
832 | |||
833 | return (iter != mHeaderIDMap.end()) ; | ||
834 | } | ||
835 | |||
836 | //debug | ||
837 | BOOL LLTextureCache::isInLocal(const LLUUID& id) | ||
838 | { | ||
839 | S32 local_size = 0; | ||
840 | std::string local_filename; | ||
841 | |||
842 | std::string filename = getLocalFileName(id); | ||
843 | // Is it a JPEG2000 file? | ||
844 | { | ||
845 | local_filename = filename + ".j2c"; | ||
846 | local_size = LLAPRFile::size(local_filename); | ||
847 | if (local_size > 0) | ||
848 | { | ||
849 | return TRUE ; | ||
850 | } | ||
851 | } | ||
852 | |||
853 | // If not, is it a jpeg file? | ||
854 | { | 818 | { |
855 | local_filename = filename + ".jpg"; | 819 | mHeaderMutex.lock(); |
856 | local_size = LLAPRFile::size(local_filename); | 820 | size_map_t::iterator iter1 = mTexturesSizeMap.find(id); |
857 | if (local_size > 0) | 821 | if (iter1 == mTexturesSizeMap.end() || iter1->second < bodysize) |
858 | { | 822 | { |
859 | return TRUE ; | 823 | llassert_always(bodysize > 0); |
824 | |||
825 | S32 oldbodysize = 0; | ||
826 | if (iter1 != mTexturesSizeMap.end()) | ||
827 | { | ||
828 | oldbodysize = iter1->second; | ||
829 | } | ||
830 | |||
831 | Entry entry; | ||
832 | S32 idx = openAndReadEntry(id, entry, false); | ||
833 | if (idx < 0) | ||
834 | { | ||
835 | llwarns << "Failed to open entry: " << id << llendl; | ||
836 | mHeaderMutex.unlock(); | ||
837 | removeFromCache(id); | ||
838 | return false; | ||
839 | } | ||
840 | else if (oldbodysize != entry.mBodySize) | ||
841 | { | ||
842 | llwarns << "Entry mismatch in mTextureSizeMap / mHeaderIDMap" | ||
843 | << " idx=" << idx << " oldsize=" << oldbodysize << " entrysize=" << entry.mBodySize << llendl; | ||
844 | } | ||
845 | entry.mBodySize = bodysize; | ||
846 | writeEntryAndClose(idx, entry); | ||
847 | |||
848 | mTexturesSizeTotal -= oldbodysize; | ||
849 | mTexturesSizeTotal += bodysize; | ||
850 | |||
851 | if (mTexturesSizeTotal > sCacheMaxTexturesSize) | ||
852 | { | ||
853 | purge = true; | ||
854 | } | ||
855 | res = true; | ||
860 | } | 856 | } |
861 | } | 857 | } |
862 | 858 | if (purge) | |
863 | // Hmm... What about a targa file? (used for UI texture mostly) | ||
864 | { | 859 | { |
865 | local_filename = filename + ".tga"; | 860 | mDoPurge = TRUE; |
866 | local_size = LLAPRFile::size(local_filename); | ||
867 | if (local_size > 0) | ||
868 | { | ||
869 | return TRUE ; | ||
870 | } | ||
871 | } | 861 | } |
872 | 862 | mHeaderMutex.unlock(); | |
873 | return FALSE ; | 863 | return res; |
874 | } | 864 | } |
865 | |||
875 | ////////////////////////////////////////////////////////////////////////////// | 866 | ////////////////////////////////////////////////////////////////////////////// |
876 | 867 | ||
877 | //static | 868 | //static |
@@ -902,21 +893,13 @@ void LLTextureCache::purgeCache(ELLPath location) | |||
902 | LLAPRFile::remove(mHeaderEntriesFileName); | 893 | LLAPRFile::remove(mHeaderEntriesFileName); |
903 | LLAPRFile::remove(mHeaderDataFileName); | 894 | LLAPRFile::remove(mHeaderDataFileName); |
904 | } | 895 | } |
905 | //remove the current texture cache. | ||
906 | purgeAllTextures(true); | 896 | purgeAllTextures(true); |
907 | } | 897 | } |
908 | 898 | ||
909 | //is called in the main thread before initCache(...) is called. | 899 | S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL read_only) |
910 | void LLTextureCache::setReadOnly(BOOL read_only) | ||
911 | { | 900 | { |
912 | mReadOnly = read_only; | 901 | mReadOnly = read_only; |
913 | } | 902 | |
914 | |||
915 | //called in the main thread. | ||
916 | S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL disable_texture_cache) | ||
917 | { | ||
918 | llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. | ||
919 | |||
920 | S64 header_size = (max_size * 2) / 10; | 903 | S64 header_size = (max_size * 2) / 10; |
921 | S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE; | 904 | S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE; |
922 | sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries)); | 905 | sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries)); |
@@ -928,15 +911,6 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL disable_textu | |||
928 | sCacheMaxTexturesSize = max_size; | 911 | sCacheMaxTexturesSize = max_size; |
929 | max_size -= sCacheMaxTexturesSize; | 912 | max_size -= sCacheMaxTexturesSize; |
930 | 913 | ||
931 | if(disable_texture_cache) //the texture cache is disabled | ||
932 | { | ||
933 | llinfos << "The texture cache is disabled!" << llendl ; | ||
934 | setReadOnly(TRUE) ; | ||
935 | purgeAllTextures(true); | ||
936 | |||
937 | return max_size ; | ||
938 | } | ||
939 | |||
940 | LL_INFOS("TextureCache") << "Headers: " << sCacheMaxEntries | 914 | LL_INFOS("TextureCache") << "Headers: " << sCacheMaxEntries |
941 | << " Textures size: " << sCacheMaxTexturesSize/(1024*1024) << " MB" << LL_ENDL; | 915 | << " Textures size: " << sCacheMaxTexturesSize/(1024*1024) << " MB" << LL_ENDL; |
942 | 916 | ||
@@ -945,7 +919,6 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL disable_textu | |||
945 | if (!mReadOnly) | 919 | if (!mReadOnly) |
946 | { | 920 | { |
947 | LLFile::mkdir(mTexturesDirName); | 921 | LLFile::mkdir(mTexturesDirName); |
948 | |||
949 | const char* subdirs = "0123456789abcdef"; | 922 | const char* subdirs = "0123456789abcdef"; |
950 | for (S32 i=0; i<16; i++) | 923 | for (S32 i=0; i<16; i++) |
951 | { | 924 | { |
@@ -956,8 +929,6 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL disable_textu | |||
956 | readHeaderCache(); | 929 | readHeaderCache(); |
957 | purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it | 930 | purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it |
958 | 931 | ||
959 | llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. | ||
960 | |||
961 | return max_size; // unused cache space | 932 | return max_size; // unused cache space |
962 | } | 933 | } |
963 | 934 | ||
@@ -969,20 +940,13 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset) | |||
969 | llassert_always(mHeaderAPRFile == NULL); | 940 | llassert_always(mHeaderAPRFile == NULL); |
970 | apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY; | 941 | apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY; |
971 | mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, LLAPRFile::local); | 942 | mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, LLAPRFile::local); |
972 | if(offset > 0) | 943 | mHeaderAPRFile->seek(APR_SET, offset); |
973 | { | ||
974 | mHeaderAPRFile->seek(APR_SET, offset); | ||
975 | } | ||
976 | return mHeaderAPRFile; | 944 | return mHeaderAPRFile; |
977 | } | 945 | } |
978 | 946 | ||
979 | void LLTextureCache::closeHeaderEntriesFile() | 947 | void LLTextureCache::closeHeaderEntriesFile() |
980 | { | 948 | { |
981 | if(!mHeaderAPRFile) | 949 | llassert_always(mHeaderAPRFile != NULL); |
982 | { | ||
983 | return ; | ||
984 | } | ||
985 | |||
986 | delete mHeaderAPRFile; | 950 | delete mHeaderAPRFile; |
987 | mHeaderAPRFile = NULL; | 951 | mHeaderAPRFile = NULL; |
988 | } | 952 | } |
@@ -995,12 +959,6 @@ void LLTextureCache::readEntriesHeader() | |||
995 | { | 959 | { |
996 | LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo)); | 960 | LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo)); |
997 | } | 961 | } |
998 | else //create an empty entries header. | ||
999 | { | ||
1000 | mHeaderEntriesInfo.mVersion = sHeaderCacheVersion ; | ||
1001 | mHeaderEntriesInfo.mEntries = 0 ; | ||
1002 | writeEntriesHeader() ; | ||
1003 | } | ||
1004 | } | 962 | } |
1005 | 963 | ||
1006 | void LLTextureCache::writeEntriesHeader() | 964 | void LLTextureCache::writeEntriesHeader() |
@@ -1012,7 +970,8 @@ void LLTextureCache::writeEntriesHeader() | |||
1012 | } | 970 | } |
1013 | } | 971 | } |
1014 | 972 | ||
1015 | //mHeaderMutex is locked before calling this. | 973 | static S32 mHeaderEntriesMaxWriteIdx = 0; |
974 | |||
1016 | S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create) | 975 | S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create) |
1017 | { | 976 | { |
1018 | S32 idx = -1; | 977 | S32 idx = -1; |
@@ -1052,7 +1011,8 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create | |||
1052 | if (iter3 != mHeaderIDMap.end() && iter3->second >= 0) | 1011 | if (iter3 != mHeaderIDMap.end() && iter3->second >= 0) |
1053 | { | 1012 | { |
1054 | idx = iter3->second; | 1013 | idx = iter3->second; |
1055 | removeCachedTexture(oldid) ;//remove the existing cached texture to release the entry index. | 1014 | mHeaderIDMap.erase(oldid); |
1015 | mTexturesSizeMap.erase(oldid); | ||
1056 | break; | 1016 | break; |
1057 | } | 1017 | } |
1058 | } | 1018 | } |
@@ -1062,9 +1022,20 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create | |||
1062 | } | 1022 | } |
1063 | if (idx >= 0) | 1023 | if (idx >= 0) |
1064 | { | 1024 | { |
1065 | entry.mID = id ; | 1025 | // Set the header index |
1066 | entry.mImageSize = -1 ; //mark it is a brand-new entry. | 1026 | mHeaderIDMap[id] = idx; |
1067 | entry.mBodySize = 0 ; | 1027 | llassert_always(mTexturesSizeMap.erase(id) == 0); |
1028 | // Initialize the entry (will get written later) | ||
1029 | entry.init(id, time(NULL)); | ||
1030 | // Update Header | ||
1031 | writeEntriesHeader(); | ||
1032 | // Write Entry | ||
1033 | S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); | ||
1034 | LLAPRFile* aprfile = openHeaderEntriesFile(false, offset); | ||
1035 | S32 bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry)); | ||
1036 | llassert_always(bytes_written == sizeof(Entry)); | ||
1037 | mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx); | ||
1038 | closeHeaderEntriesFile(); | ||
1068 | } | 1039 | } |
1069 | } | 1040 | } |
1070 | } | 1041 | } |
@@ -1073,153 +1044,44 @@ S32 LLTextureCache::openAndReadEntry(const LLUUID& id, Entry& entry, bool create | |||
1073 | // Remove this entry from the LRU if it exists | 1044 | // Remove this entry from the LRU if it exists |
1074 | mLRU.erase(id); | 1045 | mLRU.erase(id); |
1075 | // Read the entry | 1046 | // Read the entry |
1076 | idx_entry_map_t::iterator iter = mUpdatedEntryMap.find(idx) ; | 1047 | S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); |
1077 | if(iter != mUpdatedEntryMap.end()) | 1048 | LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); |
1078 | { | 1049 | S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); |
1079 | entry = iter->second ; | 1050 | llassert_always(bytes_read == sizeof(Entry)); |
1080 | } | 1051 | llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize); |
1081 | else | 1052 | closeHeaderEntriesFile(); |
1082 | { | ||
1083 | readEntryFromHeaderImmediately(idx, entry) ; | ||
1084 | } | ||
1085 | if(entry.mImageSize <= entry.mBodySize)//it happens on 64-bit systems, do not know why | ||
1086 | { | ||
1087 | llwarns << "corrupted entry: " << id << " entry image size: " << entry.mImageSize << " entry body size: " << entry.mBodySize << llendl ; | ||
1088 | |||
1089 | //erase this entry and the cached texture from the cache. | ||
1090 | std::string tex_filename = getTextureFileName(id); | ||
1091 | removeEntry(idx, entry, tex_filename) ; | ||
1092 | mUpdatedEntryMap.erase(idx) ; | ||
1093 | idx = -1 ; | ||
1094 | } | ||
1095 | } | 1053 | } |
1096 | return idx; | 1054 | return idx; |
1097 | } | 1055 | } |
1098 | 1056 | ||
1099 | //mHeaderMutex is locked before calling this. | 1057 | void LLTextureCache::writeEntryAndClose(S32 idx, Entry& entry) |
1100 | void LLTextureCache::writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header) | ||
1101 | { | ||
1102 | LLAPRFile* aprfile ; | ||
1103 | S32 bytes_written ; | ||
1104 | S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); | ||
1105 | if(write_header) | ||
1106 | { | ||
1107 | aprfile = openHeaderEntriesFile(false, 0); | ||
1108 | bytes_written = aprfile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ; | ||
1109 | if(bytes_written != sizeof(EntriesInfo)) | ||
1110 | { | ||
1111 | clearCorruptedCache() ; //clear the cache. | ||
1112 | idx = -1 ;//mark the idx invalid. | ||
1113 | return ; | ||
1114 | } | ||
1115 | |||
1116 | mHeaderAPRFile->seek(APR_SET, offset); | ||
1117 | } | ||
1118 | else | ||
1119 | { | ||
1120 | aprfile = openHeaderEntriesFile(false, offset); | ||
1121 | } | ||
1122 | bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry)); | ||
1123 | if(bytes_written != sizeof(Entry)) | ||
1124 | { | ||
1125 | clearCorruptedCache() ; //clear the cache. | ||
1126 | idx = -1 ;//mark the idx invalid. | ||
1127 | |||
1128 | return ; | ||
1129 | } | ||
1130 | |||
1131 | closeHeaderEntriesFile(); | ||
1132 | mUpdatedEntryMap.erase(idx) ; | ||
1133 | } | ||
1134 | |||
1135 | //mHeaderMutex is locked before calling this. | ||
1136 | void LLTextureCache::readEntryFromHeaderImmediately(S32& idx, Entry& entry) | ||
1137 | { | ||
1138 | S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); | ||
1139 | LLAPRFile* aprfile = openHeaderEntriesFile(true, offset); | ||
1140 | S32 bytes_read = aprfile->read((void*)&entry, (S32)sizeof(Entry)); | ||
1141 | closeHeaderEntriesFile(); | ||
1142 | |||
1143 | if(bytes_read != sizeof(Entry)) | ||
1144 | { | ||
1145 | clearCorruptedCache() ; //clear the cache. | ||
1146 | idx = -1 ;//mark the idx invalid. | ||
1147 | } | ||
1148 | } | ||
1149 | |||
1150 | //mHeaderMutex is locked before calling this. | ||
1151 | //update an existing entry time stamp, delay writing. | ||
1152 | void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry) | ||
1153 | { | 1058 | { |
1154 | static const U32 MAX_ENTRIES_WITHOUT_TIME_STAMP = (U32)(LLTextureCache::sCacheMaxEntries * 0.75f) ; | ||
1155 | |||
1156 | if(mHeaderEntriesInfo.mEntries < MAX_ENTRIES_WITHOUT_TIME_STAMP) | ||
1157 | { | ||
1158 | return ; //there are enough empty entry index space, no need to stamp time. | ||
1159 | } | ||
1160 | |||
1161 | if (idx >= 0) | 1059 | if (idx >= 0) |
1162 | { | 1060 | { |
1163 | if (!mReadOnly) | 1061 | if (!mReadOnly) |
1164 | { | 1062 | { |
1165 | entry.mTime = time(NULL); | 1063 | entry.mTime = time(NULL); |
1166 | mUpdatedEntryMap[idx] = entry ; | 1064 | if(entry.mImageSize < entry.mBodySize) |
1167 | } | 1065 | { |
1168 | } | 1066 | // Just say no, due to my messing around to cache discards other than 0 we can end up here |
1169 | } | 1067 | // after recalling an image from cache at a lower discard than cached. RC |
1170 | 1068 | return; | |
1171 | //update an existing entry, write to header file immediately. | 1069 | } |
1172 | bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size) | ||
1173 | { | ||
1174 | S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ; | ||
1175 | |||
1176 | if(new_image_size == entry.mImageSize && new_body_size == entry.mBodySize) | ||
1177 | { | ||
1178 | return true ; //nothing changed. | ||
1179 | } | ||
1180 | else | ||
1181 | { | ||
1182 | bool purge = false ; | ||
1183 | |||
1184 | lockHeaders() ; | ||
1185 | |||
1186 | bool update_header = false ; | ||
1187 | if(entry.mImageSize < 0) //is a brand-new entry | ||
1188 | { | ||
1189 | mHeaderIDMap[entry.mID] = idx; | ||
1190 | mTexturesSizeMap[entry.mID] = new_body_size ; | ||
1191 | mTexturesSizeTotal += new_body_size ; | ||
1192 | |||
1193 | // Update Header | ||
1194 | update_header = true ; | ||
1195 | } | ||
1196 | else if (entry.mBodySize != new_body_size) | ||
1197 | { | ||
1198 | //already in mHeaderIDMap. | ||
1199 | mTexturesSizeMap[entry.mID] = new_body_size ; | ||
1200 | mTexturesSizeTotal -= entry.mBodySize ; | ||
1201 | mTexturesSizeTotal += new_body_size ; | ||
1202 | } | ||
1203 | entry.mTime = time(NULL); | ||
1204 | entry.mImageSize = new_image_size ; | ||
1205 | entry.mBodySize = new_body_size ; | ||
1206 | |||
1207 | writeEntryToHeaderImmediately(idx, entry, update_header) ; | ||
1208 | |||
1209 | if (mTexturesSizeTotal > sCacheMaxTexturesSize) | ||
1210 | { | ||
1211 | purge = true; | ||
1212 | } | ||
1213 | |||
1214 | unlockHeaders() ; | ||
1215 | 1070 | ||
1216 | if (purge) | 1071 | llassert_always(entry.mImageSize == 0 || entry.mImageSize == -1 || entry.mImageSize > entry.mBodySize); |
1217 | { | 1072 | if (entry.mBodySize > 0) |
1218 | mDoPurge = TRUE; | 1073 | { |
1074 | mTexturesSizeMap[entry.mID] = entry.mBodySize; | ||
1075 | } | ||
1076 | // llinfos << "Updating TE: " << idx << ": " << id << " Size: " << entry.mBodySize << " Time: " << entry.mTime << llendl; | ||
1077 | S32 offset = sizeof(EntriesInfo) + idx * sizeof(Entry); | ||
1078 | LLAPRFile* aprfile = openHeaderEntriesFile(false, offset); | ||
1079 | S32 bytes_written = aprfile->write((void*)&entry, (S32)sizeof(Entry)); | ||
1080 | llassert_always(bytes_written == sizeof(Entry)); | ||
1081 | mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, idx); | ||
1082 | closeHeaderEntriesFile(); | ||
1219 | } | 1083 | } |
1220 | } | 1084 | } |
1221 | |||
1222 | return false ; | ||
1223 | } | 1085 | } |
1224 | 1086 | ||
1225 | U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries) | 1087 | U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries) |
@@ -1231,21 +1093,7 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries) | |||
1231 | mFreeList.clear(); | 1093 | mFreeList.clear(); |
1232 | mTexturesSizeTotal = 0; | 1094 | mTexturesSizeTotal = 0; |
1233 | 1095 | ||
1234 | LLAPRFile* aprfile = NULL; | 1096 | LLAPRFile* aprfile = openHeaderEntriesFile(false, (S32)sizeof(EntriesInfo)); |
1235 | if(mUpdatedEntryMap.empty()) | ||
1236 | { | ||
1237 | aprfile = openHeaderEntriesFile(true, (S32)sizeof(EntriesInfo)); | ||
1238 | } | ||
1239 | else //update the header file first. | ||
1240 | { | ||
1241 | aprfile = openHeaderEntriesFile(false, 0); | ||
1242 | updatedHeaderEntriesFile() ; | ||
1243 | if(!aprfile) | ||
1244 | { | ||
1245 | return 0; | ||
1246 | } | ||
1247 | aprfile->seek(APR_SET, (S32)sizeof(EntriesInfo)); | ||
1248 | } | ||
1249 | for (U32 idx=0; idx<num_entries; idx++) | 1097 | for (U32 idx=0; idx<num_entries; idx++) |
1250 | { | 1098 | { |
1251 | Entry entry; | 1099 | Entry entry; |
@@ -1259,15 +1107,19 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries) | |||
1259 | } | 1107 | } |
1260 | entries.push_back(entry); | 1108 | entries.push_back(entry); |
1261 | // llinfos << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << llendl; | 1109 | // llinfos << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << llendl; |
1262 | if(entry.mImageSize > entry.mBodySize) | 1110 | if (entry.mImageSize < 0) |
1263 | { | 1111 | { |
1264 | mHeaderIDMap[entry.mID] = idx; | 1112 | mFreeList.insert(idx); |
1265 | mTexturesSizeMap[entry.mID] = entry.mBodySize; | ||
1266 | mTexturesSizeTotal += entry.mBodySize; | ||
1267 | } | 1113 | } |
1268 | else | 1114 | else |
1269 | { | 1115 | { |
1270 | mFreeList.insert(idx); | 1116 | mHeaderIDMap[entry.mID] = idx; |
1117 | if (entry.mBodySize > 0) | ||
1118 | { | ||
1119 | mTexturesSizeMap[entry.mID] = entry.mBodySize; | ||
1120 | mTexturesSizeTotal += entry.mBodySize; | ||
1121 | } | ||
1122 | llassert_always(entry.mImageSize == 0 || entry.mImageSize > entry.mBodySize); | ||
1271 | } | 1123 | } |
1272 | } | 1124 | } |
1273 | closeHeaderEntriesFile(); | 1125 | closeHeaderEntriesFile(); |
@@ -1285,65 +1137,13 @@ void LLTextureCache::writeEntriesAndClose(const std::vector<Entry>& entries) | |||
1285 | for (S32 idx=0; idx<num_entries; idx++) | 1137 | for (S32 idx=0; idx<num_entries; idx++) |
1286 | { | 1138 | { |
1287 | S32 bytes_written = aprfile->write((void*)(&entries[idx]), (S32)sizeof(Entry)); | 1139 | S32 bytes_written = aprfile->write((void*)(&entries[idx]), (S32)sizeof(Entry)); |
1288 | if(bytes_written != sizeof(Entry)) | 1140 | llassert_always(bytes_written == sizeof(Entry)); |
1289 | { | ||
1290 | clearCorruptedCache() ; //clear the cache. | ||
1291 | return ; | ||
1292 | } | ||
1293 | } | 1141 | } |
1142 | mHeaderEntriesMaxWriteIdx = llmax(mHeaderEntriesMaxWriteIdx, num_entries-1); | ||
1294 | closeHeaderEntriesFile(); | 1143 | closeHeaderEntriesFile(); |
1295 | } | 1144 | } |
1296 | } | 1145 | } |
1297 | 1146 | ||
1298 | void LLTextureCache::writeUpdatedEntries() | ||
1299 | { | ||
1300 | lockHeaders() ; | ||
1301 | if (!mReadOnly && !mUpdatedEntryMap.empty()) | ||
1302 | { | ||
1303 | openHeaderEntriesFile(false, 0); | ||
1304 | updatedHeaderEntriesFile() ; | ||
1305 | closeHeaderEntriesFile(); | ||
1306 | } | ||
1307 | unlockHeaders() ; | ||
1308 | } | ||
1309 | |||
1310 | //mHeaderMutex is locked and mHeaderAPRFile is created before calling this. | ||
1311 | void LLTextureCache::updatedHeaderEntriesFile() | ||
1312 | { | ||
1313 | if (!mReadOnly && !mUpdatedEntryMap.empty() && mHeaderAPRFile) | ||
1314 | { | ||
1315 | //entriesInfo | ||
1316 | mHeaderAPRFile->seek(APR_SET, 0); | ||
1317 | S32 bytes_written = mHeaderAPRFile->write((U8*)&mHeaderEntriesInfo, sizeof(EntriesInfo)) ; | ||
1318 | if(bytes_written != sizeof(EntriesInfo)) | ||
1319 | { | ||
1320 | clearCorruptedCache() ; //clear the cache. | ||
1321 | return ; | ||
1322 | } | ||
1323 | |||
1324 | //write each updated entry | ||
1325 | S32 entry_size = (S32)sizeof(Entry) ; | ||
1326 | S32 prev_idx = -1 ; | ||
1327 | S32 delta_idx ; | ||
1328 | for (idx_entry_map_t::iterator iter = mUpdatedEntryMap.begin(); iter != mUpdatedEntryMap.end(); ++iter) | ||
1329 | { | ||
1330 | delta_idx = iter->first - prev_idx - 1; | ||
1331 | prev_idx = iter->first ; | ||
1332 | if(delta_idx) | ||
1333 | { | ||
1334 | mHeaderAPRFile->seek(APR_CUR, delta_idx * entry_size); | ||
1335 | } | ||
1336 | |||
1337 | bytes_written = mHeaderAPRFile->write((void*)(&iter->second), entry_size); | ||
1338 | if(bytes_written != entry_size) | ||
1339 | { | ||
1340 | clearCorruptedCache() ; //clear the cache. | ||
1341 | return ; | ||
1342 | } | ||
1343 | } | ||
1344 | mUpdatedEntryMap.clear() ; | ||
1345 | } | ||
1346 | } | ||
1347 | //---------------------------------------------------------------------------- | 1147 | //---------------------------------------------------------------------------- |
1348 | 1148 | ||
1349 | // Called from either the main thread or the worker thread | 1149 | // Called from either the main thread or the worker thread |
@@ -1369,27 +1169,28 @@ void LLTextureCache::readHeaderCache() | |||
1369 | if (num_entries) | 1169 | if (num_entries) |
1370 | { | 1170 | { |
1371 | U32 empty_entries = 0; | 1171 | U32 empty_entries = 0; |
1372 | typedef std::pair<U32, S32> lru_data_t; | 1172 | typedef std::pair<U32, LLUUID> lru_data_t; |
1373 | std::set<lru_data_t> lru; | 1173 | std::set<lru_data_t> lru; |
1374 | std::set<U32> purge_list; | 1174 | std::vector<LLUUID> purge_list; |
1375 | for (U32 i=0; i<num_entries; i++) | 1175 | for (U32 i=0; i<num_entries; i++) |
1376 | { | 1176 | { |
1377 | Entry& entry = entries[i]; | 1177 | Entry& entry = entries[i]; |
1378 | if (entry.mImageSize <= 0) | 1178 | const LLUUID& id = entry.mID; |
1179 | if (entry.mImageSize < 0) | ||
1379 | { | 1180 | { |
1380 | // This will be in the Free List, don't put it in the LRU | 1181 | // This will be in the Free List, don't put it in the LRU |
1381 | ++empty_entries; | 1182 | ++empty_entries; |
1382 | } | 1183 | } |
1383 | else | 1184 | else |
1384 | { | 1185 | { |
1385 | lru.insert(std::make_pair(entry.mTime, i)); | 1186 | lru.insert(std::make_pair(entry.mTime, id)); |
1386 | if (entry.mBodySize > 0) | 1187 | if (entry.mBodySize > 0) |
1387 | { | 1188 | { |
1388 | if (entry.mBodySize > entry.mImageSize) | 1189 | if (entry.mBodySize > entry.mImageSize) |
1389 | { | 1190 | { |
1390 | // Shouldn't happen, failsafe only | 1191 | // Shouldn't happen, failsafe only |
1391 | llwarns << "Bad entry: " << i << ": " << entry.mID << ": BodySize: " << entry.mBodySize << llendl; | 1192 | llwarns << "Bad entry: " << i << ": " << id << ": BodySize: " << entry.mBodySize << llendl; |
1392 | purge_list.insert(i); | 1193 | purge_list.push_back(id); |
1393 | } | 1194 | } |
1394 | } | 1195 | } |
1395 | } | 1196 | } |
@@ -1399,24 +1200,22 @@ void LLTextureCache::readHeaderCache() | |||
1399 | // Special case: cache size was reduced, need to remove entries | 1200 | // Special case: cache size was reduced, need to remove entries |
1400 | // Note: After we prune entries, we will call this again and create the LRU | 1201 | // Note: After we prune entries, we will call this again and create the LRU |
1401 | U32 entries_to_purge = (num_entries-empty_entries) - sCacheMaxEntries; | 1202 | U32 entries_to_purge = (num_entries-empty_entries) - sCacheMaxEntries; |
1402 | llinfos << "Texture Cache Entries: " << num_entries << " Max: " << sCacheMaxEntries << " Empty: " << empty_entries << " Purging: " << entries_to_purge << llendl; | ||
1403 | if (entries_to_purge > 0) | 1203 | if (entries_to_purge > 0) |
1404 | { | 1204 | { |
1405 | for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter) | 1205 | for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter) |
1406 | { | 1206 | { |
1407 | purge_list.insert(iter->second); | 1207 | purge_list.push_back(iter->second); |
1408 | if (purge_list.size() >= entries_to_purge) | 1208 | if (--entries_to_purge <= 0) |
1409 | break; | 1209 | break; |
1410 | } | 1210 | } |
1411 | } | 1211 | } |
1412 | llassert_always(purge_list.size() >= entries_to_purge); | ||
1413 | } | 1212 | } |
1414 | else | 1213 | else |
1415 | { | 1214 | { |
1416 | S32 lru_entries = (S32)((F32)sCacheMaxEntries * TEXTURE_CACHE_LRU_SIZE); | 1215 | S32 lru_entries = (S32)((F32)sCacheMaxEntries * TEXTURE_CACHE_LRU_SIZE); |
1417 | for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter) | 1216 | for (std::set<lru_data_t>::iterator iter = lru.begin(); iter != lru.end(); ++iter) |
1418 | { | 1217 | { |
1419 | mLRU.insert(entries[iter->second].mID); | 1218 | mLRU.insert(iter->second); |
1420 | // llinfos << "LRU: " << iter->first << " : " << iter->second << llendl; | 1219 | // llinfos << "LRU: " << iter->first << " : " << iter->second << llendl; |
1421 | if (--lru_entries <= 0) | 1220 | if (--lru_entries <= 0) |
1422 | break; | 1221 | break; |
@@ -1425,10 +1224,11 @@ void LLTextureCache::readHeaderCache() | |||
1425 | 1224 | ||
1426 | if (purge_list.size() > 0) | 1225 | if (purge_list.size() > 0) |
1427 | { | 1226 | { |
1428 | for (std::set<U32>::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) | 1227 | for (std::vector<LLUUID>::iterator iter = purge_list.begin(); iter != purge_list.end(); ++iter) |
1429 | { | 1228 | { |
1430 | std::string tex_filename = getTextureFileName(entries[*iter].mID); | 1229 | mHeaderMutex.unlock(); |
1431 | removeEntry((S32)*iter, entries[*iter], tex_filename); | 1230 | removeFromCache(*iter); |
1231 | mHeaderMutex.lock(); | ||
1432 | } | 1232 | } |
1433 | // If we removed any entries, we need to rebuild the entries list, | 1233 | // If we removed any entries, we need to rebuild the entries list, |
1434 | // write the header, and call this again | 1234 | // write the header, and call this again |
@@ -1436,14 +1236,13 @@ void LLTextureCache::readHeaderCache() | |||
1436 | for (U32 i=0; i<num_entries; i++) | 1236 | for (U32 i=0; i<num_entries; i++) |
1437 | { | 1237 | { |
1438 | const Entry& entry = entries[i]; | 1238 | const Entry& entry = entries[i]; |
1439 | if (entry.mImageSize > 0) | 1239 | if (entry.mImageSize >=0) |
1440 | { | 1240 | { |
1441 | new_entries.push_back(entry); | 1241 | new_entries.push_back(entry); |
1442 | } | 1242 | } |
1443 | } | 1243 | } |
1444 | llassert_always(new_entries.size() <= sCacheMaxEntries); | 1244 | llassert_always(new_entries.size() <= sCacheMaxEntries); |
1445 | mHeaderEntriesInfo.mEntries = new_entries.size(); | 1245 | mHeaderEntriesInfo.mEntries = new_entries.size(); |
1446 | writeEntriesHeader(); | ||
1447 | writeEntriesAndClose(new_entries); | 1246 | writeEntriesAndClose(new_entries); |
1448 | mHeaderMutex.unlock(); // unlock the mutex before calling again | 1247 | mHeaderMutex.unlock(); // unlock the mutex before calling again |
1449 | readHeaderCache(); // repeat with new entries file | 1248 | readHeaderCache(); // repeat with new entries file |
@@ -1451,7 +1250,7 @@ void LLTextureCache::readHeaderCache() | |||
1451 | } | 1250 | } |
1452 | else | 1251 | else |
1453 | { | 1252 | { |
1454 | //entries are not changed, nothing here. | 1253 | writeEntriesAndClose(entries); |
1455 | } | 1254 | } |
1456 | } | 1255 | } |
1457 | } | 1256 | } |
@@ -1460,29 +1259,6 @@ void LLTextureCache::readHeaderCache() | |||
1460 | 1259 | ||
1461 | ////////////////////////////////////////////////////////////////////////////// | 1260 | ////////////////////////////////////////////////////////////////////////////// |
1462 | 1261 | ||
1463 | //the header mutex is locked before calling this. | ||
1464 | void LLTextureCache::clearCorruptedCache() | ||
1465 | { | ||
1466 | llwarns << "the texture cache is corrupted, need to be cleared." << llendl ; | ||
1467 | |||
1468 | closeHeaderEntriesFile();//close possible file handler | ||
1469 | purgeAllTextures(false) ; //clear the cache. | ||
1470 | |||
1471 | if (!mReadOnly) //regenerate the directory tree if not exists. | ||
1472 | { | ||
1473 | LLFile::mkdir(mTexturesDirName); | ||
1474 | |||
1475 | const char* subdirs = "0123456789abcdef"; | ||
1476 | for (S32 i=0; i<16; i++) | ||
1477 | { | ||
1478 | std::string dirname = mTexturesDirName + gDirUtilp->getDirDelimiter() + subdirs[i]; | ||
1479 | LLFile::mkdir(dirname); | ||
1480 | } | ||
1481 | } | ||
1482 | |||
1483 | return ; | ||
1484 | } | ||
1485 | |||
1486 | void LLTextureCache::purgeAllTextures(bool purge_directories) | 1262 | void LLTextureCache::purgeAllTextures(bool purge_directories) |
1487 | { | 1263 | { |
1488 | if (!mReadOnly) | 1264 | if (!mReadOnly) |
@@ -1493,7 +1269,6 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) | |||
1493 | for (S32 i=0; i<16; i++) | 1269 | for (S32 i=0; i<16; i++) |
1494 | { | 1270 | { |
1495 | std::string dirname = mTexturesDirName + delem + subdirs[i]; | 1271 | std::string dirname = mTexturesDirName + delem + subdirs[i]; |
1496 | llinfos << "Deleting files in directory: " << dirname << llendl; | ||
1497 | gDirUtilp->deleteFilesInDir(dirname,mask); | 1272 | gDirUtilp->deleteFilesInDir(dirname,mask); |
1498 | if (purge_directories) | 1273 | if (purge_directories) |
1499 | { | 1274 | { |
@@ -1502,23 +1277,19 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) | |||
1502 | } | 1277 | } |
1503 | if (purge_directories) | 1278 | if (purge_directories) |
1504 | { | 1279 | { |
1505 | gDirUtilp->deleteFilesInDir(mTexturesDirName, mask); | ||
1506 | LLFile::rmdir(mTexturesDirName); | 1280 | LLFile::rmdir(mTexturesDirName); |
1507 | } | 1281 | } |
1508 | } | 1282 | } |
1509 | mHeaderIDMap.clear(); | 1283 | mHeaderIDMap.clear(); |
1510 | mTexturesSizeMap.clear(); | 1284 | mTexturesSizeMap.clear(); |
1511 | mTexturesSizeTotal = 0; | 1285 | mTexturesSizeTotal = 0; |
1512 | mFreeList.clear(); | 1286 | mFreeList.clear(); |
1513 | mTexturesSizeTotal = 0; | 1287 | mTexturesSizeTotal = 0; |
1514 | mUpdatedEntryMap.clear(); | ||
1515 | 1288 | ||
1516 | // Info with 0 entries | 1289 | // Info with 0 entries |
1517 | mHeaderEntriesInfo.mVersion = sHeaderCacheVersion; | 1290 | mHeaderEntriesInfo.mVersion = sHeaderCacheVersion; |
1518 | mHeaderEntriesInfo.mEntries = 0; | 1291 | mHeaderEntriesInfo.mEntries = 0; |
1519 | writeEntriesHeader(); | 1292 | writeEntriesHeader(); |
1520 | |||
1521 | llinfos << "The entire texture cache is cleared." << llendl ; | ||
1522 | } | 1293 | } |
1523 | 1294 | ||
1524 | void LLTextureCache::purgeTextures(bool validate) | 1295 | void LLTextureCache::purgeTextures(bool validate) |
@@ -1543,6 +1314,7 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1543 | U32 num_entries = openAndReadEntries(entries); | 1314 | U32 num_entries = openAndReadEntries(entries); |
1544 | if (!num_entries) | 1315 | if (!num_entries) |
1545 | { | 1316 | { |
1317 | writeEntriesAndClose(entries); | ||
1546 | return; // nothing to purge | 1318 | return; // nothing to purge |
1547 | } | 1319 | } |
1548 | 1320 | ||
@@ -1561,10 +1333,6 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1561 | time_idx_set.insert(std::make_pair(entries[idx].mTime, idx)); | 1333 | time_idx_set.insert(std::make_pair(entries[idx].mTime, idx)); |
1562 | // llinfos << "TIME: " << entries[idx].mTime << " TEX: " << entries[idx].mID << " IDX: " << idx << " Size: " << entries[idx].mImageSize << llendl; | 1334 | // llinfos << "TIME: " << entries[idx].mTime << " TEX: " << entries[idx].mID << " IDX: " << idx << " Size: " << entries[idx].mImageSize << llendl; |
1563 | } | 1335 | } |
1564 | else | ||
1565 | { | ||
1566 | llerrs << "mTexturesSizeMap / mHeaderIDMap corrupted." << llendl ; | ||
1567 | } | ||
1568 | } | 1336 | } |
1569 | } | 1337 | } |
1570 | 1338 | ||
@@ -1616,8 +1384,11 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1616 | { | 1384 | { |
1617 | purge_count++; | 1385 | purge_count++; |
1618 | LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL; | 1386 | LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL; |
1619 | removeEntry(idx, entries[idx], filename) ; | 1387 | LLAPRFile::remove(filename); |
1620 | cache_size -= entries[idx].mBodySize; | 1388 | cache_size -= entries[idx].mBodySize; |
1389 | mTexturesSizeTotal -= entries[idx].mBodySize; | ||
1390 | entries[idx].mBodySize = 0; | ||
1391 | mTexturesSizeMap.erase(entries[idx].mID); | ||
1621 | } | 1392 | } |
1622 | } | 1393 | } |
1623 | 1394 | ||
@@ -1625,8 +1396,11 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1625 | 1396 | ||
1626 | writeEntriesAndClose(entries); | 1397 | writeEntriesAndClose(entries); |
1627 | 1398 | ||
1628 | // *FIX:Mani - watchdog back on. | 1399 | if (!mThreaded) |
1629 | LLAppViewer::instance()->resumeMainloopTimeout(); | 1400 | { |
1401 | // *FIX:Mani - watchdog back on. | ||
1402 | LLAppViewer::instance()->resumeMainloopTimeout(); | ||
1403 | } | ||
1630 | 1404 | ||
1631 | LL_INFOS("TextureCache") << "TEXTURE CACHE:" | 1405 | LL_INFOS("TextureCache") << "TEXTURE CACHE:" |
1632 | << " PURGED: " << purge_count | 1406 | << " PURGED: " << purge_count |
@@ -1664,38 +1438,40 @@ LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle) | |||
1664 | // Called from work thread | 1438 | // Called from work thread |
1665 | 1439 | ||
1666 | // Reads imagesize from the header, updates timestamp | 1440 | // Reads imagesize from the header, updates timestamp |
1667 | S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry) | 1441 | S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, S32& imagesize) |
1668 | { | 1442 | { |
1669 | LLMutexLock lock(&mHeaderMutex); | 1443 | LLMutexLock lock(&mHeaderMutex); |
1444 | Entry entry; | ||
1670 | S32 idx = openAndReadEntry(id, entry, false); | 1445 | S32 idx = openAndReadEntry(id, entry, false); |
1671 | if (idx >= 0) | 1446 | if (idx >= 0) |
1672 | { | 1447 | { |
1673 | updateEntryTimeStamp(idx, entry); // updates time | 1448 | imagesize = entry.mImageSize; |
1449 | writeEntryAndClose(idx, entry); // updates time | ||
1674 | } | 1450 | } |
1675 | return idx; | 1451 | return idx; |
1676 | } | 1452 | } |
1677 | 1453 | ||
1678 | // Writes imagesize to the header, updates timestamp | 1454 | // Writes imagesize to the header, updates timestamp |
1679 | S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize) | 1455 | S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, S32 imagesize) |
1680 | { | 1456 | { |
1681 | mHeaderMutex.lock(); | 1457 | mHeaderMutex.lock(); |
1458 | llassert_always(imagesize >= 0); | ||
1459 | Entry entry; | ||
1682 | S32 idx = openAndReadEntry(id, entry, true); | 1460 | S32 idx = openAndReadEntry(id, entry, true); |
1683 | mHeaderMutex.unlock(); | ||
1684 | |||
1685 | if (idx >= 0) | 1461 | if (idx >= 0) |
1686 | { | 1462 | { |
1687 | updateEntry(idx, entry, imagesize, datasize); | 1463 | entry.mImageSize = imagesize; |
1464 | writeEntryAndClose(idx, entry); | ||
1465 | mHeaderMutex.unlock(); | ||
1688 | } | 1466 | } |
1689 | 1467 | else // retry | |
1690 | if(idx < 0) // retry | ||
1691 | { | 1468 | { |
1469 | mHeaderMutex.unlock(); | ||
1692 | readHeaderCache(); // We couldn't write an entry, so refresh the LRU | 1470 | readHeaderCache(); // We couldn't write an entry, so refresh the LRU |
1693 | |||
1694 | mHeaderMutex.lock(); | 1471 | mHeaderMutex.lock(); |
1695 | llassert_always(!mLRU.empty() || mHeaderEntriesInfo.mEntries < sCacheMaxEntries); | 1472 | llassert_always(!mLRU.empty() || mHeaderEntriesInfo.mEntries < sCacheMaxEntries); |
1696 | mHeaderMutex.unlock(); | 1473 | mHeaderMutex.unlock(); |
1697 | 1474 | idx = setHeaderCacheEntry(id, imagesize); // assert above ensures no inf. recursion | |
1698 | idx = setHeaderCacheEntry(id, entry, imagesize, datasize); // assert above ensures no inf. recursion | ||
1699 | } | 1475 | } |
1700 | return idx; | 1476 | return idx; |
1701 | } | 1477 | } |
@@ -1732,34 +1508,39 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri | |||
1732 | return handle; | 1508 | return handle; |
1733 | } | 1509 | } |
1734 | 1510 | ||
1735 | 1511 | // Return true if the handle is not valid, which is the case | |
1512 | // when the worker was already deleted or is scheduled for deletion. | ||
1513 | // | ||
1514 | // If the handle exists and a call to worker->complete() returns | ||
1515 | // true or abort is true, then the handle is removed and the worker | ||
1516 | // scheduled for deletion. | ||
1736 | bool LLTextureCache::readComplete(handle_t handle, bool abort) | 1517 | bool LLTextureCache::readComplete(handle_t handle, bool abort) |
1737 | { | 1518 | { |
1738 | lockWorkers(); | 1519 | lockWorkers(); // Needed for access to mReaders. |
1520 | |||
1739 | handle_map_t::iterator iter = mReaders.find(handle); | 1521 | handle_map_t::iterator iter = mReaders.find(handle); |
1522 | bool handle_is_valid = iter != mReaders.end(); | ||
1523 | llassert_always(handle_is_valid || abort); | ||
1740 | LLTextureCacheWorker* worker = NULL; | 1524 | LLTextureCacheWorker* worker = NULL; |
1741 | bool complete = false; | 1525 | bool delete_worker = false; |
1742 | if (iter != mReaders.end()) | 1526 | |
1527 | if (handle_is_valid) | ||
1743 | { | 1528 | { |
1744 | worker = iter->second; | 1529 | worker = iter->second; |
1745 | complete = worker->complete(); | 1530 | delete_worker = worker->complete() || abort; |
1746 | 1531 | if (delete_worker) | |
1747 | if(!complete && abort) | ||
1748 | { | 1532 | { |
1749 | abortRequest(handle, true) ; | 1533 | mReaders.erase(handle); |
1534 | handle_is_valid = false; | ||
1750 | } | 1535 | } |
1751 | } | 1536 | } |
1752 | if (worker && (complete || abort)) | 1537 | |
1753 | { | 1538 | unlockWorkers(); |
1754 | mReaders.erase(iter); | 1539 | |
1755 | unlockWorkers(); | 1540 | if (delete_worker) worker->scheduleDelete(); |
1756 | worker->scheduleDelete(); | 1541 | |
1757 | } | 1542 | // Return false if the handle is (still) valid. |
1758 | else | 1543 | return !handle_is_valid; |
1759 | { | ||
1760 | unlockWorkers(); | ||
1761 | } | ||
1762 | return (complete || abort); | ||
1763 | } | 1544 | } |
1764 | 1545 | ||
1765 | LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority, | 1546 | LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority, |
@@ -1792,20 +1573,20 @@ bool LLTextureCache::writeComplete(handle_t handle, bool abort) | |||
1792 | { | 1573 | { |
1793 | lockWorkers(); | 1574 | lockWorkers(); |
1794 | handle_map_t::iterator iter = mWriters.find(handle); | 1575 | handle_map_t::iterator iter = mWriters.find(handle); |
1795 | llassert(iter != mWriters.end()); | 1576 | llassert_always(iter != mWriters.end()); |
1796 | if (iter != mWriters.end()) | 1577 | LLTextureCacheWorker* worker = iter->second; |
1578 | if (worker->complete() || abort) | ||
1797 | { | 1579 | { |
1798 | LLTextureCacheWorker* worker = iter->second; | 1580 | mWriters.erase(handle); |
1799 | if (worker->complete() || abort) | 1581 | unlockWorkers(); |
1800 | { | 1582 | worker->scheduleDelete(); |
1801 | mWriters.erase(handle); | 1583 | return true; |
1802 | unlockWorkers(); | 1584 | } |
1803 | worker->scheduleDelete(); | 1585 | else |
1804 | return true; | 1586 | { |
1805 | } | 1587 | unlockWorkers(); |
1588 | return false; | ||
1806 | } | 1589 | } |
1807 | unlockWorkers(); | ||
1808 | return false; | ||
1809 | } | 1590 | } |
1810 | 1591 | ||
1811 | void LLTextureCache::prioritizeWrite(handle_t handle) | 1592 | void LLTextureCache::prioritizeWrite(handle_t handle) |
@@ -1824,56 +1605,38 @@ void LLTextureCache::addCompleted(Responder* responder, bool success) | |||
1824 | 1605 | ||
1825 | ////////////////////////////////////////////////////////////////////////////// | 1606 | ////////////////////////////////////////////////////////////////////////////// |
1826 | 1607 | ||
1827 | //called after mHeaderMutex is locked. | 1608 | // Called from MAIN thread (endWork()) |
1828 | void LLTextureCache::removeCachedTexture(const LLUUID& id) | ||
1829 | { | ||
1830 | if(mTexturesSizeMap.find(id) != mTexturesSizeMap.end()) | ||
1831 | { | ||
1832 | mTexturesSizeTotal -= mTexturesSizeMap[id] ; | ||
1833 | mTexturesSizeMap.erase(id); | ||
1834 | } | ||
1835 | mHeaderIDMap.erase(id); | ||
1836 | LLAPRFile::remove(getTextureFileName(id)); | ||
1837 | } | ||
1838 | 1609 | ||
1839 | //called after mHeaderMutex is locked. | 1610 | bool LLTextureCache::removeHeaderCacheEntry(const LLUUID& id) |
1840 | void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename) | ||
1841 | { | 1611 | { |
1842 | if(idx >= 0) //valid entry | 1612 | if (!mReadOnly) |
1843 | { | 1613 | { |
1844 | entry.mImageSize = -1; | 1614 | LLMutexLock lock(&mHeaderMutex); |
1845 | entry.mBodySize = 0; | 1615 | Entry entry; |
1846 | mHeaderIDMap.erase(entry.mID); | 1616 | S32 idx = openAndReadEntry(id, entry, false); |
1847 | mTexturesSizeMap.erase(entry.mID); | 1617 | if (idx >= 0) |
1848 | 1618 | { | |
1849 | mTexturesSizeTotal -= entry.mBodySize; | 1619 | entry.mImageSize = -1; |
1850 | mFreeList.insert(idx); | 1620 | entry.mBodySize = 0; |
1621 | writeEntryAndClose(idx, entry); | ||
1622 | mFreeList.insert(idx); | ||
1623 | mHeaderIDMap.erase(id); | ||
1624 | mTexturesSizeMap.erase(id); | ||
1625 | return true; | ||
1626 | } | ||
1851 | } | 1627 | } |
1852 | 1628 | return false; | |
1853 | LLAPRFile::remove(filename); | ||
1854 | } | 1629 | } |
1855 | 1630 | ||
1856 | bool LLTextureCache::removeFromCache(const LLUUID& id) | 1631 | void LLTextureCache::removeFromCache(const LLUUID& id) |
1857 | { | 1632 | { |
1858 | //llwarns << "Removing texture from cache: " << id << llendl; | 1633 | //llwarns << "Removing texture from cache: " << id << llendl; |
1859 | bool ret = false ; | ||
1860 | if (!mReadOnly) | 1634 | if (!mReadOnly) |
1861 | { | 1635 | { |
1862 | lockHeaders() ; | 1636 | removeHeaderCacheEntry(id); |
1863 | 1637 | LLMutexLock lock(&mHeaderMutex); | |
1864 | Entry entry; | 1638 | LLAPRFile::remove(getTextureFileName(id)); |
1865 | S32 idx = openAndReadEntry(id, entry, false); | ||
1866 | std::string tex_filename = getTextureFileName(id); | ||
1867 | removeEntry(idx, entry, tex_filename) ; | ||
1868 | if (idx >= 0) | ||
1869 | { | ||
1870 | writeEntryToHeaderImmediately(idx, entry); | ||
1871 | ret = true; | ||
1872 | } | ||
1873 | |||
1874 | unlockHeaders() ; | ||
1875 | } | 1639 | } |
1876 | return ret ; | ||
1877 | } | 1640 | } |
1878 | 1641 | ||
1879 | ////////////////////////////////////////////////////////////////////////////// | 1642 | ////////////////////////////////////////////////////////////////////////////// |
diff --git a/linden/indra/newview/lltexturecache.h b/linden/indra/newview/lltexturecache.h index f80be00..45804c2 100644 --- a/linden/indra/newview/lltexturecache.h +++ b/linden/indra/newview/lltexturecache.h | |||
@@ -40,7 +40,6 @@ | |||
40 | 40 | ||
41 | #include "llworkerthread.h" | 41 | #include "llworkerthread.h" |
42 | 42 | ||
43 | class LLImageFormatted; | ||
44 | class LLTextureCacheWorker; | 43 | class LLTextureCacheWorker; |
45 | 44 | ||
46 | class LLTextureCache : public LLWorkerThread | 45 | class LLTextureCache : public LLWorkerThread |
@@ -59,16 +58,10 @@ private: | |||
59 | }; | 58 | }; |
60 | struct Entry | 59 | struct Entry |
61 | { | 60 | { |
62 | Entry() : | 61 | Entry() {} |
63 | mBodySize(0), | ||
64 | mImageSize(0), | ||
65 | mTime(0) | ||
66 | { | ||
67 | } | ||
68 | Entry(const LLUUID& id, S32 imagesize, S32 bodysize, U32 time) : | 62 | Entry(const LLUUID& id, S32 imagesize, S32 bodysize, U32 time) : |
69 | mID(id), mImageSize(imagesize), mBodySize(bodysize), mTime(time) {} | 63 | mID(id), mImageSize(imagesize), mBodySize(bodysize), mTime(time) {} |
70 | void init(const LLUUID& id, U32 time) { mID = id, mImageSize = 0; mBodySize = 0; mTime = time; } | 64 | void init(const LLUUID& id, U32 time) { mID = id, mImageSize = 0; mBodySize = 0; mTime = time; } |
71 | Entry& operator=(const Entry& entry) {mID = entry.mID, mImageSize = entry.mImageSize; mBodySize = entry.mBodySize; mTime = entry.mTime; return *this;} | ||
72 | LLUUID mID; // 16 bytes | 65 | LLUUID mID; // 16 bytes |
73 | S32 mImageSize; // total size of image if known | 66 | S32 mImageSize; // total size of image if known |
74 | S32 mBodySize; // size of body file in body cache | 67 | S32 mBodySize; // size of body file in body cache |
@@ -110,8 +103,7 @@ public: | |||
110 | /*virtual*/ S32 update(U32 max_time_ms); | 103 | /*virtual*/ S32 update(U32 max_time_ms); |
111 | 104 | ||
112 | void purgeCache(ELLPath location); | 105 | void purgeCache(ELLPath location); |
113 | void setReadOnly(BOOL read_only) ; | 106 | S64 initCache(ELLPath location, S64 maxsize, BOOL read_only); |
114 | S64 initCache(ELLPath location, S64 maxsize, BOOL disable_texture_cache); | ||
115 | 107 | ||
116 | handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size, | 108 | handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size, |
117 | ReadResponder* responder); | 109 | ReadResponder* responder); |
@@ -124,7 +116,7 @@ public: | |||
124 | bool writeComplete(handle_t handle, bool abort = false); | 116 | bool writeComplete(handle_t handle, bool abort = false); |
125 | void prioritizeWrite(handle_t handle); | 117 | void prioritizeWrite(handle_t handle); |
126 | 118 | ||
127 | bool removeFromCache(const LLUUID& id); | 119 | void removeFromCache(const LLUUID& id); |
128 | 120 | ||
129 | // For LLTextureCacheWorker::Responder | 121 | // For LLTextureCacheWorker::Responder |
130 | LLTextureCacheWorker* getReader(handle_t handle); | 122 | LLTextureCacheWorker* getReader(handle_t handle); |
@@ -139,11 +131,10 @@ public: | |||
139 | S64 getMaxUsage() { return sCacheMaxTexturesSize; } | 131 | S64 getMaxUsage() { return sCacheMaxTexturesSize; } |
140 | U32 getEntries() { return mHeaderEntriesInfo.mEntries; } | 132 | U32 getEntries() { return mHeaderEntriesInfo.mEntries; } |
141 | U32 getMaxEntries() { return sCacheMaxEntries; }; | 133 | U32 getMaxEntries() { return sCacheMaxEntries; }; |
142 | BOOL isInCache(const LLUUID& id) ; | ||
143 | BOOL isInLocal(const LLUUID& id) ; | ||
144 | 134 | ||
145 | protected: | 135 | protected: |
146 | // Accessed by LLTextureCacheWorker | 136 | // Accessed by LLTextureCacheWorker |
137 | bool updateTextureEntryList(const LLUUID& id, S32 size); | ||
147 | std::string getLocalFileName(const LLUUID& id); | 138 | std::string getLocalFileName(const LLUUID& id); |
148 | std::string getTextureFileName(const LLUUID& id); | 139 | std::string getTextureFileName(const LLUUID& id); |
149 | void addCompleted(Responder* responder, bool success); | 140 | void addCompleted(Responder* responder, bool success); |
@@ -154,7 +145,6 @@ protected: | |||
154 | private: | 145 | private: |
155 | void setDirNames(ELLPath location); | 146 | void setDirNames(ELLPath location); |
156 | void readHeaderCache(); | 147 | void readHeaderCache(); |
157 | void clearCorruptedCache(); | ||
158 | void purgeAllTextures(bool purge_directories); | 148 | void purgeAllTextures(bool purge_directories); |
159 | void purgeTextures(bool validate); | 149 | void purgeTextures(bool validate); |
160 | LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset); | 150 | LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset); |
@@ -162,20 +152,12 @@ private: | |||
162 | void readEntriesHeader(); | 152 | void readEntriesHeader(); |
163 | void writeEntriesHeader(); | 153 | void writeEntriesHeader(); |
164 | S32 openAndReadEntry(const LLUUID& id, Entry& entry, bool create); | 154 | S32 openAndReadEntry(const LLUUID& id, Entry& entry, bool create); |
165 | bool updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_body_size); | 155 | void writeEntryAndClose(S32 idx, Entry& entry); |
166 | void updateEntryTimeStamp(S32 idx, Entry& entry) ; | ||
167 | U32 openAndReadEntries(std::vector<Entry>& entries); | 156 | U32 openAndReadEntries(std::vector<Entry>& entries); |
168 | void writeEntriesAndClose(const std::vector<Entry>& entries); | 157 | void writeEntriesAndClose(const std::vector<Entry>& entries); |
169 | void readEntryFromHeaderImmediately(S32& idx, Entry& entry) ; | 158 | S32 getHeaderCacheEntry(const LLUUID& id, S32& imagesize); |
170 | void writeEntryToHeaderImmediately(S32& idx, Entry& entry, bool write_header = false) ; | 159 | S32 setHeaderCacheEntry(const LLUUID& id, S32 imagesize); |
171 | void removeEntry(S32 idx, Entry& entry, std::string& filename); | 160 | bool removeHeaderCacheEntry(const LLUUID& id); |
172 | void removeCachedTexture(const LLUUID& id) ; | ||
173 | S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry); | ||
174 | S32 setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize); | ||
175 | void writeUpdatedEntries() ; | ||
176 | void updatedHeaderEntriesFile() ; | ||
177 | void lockHeaders() { mHeaderMutex.lock(); } | ||
178 | void unlockHeaders() { mHeaderMutex.unlock(); } | ||
179 | 161 | ||
180 | private: | 162 | private: |
181 | // Internal | 163 | // Internal |
@@ -212,9 +194,6 @@ private: | |||
212 | S64 mTexturesSizeTotal; | 194 | S64 mTexturesSizeTotal; |
213 | LLAtomic32<BOOL> mDoPurge; | 195 | LLAtomic32<BOOL> mDoPurge; |
214 | 196 | ||
215 | typedef std::map<S32, Entry> idx_entry_map_t; | ||
216 | idx_entry_map_t mUpdatedEntryMap; | ||
217 | |||
218 | // Statics | 197 | // Statics |
219 | static F32 sHeaderCacheVersion; | 198 | static F32 sHeaderCacheVersion; |
220 | static U32 sCacheMaxEntries; | 199 | static U32 sCacheMaxEntries; |
diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index 427e55a..2184478 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp | |||
@@ -1500,8 +1500,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image | |||
1500 | 1500 | ||
1501 | LLTextureFetch::~LLTextureFetch() | 1501 | LLTextureFetch::~LLTextureFetch() |
1502 | { | 1502 | { |
1503 | clearDeleteList() ; | ||
1504 | |||
1505 | // ~LLQueuedThread() called here | 1503 | // ~LLQueuedThread() called here |
1506 | } | 1504 | } |
1507 | 1505 | ||