llvocache.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /**
  2. * @file llvocache.h
  3. * @brief Cache of objects on the viewer.
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewergpl$
  6. *
  7. * Copyright (c) 2003-2016 (original implementation), Linden Research, Inc.
  8. * Copyright (c) 2022 (PBR extra data implementation), Linden Research, Inc.
  9. * Copyright (c) 2016-2023, Henri Beauchamp (debugging, cache parameters
  10. * biasing based on memory usage, removal of APR dependency, threading).
  11. *
  12. * Second Life Viewer Source Code
  13. * The source code in this file ("Source Code") is provided by Linden Lab
  14. * to you under the terms of the GNU General Public License, version 2.0
  15. * ("GPL"), unless you have obtained a separate licensing agreement
  16. * ("Other License"), formally executed by you and Linden Lab. Terms of
  17. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  18. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  19. *
  20. * There are special exceptions to the terms and conditions of the GPL as
  21. * it is applied to this Source Code. View the full text of the exception
  22. * in the file doc/FLOSS-exception.txt in this software distribution, or
  23. * online at
  24. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  25. *
  26. * By copying, modifying or distributing this software, you acknowledge
  27. * that you have read and understood your obligations described above,
  28. * and agree to abide by those obligations.
  29. *
  30. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  31. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  32. * COMPLETENESS OR PERFORMANCE.
  33. * $/LicenseInfo$
  34. */
  35. #ifndef LL_LLVOCACHE_H
  36. #define LL_LLVOCACHE_H
  37. #include <set>
  38. #include <string>
  39. #include "lldatapacker.h"
  40. #include "lldir.h"
  41. #include "hbfastmap.h"
  42. #include "llfile.h"
  43. #include "llgltfmaterial.h"
  44. #include "llpointer.h"
  45. #include "llsingleton.h"
  46. #include "llthreadpool.h"
  47. #include "lluuid.h"
  48. #include "llvieweroctree.h"
  49. #define HB_AJUSTED_VOCACHE_PARAMETERS 1
  50. class LLCamera;
  51. //---------------------------------------------------------------------------
  52. // Cache entries
  53. class LLGLTFOverrideCacheEntry
  54. {
  55. protected:
  56. LOG_CLASS(LLGLTFOverrideCacheEntry);
  57. public:
  58. LL_INLINE LLGLTFOverrideCacheEntry()
  59. : mRegionHandle(0),
  60. mLocalId(0)
  61. {
  62. }
  63. bool fromLLSD(const LLSD& data);
  64. LLSD toLLSD() const;
  65. public:
  66. // LLSD per side
  67. typedef fast_hmap<S32, LLSD> data_map_t;
  68. data_map_t mSides;
  69. // GLTF material per side
  70. typedef fast_hmap<S32, LLPointer<LLGLTFMaterial> > mat_map_t;
  71. mat_map_t mGLTFMaterial;
  72. U64 mRegionHandle;
  73. U32 mLocalId;
  74. };
  75. class alignas(16) LLVOCacheEntry : public LLViewerOctreeEntryData
  76. {
  77. protected:
  78. LOG_CLASS(LLVOCacheEntry);
  79. ~LLVOCacheEntry();
  80. public:
  81. LL_VOLUME_AREANA_NEW_DELETE
  82. enum
  83. {
  84. // Low 16-bit state
  85. INACTIVE = 0x00000000, // Not visible
  86. IN_QUEUE = 0x00000001, // In visible queue, object to be created
  87. WAITING = 0x00000002, // Object creation request sent
  88. ACTIVE = 0x00000004, // Object created and in rendering pipeline
  89. // High 16-bit state
  90. IN_VO_TREE = 0x00010000, // Entry is in the object cache tree
  91. LOW_BITS = 0x0000ffff,
  92. HIGH_BITS = 0xffff0000
  93. };
  94. struct CompareVOCacheEntry
  95. {
  96. LL_INLINE bool operator()(const LLVOCacheEntry* const& lhs,
  97. const LLVOCacheEntry* const& rhs) const
  98. {
  99. F32 lpa = lhs->getSceneContribution();
  100. F32 rpa = rhs->getSceneContribution();
  101. // Larger pixel area first
  102. #if 1
  103. return lpa > rpa || (lpa == rpa && lhs < rhs);
  104. #else
  105. if (lpa > rpa)
  106. {
  107. return true;
  108. }
  109. else if (lpa < rpa)
  110. {
  111. return false;
  112. }
  113. else
  114. {
  115. return lhs < rhs;
  116. }
  117. #endif
  118. }
  119. };
  120. LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer& dp);
  121. LLVOCacheEntry(LLFile* infile);
  122. LLVOCacheEntry();
  123. void updateEntry(U32 crc, LLDataPackerBinaryBuffer& dp);
  124. void setState(U32 state);
  125. LL_INLINE void clearState(U32 state) { mState &= ~state; }
  126. LL_INLINE bool hasState(U32 state) { return (mState & state) != 0; }
  127. LL_INLINE bool isState(U32 state) { return (mState & LOW_BITS) == state; }
  128. LL_INLINE U32 getState() const { return mState & LOW_BITS; }
  129. bool isAnyVisible(const LLVector4a& camera_origin,
  130. const LLVector4a& local_camera_origin,
  131. F32 dist_threshold);
  132. LL_INLINE U32 getLocalID() const { return mLocalID; }
  133. LL_INLINE U32 getCRC() const { return mCRC; }
  134. LL_INLINE S32 getHitCount() const { return mHitCount; }
  135. LL_INLINE S32 getCRCChangeCount() const { return mCRCChangeCount; }
  136. void calcSceneContribution(const LLVector4a& camera_origin,
  137. bool needs_update, U32 last_update,
  138. F32 dist_threshold);
  139. LL_INLINE void setSceneContribution(F32 contrib) { mSceneContrib = contrib;}
  140. LL_INLINE F32 getSceneContribution() const { return mSceneContrib; }
  141. void dump() const;
  142. bool writeToFile(LLFile* outfile) const;
  143. LLDataPackerBinaryBuffer* getDP();
  144. void recordHit() { ++mHitCount; }
  145. LL_INLINE void recordDupe() { ++mDupeCount; }
  146. void setOctreeEntry(LLViewerOctreeEntry* entry) override;
  147. void setParentID(U32 id);
  148. LL_INLINE U32 getParentID() const { return mParentID; }
  149. LL_INLINE bool isChild() const { return mParentID > 0; }
  150. void addChild(LLVOCacheEntry* entry);
  151. void removeChild(LLVOCacheEntry* entry);
  152. void removeAllChildren();
  153. // Removes the first child and returns it.
  154. LLVOCacheEntry* getChild();
  155. LL_INLINE S32 getNumOfChildren() { return mChildrenList.size(); }
  156. // Called from processing object update message:
  157. void setBoundingInfo(const LLVector3& pos, const LLVector3& scale);
  158. void updateParentBoundingInfo();
  159. void saveBoundingSphere();
  160. LL_INLINE void setValid(bool valid = true) { mValid = valid; }
  161. LL_INLINE bool isValid() const { return mValid; }
  162. LL_INLINE void setUpdateFlags(U32 flags) { if (flags != 0xffffffff) mUpdateFlags = flags; }
  163. LL_INLINE U32 getUpdateFlags() const { return mUpdateFlags; }
  164. static void updateSettings();
  165. static F32 getSquaredPixelThreshold(bool is_front);
  166. typedef fast_hmap<U32, LLPointer<LLVOCacheEntry> > map_t;
  167. typedef std::set<LLVOCacheEntry*> set_t;
  168. typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> prio_list_t;
  169. typedef fast_hmap<U32, LLGLTFOverrideCacheEntry> emap_t;
  170. private:
  171. void updateParentBoundingInfo(const LLVOCacheEntry* child);
  172. protected:
  173. LLVector4a mBSphereCenter; // Bounding sphere center
  174. F32 mBSphereRadius; // Bounding sphere radius
  175. U32 mLocalID;
  176. U32 mParentID;
  177. U32 mCRC;
  178. U32 mUpdateFlags; // Received from sim
  179. S32 mHitCount;
  180. S32 mDupeCount;
  181. S32 mCRCChangeCount;
  182. U8* mBuffer;
  183. LLDataPackerBinaryBuffer mDP;
  184. // Projected scene contributuion of this object:
  185. F32 mSceneContrib;
  186. // High 16 bits reserved for special use:
  187. U32 mState;
  188. // Children entries in a linked set.
  189. set_t mChildrenList;
  190. // If set, this entry is valid, otherwise it is invalid:
  191. bool mValid;
  192. public:
  193. S32 mLastCameraUpdated;
  194. static U32 sMinFrameRange;
  195. static F32 sNearRadius;
  196. static F32 sRearFarRadius;
  197. static F32 sFrontPixelThreshold;
  198. static F32 sRearPixelThreshold;
  199. #if HB_AJUSTED_VOCACHE_PARAMETERS
  200. static bool sBiasedRetention;
  201. #endif
  202. };
  203. class LLVOCacheGroup : public LLOcclusionCullingGroup
  204. {
  205. protected:
  206. LOG_CLASS(LLVOCacheGroup);
  207. public:
  208. LLVOCacheGroup(OctreeNode* node, LLViewerOctreePartition* part)
  209. : LLOcclusionCullingGroup(node, part)
  210. {
  211. }
  212. // virtual
  213. void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
  214. protected:
  215. virtual ~LLVOCacheGroup();
  216. };
  217. class LLVOCachePartition : public LLViewerOctreePartition
  218. {
  219. protected:
  220. LOG_CLASS(LLVOCachePartition);
  221. public:
  222. LLVOCachePartition(LLViewerRegion* regionp);
  223. ~LLVOCachePartition() override;
  224. bool addEntry(LLViewerOctreeEntry* entry);
  225. void removeEntry(LLViewerOctreeEntry* entry);
  226. S32 cull(LLCamera& camera, bool do_occlusion = false) override;
  227. void addOccluders(LLViewerOctreeGroup* gp);
  228. void resetOccluders();
  229. void processOccluders(LLCamera* camera);
  230. void removeOccluder(LLVOCacheGroup* group);
  231. void setCullHistory(bool has_new_object);
  232. LL_INLINE bool isFrontCull() const { return mFrontCull; }
  233. private:
  234. // Selects objects behind camera.
  235. void selectBackObjects(LLCamera& camera, F32 projection_area_cutoff,
  236. bool use_occlusion);
  237. public:
  238. static bool sNeedsOcclusionCheck;
  239. private:
  240. U32 mCullHistory;
  241. U32 mCulledTime[LLViewerCamera::NUM_CAMERAS];
  242. S32 mBackSlectionEnabled; // enable to select back objects if > 0.
  243. U32 mIdleHash;
  244. // The view frustum cull if set, otherwise is back sphere cull:
  245. bool mFrontCull;
  246. std::set<LLVOCacheGroup*> mOccludedGroups;
  247. };
  248. // Note: LLVOCache is not thread-safe
  249. class LLVOCache : public LLSingleton<LLVOCache>
  250. {
  251. friend class LLSingleton<LLVOCache>;
  252. protected:
  253. LOG_CLASS(LLVOCache);
  254. private:
  255. struct HeaderEntryInfo
  256. {
  257. HeaderEntryInfo()
  258. : mIndex(0),
  259. mHandle(0),
  260. mTime(0)
  261. {
  262. }
  263. S32 mIndex;
  264. U64 mHandle;
  265. U32 mTime;
  266. };
  267. struct HeaderMetaInfo
  268. {
  269. HeaderMetaInfo()
  270. : mVersion(0),
  271. mAddressSize(0)
  272. {
  273. }
  274. U32 mVersion;
  275. U32 mAddressSize;
  276. };
  277. struct header_entry_less
  278. {
  279. LL_INLINE bool operator()(const HeaderEntryInfo* lhs,
  280. const HeaderEntryInfo* rhs) const
  281. {
  282. if (lhs->mTime == rhs->mTime)
  283. {
  284. return lhs < rhs;
  285. }
  286. // older entry in front of queue (set)
  287. return lhs->mTime < rhs->mTime;
  288. }
  289. };
  290. typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;
  291. typedef fast_hmap<U64, HeaderEntryInfo*> handle_entry_map_t;
  292. private:
  293. LLVOCache();
  294. public:
  295. ~LLVOCache();
  296. void initCache(ELLPath location, U32 size);
  297. void removeCache(ELLPath location);
  298. void readFromCache(U64 handle, const std::string& region_name,
  299. const LLUUID& id);
  300. // IMPORTANT: entry_map and extras_map may be wiped out by this method. HB
  301. void writeToCache(U64 handle, const std::string& region_name,
  302. const LLUUID& id, LLVOCacheEntry::map_t& entry_map,
  303. bool dirty_cache, LLVOCacheEntry::emap_t& extras_map,
  304. bool removal_enabled);
  305. void removeEntry(U64 handle);
  306. void setReadOnly(bool read_only) { mReadOnly = read_only; }
  307. bool isReadOnly() const { return mReadOnly; }
  308. bool isEnabled() const { return mEnabled; }
  309. private:
  310. class ReadWorker
  311. {
  312. protected:
  313. LOG_CLASS(LLVOCache::ReadWorker);
  314. public:
  315. ReadWorker(U64 handle, const LLUUID& id,
  316. const std::string& region_name);
  317. void readCacheFile();
  318. private:
  319. LLUUID mId;
  320. U64 mHandle;
  321. std::string mRegionName;
  322. };
  323. class WriteWorker
  324. {
  325. protected:
  326. LOG_CLASS(LLVOCache::WriteWorker);
  327. public:
  328. WriteWorker(U64 handle, const LLUUID& id,
  329. const std::string& region_name,
  330. LLVOCacheEntry::map_t& entry_map,
  331. LLVOCacheEntry::emap_t& extras_map,
  332. bool removal_enabled);
  333. void writeCacheFile();
  334. private:
  335. LLUUID mId;
  336. U64 mHandle;
  337. std::string mRegionName;
  338. LLVOCacheEntry::map_t mEntryMap;
  339. LLVOCacheEntry::emap_t mExtraMap;
  340. bool mRemovalEnabled;
  341. };
  342. void setDirNames(ELLPath location);
  343. // Determine the cache filename for the region from the region handle
  344. void getObjectCacheFilename(U64 handle, std::string& filename,
  345. bool extra_entries = false);
  346. void removeFromCache(HeaderEntryInfo* entry);
  347. void readCacheHeader();
  348. void writeCacheHeader();
  349. void clearCacheInMemory();
  350. void removeCache();
  351. void removeEntry(HeaderEntryInfo* entry);
  352. void purgeEntries(U32 size);
  353. bool updateEntry(const HeaderEntryInfo* entry);
  354. private:
  355. typedef std::unique_ptr<LLThreadPool> thread_pool_ptr_t;
  356. thread_pool_ptr_t mThreadPoolp;
  357. LLMutex mMutex;
  358. HeaderMetaInfo mMetaInfo;
  359. U32 mCacheSize;
  360. U32 mNumEntries;
  361. std::string mHeaderFileName;
  362. std::string mObjectCacheDirName;
  363. header_entry_queue_t mHeaderEntryQueue;
  364. handle_entry_map_t mHandleEntryMap;
  365. bool mEnabled;
  366. bool mInitialized;
  367. bool mReadOnly;
  368. };
  369. #endif