lltexturecache.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /**
  2. * @file lltexturecache.h
  3. * @brief Object for managing texture cachees.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewergpl$
  6. *
  7. * Copyright (c) 2000-2009, Linden Research, Inc.
  8. * Copyright (c) 2011-2023, Henri Beauchamp.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #ifndef LL_LLTEXTURECACHE_H
  34. #define LL_LLTEXTURECACHE_H
  35. #include <map>
  36. #include <memory>
  37. #include <set>
  38. #include "lldir.h"
  39. #include "hbfastmap.h"
  40. #include "llfile.h"
  41. #include "llimage.h"
  42. #include "llstring.h"
  43. #include "llthreadpool.h"
  44. #include "lluuid.h"
  45. class LLTextureCache
  46. {
  47. friend class LLTextureCacheWorker;
  48. friend class LLTextureCacheRemoteWorker;
  49. friend class LLTextureCacheLocalFileWorker;
  50. protected:
  51. LOG_CLASS(LLTextureCache);
  52. private:
  53. // Entries
  54. struct EntriesInfo
  55. {
  56. EntriesInfo()
  57. : mVersion(0.f),
  58. mAddressSize(0),
  59. mEntries(0)
  60. {
  61. }
  62. F32 mVersion;
  63. U32 mAddressSize;
  64. U32 mEntries;
  65. };
  66. struct Entry
  67. {
  68. Entry()
  69. : mBodySize(0),
  70. mImageSize(0),
  71. mTime(0)
  72. {
  73. }
  74. Entry(const LLUUID& id, S32 imagesize, S32 bodysize, U32 time)
  75. : mID(id),
  76. mImageSize(imagesize),
  77. mBodySize(bodysize),
  78. mTime(time)
  79. {
  80. }
  81. LL_INLINE void init(const LLUUID& id, U32 time)
  82. {
  83. mID = id;
  84. mImageSize = mBodySize = 0;
  85. mTime = time;
  86. }
  87. LL_INLINE Entry& operator=(const Entry& entry)
  88. {
  89. mID = entry.mID;
  90. mImageSize = entry.mImageSize;
  91. mBodySize = entry.mBodySize;
  92. mTime = entry.mTime;
  93. return *this;
  94. }
  95. LLUUID mID; // 16 bytes
  96. S32 mImageSize; // total size of image if known
  97. S32 mBodySize; // size of body file in body cache
  98. U32 mTime; // seconds since 1/1/1970
  99. };
  100. public:
  101. class Responder : public LLThreadSafeRefCount
  102. {
  103. public:
  104. virtual ~Responder() = default;
  105. virtual void started() = 0;
  106. virtual void completed(bool success) = 0;
  107. virtual void setData(U8* data, S32 datasize, S32 imagesize,
  108. S32 imageformat, bool imagelocal) = 0;
  109. };
  110. class ReadResponder : public Responder
  111. {
  112. public:
  113. LL_INLINE ReadResponder()
  114. : mImageSize(0),
  115. mImageLocal(false)
  116. {
  117. }
  118. // Called from LLTextureCacheWorker::finishRead()
  119. void setData(U8* data, S32 datasize, S32 imagesize,
  120. S32 imageformat, bool imagelocal) override;
  121. // Called from LLTextureFetchWorker::CacheReadResponder constructor
  122. LL_INLINE void setImage(LLImageFormatted* image)
  123. {
  124. mFormattedImage = image;
  125. }
  126. protected:
  127. LLPointer<LLImageFormatted> mFormattedImage;
  128. S32 mImageSize;
  129. bool mImageLocal;
  130. };
  131. class WriteResponder : public Responder
  132. {
  133. // Not used for write operations.
  134. LL_INLINE void setData(U8*, S32, S32, S32, bool) override
  135. {
  136. }
  137. };
  138. LLTextureCache();
  139. ~LLTextureCache();
  140. void shutdown();
  141. S32 update();
  142. void purgeCache(ELLPath location);
  143. // Called from the main thread before initCache() is called.
  144. LL_INLINE void setReadOnly(bool read_only) { mReadOnly = read_only; }
  145. S64 initCache(ELLPath location, S64 maxsize);
  146. typedef U32 handle_t;
  147. // This is for reads from local files (typically, UI textures).
  148. bool readFromFile(const std::string& local_filename, const LLUUID& id,
  149. S32 offset, S32 size, ReadResponder* responder);
  150. // This is for reads from the actual textures cache.
  151. bool readFromCache(const LLUUID& id, S32 offset, S32 size,
  152. ReadResponder* responder);
  153. bool writeToCache(const LLUUID& id, U8* data, S32 datasize,
  154. S32 imagesize, LLPointer<LLImageRaw> rawimage,
  155. S32 discardlevel, WriteResponder* responder);
  156. bool removeFromCache(const LLUUID& id);
  157. // Debug
  158. LL_INLINE U32 getNumReads() { return mNumReads; }
  159. LL_INLINE U32 getNumWrites() { return mNumWrites; }
  160. LL_INLINE S64 getUsage() { return mTexturesSizeTotal; }
  161. LL_INLINE U32 getEntries() { return mHeaderEntriesInfo.mEntries; }
  162. bool isInCache(const LLUUID& id);
  163. bool isInLocal(const LLUUID& id); // NOT thread-safe
  164. LL_INLINE static S64 getMaxUsage() { return sCacheMaxTexturesSize; }
  165. protected:
  166. std::string getLocalFileName(const LLUUID& id);
  167. std::string getTextureFileName(const LLUUID& id);
  168. void setDirNames(ELLPath location);
  169. void readHeaderCache();
  170. void clearCorruptedCache();
  171. void purgeAllTextures(bool purge_directories);
  172. void purgeTextures(bool validate);
  173. void purgeTextureFilesTimeSliced(bool force = false);
  174. LLFile* openHeaderEntriesFile(bool readonly, S32 offset);
  175. void closeHeaderEntriesFile();
  176. void readEntriesHeader();
  177. void writeEntriesHeader();
  178. S32 openAndReadEntry(const LLUUID& id, Entry& entry, bool create);
  179. bool updateEntry(S32& idx, Entry& entry, S32 new_image_size,
  180. S32 new_body_size);
  181. void updateEntryTimeStamp(S32 idx, Entry& entry);
  182. U32 openAndReadEntries(std::vector<Entry>& entries);
  183. void writeEntriesAndClose(const std::vector<Entry>& entries);
  184. void readEntryFromHeaderImmediately(S32& idx, Entry& entry);
  185. S32 readEntryFromHeaderImmediatelyShared(S32& idx, Entry& entry);
  186. void writeEntryToHeaderImmediately(S32& idx, Entry& entry,
  187. bool write_header = false);
  188. void removeEntry(S32 idx, Entry& entry, std::string& filename,
  189. bool remove_file = true);
  190. void removeCachedTexture(const LLUUID& id);
  191. S32 getHeaderCacheEntry(const LLUUID& id, Entry& entry);
  192. S32 setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize,
  193. S32 datasize);
  194. void writeUpdatedEntries();
  195. void updatedHeaderEntriesFile();
  196. protected:
  197. typedef std::unique_ptr<LLThreadPool> thread_pool_ptr_t;
  198. thread_pool_ptr_t mThreadPoolp;
  199. LLMutex mLRUMutex;
  200. LLMutex mHeaderMutex;
  201. LLAtomicU32 mNumReads;
  202. LLAtomicU32 mNumWrites;
  203. LLFile* mHeaderFile;
  204. typedef fast_hmap<LLUUID, std::string> purge_map_t;
  205. purge_map_t mFilesToDelete;
  206. LLTimer mSlicedPurgeTimer;
  207. // Headers (each header entry includes the first mip)
  208. std::string mHeaderEntriesFileName;
  209. std::string mHeaderDataFileName;
  210. EntriesInfo mHeaderEntriesInfo;
  211. // Indexes of the deleted entries; keep it as an ordered set so that the
  212. // list is auto-sorted ! HB
  213. std::set<S32> mFreeList;
  214. uuid_list_t mLRU;
  215. typedef fast_hmap<LLUUID, S32> id_map_t;
  216. id_map_t mHeaderIDMap;
  217. // Bodies (textures minus headers)
  218. std::string mTexturesDirName;
  219. typedef fast_hmap<LLUUID, S32> size_map_t;
  220. size_map_t mTexturesSizeMap;
  221. S64 mTexturesSizeTotal;
  222. LLAtomicBool mDoPurge;
  223. // Keep this as an ordered map ! HB
  224. typedef std::map<S32, Entry> idx_entry_map_t;
  225. idx_entry_map_t mUpdatedEntryMap;
  226. bool mReadOnly;
  227. static LLAtomicU32 sTotalHits;
  228. static LLAtomicU32 sTotalMisses;
  229. static LLAtomicU32 sTotalWrites;
  230. static LLAtomicU32 sTotalErrors;
  231. static U32 sCacheMaxEntries;
  232. static S64 sCacheMaxTexturesSize;
  233. };
  234. // Note: there is no good to define 1024 for TEXTURE_CACHE_ENTRY_SIZE while
  235. // FIRST_PACKET_SIZE is 600 on sim side.
  236. constexpr S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;
  237. // Global, initialized in llappviewer.cpp and used in newview/. Moved here so
  238. // that LLTextureCache consumers do not need to include llappviewer.h to use
  239. // it. HB
  240. extern LLTextureCache* gTextureCachep;
  241. #endif // LL_LLTEXTURECACHE_H