llmeshrepository.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. /**
  2. * @file llmeshrepository.h
  3. * @brief Client-side repository of mesh assets.
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewergpl$
  6. *
  7. * Copyright (c) 2010, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_MESH_REPOSITORY_H
  33. #define LL_MESH_REPOSITORY_H
  34. #include <deque>
  35. #include <map>
  36. #include <queue>
  37. #include "boost/unordered_set.hpp"
  38. #define LLCONVEXDECOMPINTER_STATIC 1
  39. #include "llconvexdecomposition.h"
  40. #include "llassettype.h"
  41. #include "llatomic.h"
  42. #include "llcorehttpcommon.h"
  43. #include "llcorehttphandler.h"
  44. #include "llcorehttpheaders.h"
  45. #include "llcorehttpoptions.h"
  46. #include "llcorehttprequest.h"
  47. #include "hbfastmap.h"
  48. #include "hbfastset.h"
  49. #include "llhandle.h"
  50. #include "llmodel.h"
  51. #include "llmutex.h"
  52. #include "llthread.h"
  53. #include "lluuid.h"
  54. #include "llappviewer.h" // gFrameTimeSeconds
  55. #include "llviewertexture.h"
  56. #include "llvolume.h"
  57. // Set to 1 to re-enable LL's pending requests sorting code (*), which only
  58. // slows down mesh loading !
  59. // (*) That code relies on drawable radius, which is often unknown or wrong
  60. // with not yet fully loaded meshes anyway... HB
  61. #define LL_PENDING_MESH_REQUEST_SORTING 0
  62. class LLMeshRepository;
  63. class LLVOVolume;
  64. class LLMeshHeader
  65. {
  66. public:
  67. LLMeshHeader() noexcept;
  68. LLMeshHeader(LLMeshHeader&&) noexcept = default;
  69. void init(const LLSD& header, U32 size);
  70. void reset();
  71. public:
  72. U32 mHeaderSize;
  73. U32 mLodOffset[4];
  74. U32 mLodSize[4];
  75. U32 mSkinOffset;
  76. U32 mSkinSize;
  77. U32 mPhysicsConvexOffset;
  78. U32 mPhysicsConvexSize;
  79. U32 mPhysicsMeshOffset;
  80. U32 mPhysicsMeshSize;
  81. bool mValid;
  82. };
  83. class LLMeshCostData final : public LLRefCount
  84. {
  85. public:
  86. LLMeshCostData() noexcept;
  87. LLMeshCostData(LLMeshCostData&&) noexcept = default;
  88. bool init(LLMeshHeader* header);
  89. bool init(const LLSD& header);
  90. bool init(S32 bytes_lowest, S32 bytes_low, S32 bytes_med, S32 bytes_high);
  91. // Size for given LOD
  92. LL_INLINE S32 getSizeByLOD(S32 lod)
  93. {
  94. return lod >= 0 && lod <= 3 ? mSizeByLOD[lod] : 0;
  95. }
  96. // Sum of all LOD sizes.
  97. LL_INLINE S32 getSizeTotal() { return mSizeTotal; }
  98. // Estimated triangle counts for the given LOD.
  99. LL_INLINE F32 getEstTrisByLOD(S32 lod)
  100. {
  101. return lod >= 0 && lod <= 3 ? mEstTrisByLOD[lod] : 0.f;
  102. }
  103. // Estimated triangle counts for the largest LOD. Typically this is also
  104. // the "high" LOD, but not necessarily.
  105. LL_INLINE F32 getEstTrisMax() { return mEstTrisMax; }
  106. // Triangle count as computed by original streaming cost formula. Triangles
  107. // in each LOD are weighted based on how frequently they will be seen.
  108. // This was called "unscaled_value" in the original getStreamingCost()
  109. // functions.
  110. F32 getRadiusWeightedTris(F32 radius);
  111. // Triangle count used by triangle-based cost formula. Based on triangles
  112. // in highest LOD plus potentially partial charges for lower LODs depending
  113. // on complexity.
  114. F32 getEstTrisForStreamingCost();
  115. // Streaming cost. This should match the server-side calculation for the
  116. // corresponding volume.
  117. F32 getRadiusBasedStreamingCost(F32 radius);
  118. // New streaming cost formula, currently only used for animated objects.
  119. F32 getTriangleBasedStreamingCost();
  120. private:
  121. // Note: the first member variable is 32 bits in order to align on 64 bits
  122. // for the next variables, counting the 32 bits counter from LLRefCount. HB
  123. // Sum of all LOD sizes.
  124. S32 mSizeTotal;
  125. // Estimated triangle counts for the largest LOD. Typically this is also
  126. // the "high" LOD, but not necessarily.
  127. F32 mEstTrisMax;
  128. F32 mChargedTris;
  129. // From the "size" field of the mesh header. LOD 0=lowest, 3=highest.
  130. std::vector<S32> mSizeByLOD;
  131. // Estimated triangle counts derived from the LOD sizes. LOD 0=lowest,
  132. // 3=highest.
  133. std::vector<F32> mEstTrisByLOD;
  134. };
  135. class LLRequestStats
  136. {
  137. public:
  138. LL_INLINE LLRequestStats() noexcept
  139. : mRetries(0),
  140. mNextRetryTime(0.f)
  141. {
  142. }
  143. LL_INLINE U32 getRetries()
  144. {
  145. return mRetries;
  146. }
  147. LL_INLINE void updateTime()
  148. {
  149. constexpr F32 DOWNLOAD_RETRY_DELAY = 0.5f; // seconds
  150. mNextRetryTime = gFrameTimeSeconds +
  151. DOWNLOAD_RETRY_DELAY * (F32)(1 << mRetries++);
  152. }
  153. LL_INLINE bool canRetry() const
  154. {
  155. constexpr U32 DOWNLOAD_RETRY_LIMIT = 8;
  156. return mRetries < DOWNLOAD_RETRY_LIMIT;
  157. }
  158. LL_INLINE bool isDelayed() const
  159. {
  160. return gFrameTimeSeconds < mNextRetryTime;
  161. }
  162. private:
  163. U32 mRetries;
  164. F32 mNextRetryTime;
  165. };
  166. class LLPhysicsDecomp : public LLThread
  167. {
  168. protected:
  169. LOG_CLASS(LLPhysicsDecomp);
  170. public:
  171. LLPhysicsDecomp();
  172. ~LLPhysicsDecomp() override;
  173. void shutdown() override;
  174. void run() override;
  175. void setMeshData(LLCDMeshData& mesh, bool vertex_based);
  176. void doDecomposition();
  177. void doDecompositionSingleHull();
  178. void notifyCompleted();
  179. void cancel();
  180. typedef std::map<std::string, LLSD> decomp_params_t;
  181. class Request : public LLRefCount
  182. {
  183. public:
  184. // Status message callback, called from decomposition thread
  185. virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0;
  186. // Completed callback, called from the main thread
  187. virtual void completed() = 0;
  188. virtual void setStatusMessage(const std::string& msg);
  189. LL_INLINE bool isValid() const
  190. {
  191. return mPositions.size() > 2 && mIndices.size() > 2;
  192. }
  193. protected:
  194. void assignData(LLModel* mdl);
  195. void updateTriangleAreaThreshold();
  196. bool isValidTriangle(U16 idx1, U16 idx2, U16 idx3);
  197. protected:
  198. // Note: the first member variable is 32 bits in order to align on 64
  199. // bits for the next variable, counting the 32 bits counter from
  200. // LLRefCount. HB
  201. F32 mTriangleAreaThreshold;
  202. LLVector3 mBBox[2];
  203. public:
  204. // Input params
  205. S32* mDecompID;
  206. std::string mStage;
  207. std::vector<U16> mIndices;
  208. std::vector<LLVector3> mPositions;
  209. decomp_params_t mParams;
  210. // Output state
  211. std::string mStatusMessage;
  212. std::vector<LLModel::PhysicsMesh> mHullMesh;
  213. LLModel::hull_decomp mHull;
  214. };
  215. void submitRequest(Request* request);
  216. static S32 llcdCallback(const char*, S32, S32);
  217. public:
  218. LLCondition mSignal;
  219. LLMutex mMutex;
  220. std::map<std::string, S32> mStageID;
  221. typedef std::queue<LLPointer<Request> > request_queue_t;
  222. request_queue_t mRequestQ;
  223. LLPointer<Request> mCurRequest;
  224. std::queue<LLPointer<Request> > mCompletedQ;
  225. bool mInited;
  226. bool mQuitting;
  227. bool mDone;
  228. };
  229. class LLMeshRepoThread final : public LLThread
  230. {
  231. protected:
  232. LOG_CLASS(LLMeshRepoThread);
  233. public:
  234. LLMeshRepoThread();
  235. ~LLMeshRepoThread() override;
  236. void run() override;
  237. void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
  238. void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
  239. bool fetchMeshHeader(const LLVolumeParams& mesh_params,
  240. bool can_retry = true);
  241. bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
  242. bool can_retry = true);
  243. bool headerReceived(const LLVolumeParams& mesh_params, U8* data,
  244. S32 data_size);
  245. bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data,
  246. S32 data_size);
  247. bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
  248. bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
  249. bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
  250. LLMeshHeader* getMeshHeader(const LLUUID& mesh_id);
  251. void notifyLoadedMeshes();
  252. S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
  253. void loadMeshSkinInfo(const LLUUID& mesh_id);
  254. void loadMeshDecomposition(const LLUUID& mesh_id);
  255. void loadMeshPhysicsShape(const LLUUID& mesh_id);
  256. // Sends the request for skin info, returns true if header info exists
  257. // (should hold onto mesh_id and try again later if header info does not
  258. // exist)
  259. bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry);
  260. // Sends the request for decomposition, returns true if header info exists
  261. // (should hold onto mesh_id and try again later if header info does not
  262. // exist)
  263. bool fetchMeshDecomposition(const LLUUID& mesh_id);
  264. // Sends the request for PhysicsShape, returns true if header info exists
  265. // (should hold onto mesh_id and try again later if header info does not
  266. // exist).
  267. bool fetchMeshPhysicsShape(const LLUUID& mesh_id);
  268. // Mutex: acquires mMutex
  269. std::string constructUrl(const LLUUID& mesh_id, U32* version);
  270. class HeaderRequest final : public LLRequestStats
  271. {
  272. public:
  273. LL_INLINE HeaderRequest(const LLVolumeParams& mesh_params) noexcept
  274. : LLRequestStats(),
  275. mMeshParams(mesh_params)
  276. {
  277. }
  278. LL_INLINE bool operator<(const HeaderRequest& rhs) const
  279. {
  280. return mMeshParams < rhs.mMeshParams;
  281. }
  282. public:
  283. LLVolumeParams mMeshParams;
  284. };
  285. class LODRequest final : public LLRequestStats
  286. {
  287. public:
  288. LL_INLINE LODRequest(const LLVolumeParams& params, S32 lod) noexcept
  289. : LLRequestStats(),
  290. #if LL_PENDING_MESH_REQUEST_SORTING
  291. mScore(0.f),
  292. #endif
  293. mMeshParams(params),
  294. mLOD(lod)
  295. {
  296. }
  297. public:
  298. LLVolumeParams mMeshParams;
  299. S32 mLOD;
  300. #if LL_PENDING_MESH_REQUEST_SORTING
  301. F32 mScore;
  302. #endif
  303. };
  304. #if LL_PENDING_MESH_REQUEST_SORTING
  305. struct CompareScoreGreater
  306. {
  307. LL_INLINE bool operator()(const LODRequest& lhs, const LODRequest& rhs)
  308. {
  309. return lhs.mScore > rhs.mScore; // Greatest = first
  310. }
  311. };
  312. #endif
  313. class UUIDBasedRequest final : public LLRequestStats
  314. {
  315. public:
  316. LL_INLINE UUIDBasedRequest(const LLUUID& id) noexcept
  317. : LLRequestStats(),
  318. mId(id)
  319. {
  320. }
  321. // Needed by boost::unordered_set and boost::unordered_map
  322. LL_INLINE bool operator==(const UUIDBasedRequest& rhs) const
  323. {
  324. return mId == rhs.mId;
  325. }
  326. public:
  327. LLUUID mId;
  328. };
  329. private:
  330. typedef fast_hset<UUIDBasedRequest> base_requests_set_t;
  331. // This method adds 'remaining' and 'incomplete' requests back into the
  332. // mMutex-protected 'dest' requests set. Both 'remaining' and 'incomplete'
  333. // are empty on method exit.
  334. void insertRequests(base_requests_set_t& dest,
  335. base_requests_set_t& remaining,
  336. base_requests_set_t& incomplete);
  337. // Issue a GET request to a URL with 'Range' header using the correct
  338. // policy class and other attributes. If an invalid handle is returned,
  339. // the request failed and caller must retry or dispose of handler.
  340. //
  341. // Threads: Repo thread only
  342. LLCore::HttpHandle getByteRange(const std::string& url, U32 cap_version,
  343. size_t offset, size_t len,
  344. const LLCore::HttpHandler::ptr_t& handler);
  345. struct LoadedMesh
  346. {
  347. LoadedMesh(LLVolume* volume, const LLVolumeParams& mesh_params,
  348. S32 lod)
  349. : mVolume(volume),
  350. mMeshParams(mesh_params),
  351. mLOD(lod)
  352. {
  353. }
  354. LLPointer<LLVolume> mVolume;
  355. S32 mLOD;
  356. LLVolumeParams mMeshParams;
  357. };
  358. public:
  359. LLMutex mMutex;
  360. LLMutex mHeaderMutex;
  361. LLCondition mSignal;
  362. std::string mGetMeshCapability;
  363. U32 mGetMeshVersion;
  364. // Map of known mesh headers
  365. typedef flat_hmap<LLUUID, LLMeshHeader*> mesh_header_map_t;
  366. mesh_header_map_t mMeshHeaders;
  367. // Queue of requested headers
  368. typedef std::deque<HeaderRequest> header_req_queue_t;
  369. header_req_queue_t mHeaderReqQ;
  370. // Queue of requested LODs
  371. typedef std::deque<LODRequest> lod_req_queue_t;
  372. lod_req_queue_t mLODReqQ;
  373. // List of unavailable LODs (either asset does not exist or asset does not
  374. // have desired LOD)
  375. typedef std::list<LODRequest> lod_req_list_t;
  376. lod_req_list_t mUnavailableLODs;
  377. // List of unavailable skin infos.
  378. uuid_vec_t mUnavailableSkins;
  379. // List of successfully loaded meshes
  380. typedef std::list<LoadedMesh> loaded_mesh_list_t;
  381. loaded_mesh_list_t mLoadedMeshes;
  382. // Set of requested skin info
  383. base_requests_set_t mSkinRequests;
  384. // List of completed skin info requests
  385. typedef std::list<LLMeshSkinInfo*> skin_info_list_t;
  386. skin_info_list_t mSkinInfos;
  387. // Set of requested decompositions
  388. base_requests_set_t mDecompositionRequests;
  389. // Set of requested physics shapes
  390. base_requests_set_t mPhysicsShapeRequests;
  391. // List of completed decomposition info requests
  392. typedef std::list<LLModel::Decomposition*> decomp_list_t;
  393. decomp_list_t mDecompositions;
  394. // CoreHttp interface objects.
  395. LLCore::HttpStatus mHttpStatus;
  396. LLCore::HttpRequest* mHttpRequest;
  397. LLCore::HttpOptions::ptr_t mHttpOptions;
  398. LLCore::HttpOptions::ptr_t mHttpLargeOptions;
  399. LLCore::HttpHeaders::ptr_t mHttpHeaders;
  400. LLCore::HttpRequest::policy_t mHttpPolicyClass;
  401. LLCore::HttpRequest::policy_t mHttpLegacyPolicyClass;
  402. LLCore::HttpRequest::policy_t mHttpLargePolicyClass;
  403. // Outstanding HTTP requests
  404. typedef fast_hset<LLCore::HttpHandler::ptr_t> http_request_t;
  405. http_request_t mHttpRequestSet;
  406. // Map of pending header requests and currently desired LODs
  407. typedef fast_hmap<LLUUID, std::vector<S32> > pending_lod_map_t;
  408. pending_lod_map_t mPendingLOD;
  409. static LLAtomicS32 sActiveHeaderRequests;
  410. static LLAtomicS32 sActiveLODRequests;
  411. static U32 sMaxConcurrentRequests;
  412. static S32 sRequestLowWater;
  413. static S32 sRequestHighWater;
  414. // Stats-use only, may read outside of thread
  415. static S32 sRequestWaterLevel;
  416. };
  417. //
  418. // Observers for model uploads
  419. //
  420. class LLWholeModelFeeObserver
  421. {
  422. protected:
  423. LOG_CLASS(LLWholeModelFeeObserver);
  424. public:
  425. LLWholeModelFeeObserver()
  426. {
  427. mWholeModelFeeObserverHandle.bind(this);
  428. }
  429. virtual ~LLWholeModelFeeObserver() = default;
  430. virtual void onModelPhysicsFeeReceived(const LLSD& result,
  431. std::string upload_url) = 0;
  432. virtual void setModelPhysicsFeeErrorStatus(S32 status,
  433. const std::string& reason,
  434. const LLSD& result) = 0;
  435. LL_INLINE LLHandle<LLWholeModelFeeObserver> getWholeModelFeeObserverHandle() const
  436. {
  437. return mWholeModelFeeObserverHandle;
  438. }
  439. protected:
  440. LLRootHandle<LLWholeModelFeeObserver> mWholeModelFeeObserverHandle;
  441. };
  442. class LLWholeModelUploadObserver
  443. {
  444. protected:
  445. LOG_CLASS(LLWholeModelUploadObserver);
  446. public:
  447. LLWholeModelUploadObserver()
  448. {
  449. mWholeModelUploadObserverHandle.bind(this);
  450. }
  451. virtual ~LLWholeModelUploadObserver() = default;
  452. virtual void onModelUploadSuccess() = 0;
  453. virtual void onModelUploadFailure() = 0;
  454. LL_INLINE LLHandle<LLWholeModelUploadObserver> getWholeModelUploadObserverHandle() const
  455. {
  456. return mWholeModelUploadObserverHandle;
  457. }
  458. protected:
  459. LLRootHandle<LLWholeModelUploadObserver> mWholeModelUploadObserverHandle;
  460. };
  461. // Class whose instances represent a single upload-type request for meshes: one
  462. // fee query or one actual upload attempt. Yes, it creates a unique thread for
  463. // that single request. As it is 1:1, it can also trivially serve as the
  464. // HttpHandler object for request completion notifications.
  465. class LLMeshUploadThread final : public LLThread, public LLCore::HttpHandler
  466. {
  467. protected:
  468. LOG_CLASS(LLMeshUploadThread);
  469. public:
  470. typedef std::vector<LLModelInstance> instance_list_t;
  471. LLMeshUploadThread(instance_list_t& data, LLVector3& scale,
  472. bool upload_textures, bool upload_skin,
  473. bool upload_joints, bool lock_scale_if_joint_position,
  474. const std::string& upload_url, bool do_upload = true,
  475. LLHandle<LLWholeModelFeeObserver> fee_observer =
  476. (LLHandle<LLWholeModelFeeObserver>()),
  477. LLHandle<LLWholeModelUploadObserver> upload_observer =
  478. (LLHandle<LLWholeModelUploadObserver>()));
  479. ~LLMeshUploadThread() override;
  480. LL_INLINE bool finished() const { return mFinished; }
  481. void run() override;
  482. void preStart();
  483. void discard();
  484. bool isDiscarded();
  485. void generateHulls();
  486. void doWholeModelUpload();
  487. void requestWholeModelFee();
  488. void wholeModelToLLSD(LLSD& dest, bool include_textures);
  489. void decomposeMeshMatrix(LLMatrix4& transformation,
  490. LLVector3& result_pos,
  491. LLQuaternion& result_rot,
  492. LLVector3& result_scale);
  493. LL_INLINE void setFeeObserverHandle(LLHandle<LLWholeModelFeeObserver> obs)
  494. {
  495. mFeeObserverHandle = obs;
  496. }
  497. LL_INLINE void setUploadObserverHandle(LLHandle<LLWholeModelUploadObserver> obs)
  498. {
  499. mUploadObserverHandle = obs;
  500. }
  501. // Inherited from LLCore::HttpHandler
  502. void onCompleted(LLCore::HttpHandle handle,
  503. LLCore::HttpResponse* response) override;
  504. LLViewerFetchedTexture* findViewerTexture(const LLImportMaterial& mat);
  505. class DecompRequest final : public LLPhysicsDecomp::Request
  506. {
  507. public:
  508. DecompRequest(LLModel* mdl, LLModel* base_model,
  509. LLMeshUploadThread* thread);
  510. LL_INLINE S32 statusCallback(const char*, S32, S32) override
  511. {
  512. return 1;
  513. }
  514. void completed() override;
  515. public:
  516. LLPointer<LLModel> mModel;
  517. LLPointer<LLModel> mBaseModel;
  518. LLMeshUploadThread* mThread;
  519. };
  520. public:
  521. LLPointer<DecompRequest> mFinalDecomp;
  522. volatile bool mPhysicsComplete;
  523. typedef std::map<LLPointer<LLModel>, std::vector<LLVector3> > hull_map_t;
  524. hull_map_t mHullMap;
  525. instance_list_t mInstanceList;
  526. typedef std::map<LLPointer<LLModel>, instance_list_t> instance_map_t;
  527. instance_map_t mInstance;
  528. LLMutex mMutex;
  529. S32 mPendingUploads;
  530. LLVector3 mOrigin;
  531. bool mFinished;
  532. bool mUploadTextures;
  533. bool mUploadSkin;
  534. bool mUploadJoints;
  535. bool mLockScaleIfJointPosition;
  536. volatile bool mDiscarded;
  537. LLHost mHost;
  538. std::string mWholeModelUploadURL;
  539. private:
  540. // Maximum time in seconds to execute an uploading request.
  541. S32 mMeshUploadTimeOut;
  542. LLHandle<LLWholeModelFeeObserver> mFeeObserverHandle;
  543. LLHandle<LLWholeModelUploadObserver> mUploadObserverHandle;
  544. // CoreHttp library interface objects.
  545. LLCore::HttpStatus mHttpStatus;
  546. LLCore::HttpRequest* mHttpRequest;
  547. LLCore::HttpOptions::ptr_t mHttpOptions;
  548. LLCore::HttpHeaders::ptr_t mHttpHeaders;
  549. LLCore::HttpRequest::policy_t mHttpPolicyClass;
  550. LLSD mModelData;
  551. // If false only model data will be requested, otherwise the model will be
  552. // uploaded
  553. bool mDoUpload;
  554. };
  555. class LLMeshRepository
  556. {
  557. protected:
  558. LOG_CLASS(LLMeshRepository);
  559. public:
  560. LLMeshRepository();
  561. void init();
  562. void shutdown();
  563. S32 update();
  564. LLMeshCostData* getCostData(const LLUUID& mesh_id);
  565. // Estimated triangle count of the largest LOD
  566. F32 getEstTrianglesMax(const LLUUID& mesh_id);
  567. F32 getEstTrianglesStreamingCost(const LLUUID& mesh_id);
  568. // This must be called on destruction by any LLVOVolume that was flagged
  569. // as referenced by the mesh repository.
  570. void unregisterVolume(LLVOVolume* volp, bool has_mesh, bool has_skin);
  571. // Mesh management functions
  572. S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params,
  573. S32 detail = 0, S32 last_lod = -1);
  574. void notifyLoadedMeshes();
  575. void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume);
  576. void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod);
  577. void notifySkinInfoReceived(LLMeshSkinInfo* info);
  578. void notifySkinInfoUnavailable(const LLUUID& info);
  579. void notifyDecompositionReceived(LLModel::Decomposition* info);
  580. S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
  581. static S32 getActualMeshLOD(LLMeshHeader* header, S32 lod);
  582. const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id,
  583. LLVOVolume* req_obj);
  584. LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
  585. void fetchPhysicsShape(const LLUUID& mesh_id);
  586. bool hasPhysicsShape(const LLUUID& mesh_id);
  587. void buildHull(const LLVolumeParams& params, S32 detail);
  588. void buildPhysicsMesh(LLModel::Decomposition& decomp);
  589. bool meshUploadEnabled();
  590. bool meshRezEnabled();
  591. void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale,
  592. bool upload_textures, bool upload_skin,
  593. bool upload_joints, bool lock_scale_if_joint_position,
  594. std::string upload_url, bool do_upload = true,
  595. LLHandle<LLWholeModelFeeObserver> fee_observer =
  596. (LLHandle<LLWholeModelFeeObserver>()),
  597. LLHandle<LLWholeModelUploadObserver> upload_observer =
  598. (LLHandle<LLWholeModelUploadObserver>()));
  599. S32 getMeshSize(const LLUUID& mesh_id, S32 lod);
  600. struct InventoryData
  601. {
  602. InventoryData(const LLSD& data, const LLSD& content)
  603. : mPostData(data),
  604. mResponse(content)
  605. {
  606. }
  607. LLSD mPostData;
  608. LLSD mResponse;
  609. };
  610. void uploadError(const LLSD& args);
  611. void updateInventory(InventoryData data);
  612. #if !LL_PENDING_MESH_REQUEST_SORTING
  613. // Called (from llagent.cpp) during a teleport into another region, to push
  614. // pending requests into a delayed queue so to give priority to the arrival
  615. // sim mesh objects rezzing over the departure ones.
  616. void delayCurrentRequests();
  617. #endif
  618. public:
  619. LLMeshRepoThread* mThread;
  620. LLPhysicsDecomp* mDecompThread;
  621. std::vector<LLMeshUploadThread*> mUploads;
  622. std::vector<LLMeshUploadThread*> mUploadWaitList;
  623. LLMutex mMeshMutex;
  624. typedef fast_hmap<LLUUID, fast_hset<LLVOVolume*> > mesh_load_map_t;
  625. mesh_load_map_t mLoadingMeshes[4];
  626. typedef flat_hmap<LLUUID, LLPointer<LLMeshSkinInfo> > skin_map_t;
  627. skin_map_t mSkinMap;
  628. typedef flat_hmap<LLUUID, LLModel::Decomposition*> decomp_map_t;
  629. decomp_map_t mDecompositionMap;
  630. #if LL_PENDING_MESH_REQUEST_SORTING
  631. std::vector<LLMeshRepoThread::LODRequest> mPendingRequests;
  632. #else
  633. LLMeshRepoThread::lod_req_queue_t mPendingRequests;
  634. LLMeshRepoThread::lod_req_queue_t mDelayedPendingRequests;
  635. #endif
  636. // List of mesh ids awaiting skin info
  637. typedef fast_hmap<LLUUID, fast_hset<LLVOVolume*> > skin_load_map_t;
  638. skin_load_map_t mLoadingSkins;
  639. // List of mesh ids that need to send skin info fetch requests
  640. std::queue<LLUUID> mPendingSkinRequests;
  641. // List of mesh ids awaiting decompositions
  642. uuid_list_t mLoadingDecompositions;
  643. // List of mesh ids that need to send decomposition fetch requests
  644. std::queue<LLUUID> mPendingDecompositionRequests;
  645. // List of mesh ids awaiting physics shapes
  646. uuid_list_t mLoadingPhysicsShapes;
  647. // List of mesh ids that need to send physics shape fetch requests
  648. std::queue<LLUUID> mPendingPhysicsShapeRequests;
  649. std::queue<InventoryData> mInventoryQ;
  650. std::queue<LLSD> mUploadErrorQ;
  651. // Costs data cache; must only be modified while mHeaderMutex is locked
  652. typedef flat_hmap<LLUUID, LLPointer<LLMeshCostData> > mesh_costs_map_t;
  653. mesh_costs_map_t mCostsMap;
  654. // Metrics
  655. static LLAtomicU32 sLODPending;
  656. static LLAtomicU32 sLODProcessing;
  657. static U32 sBytesReceived;
  658. // Total request count, http or cached, all component types:
  659. static U32 sMeshRequestCount;
  660. // HTTP GETs issued (not large)
  661. static U32 sHTTPRequestCount;
  662. // HTTP GETs issued for large requests
  663. static U32 sHTTPLargeRequestCount;
  664. // Total request retries whether successful or failed
  665. static U32 sHTTPRetryCount;
  666. // Requests that ended in error
  667. static U32 sHTTPErrorCount;
  668. static U32 sCacheBytesRead;
  669. static U32 sCacheBytesWritten;
  670. static U32 sCacheReads;
  671. static U32 sCacheWrites;
  672. // Maximum sequential locking failures
  673. static U32 sMaxLockHoldoffs;
  674. };
  675. extern LLMeshRepository gMeshRepo;
  676. // For use with boost::unordered_map and boost::unordered_set
  677. LL_INLINE size_t hash_value(const LLMeshRepoThread::UUIDBasedRequest& rhs) noexcept
  678. {
  679. return *((size_t*)rhs.mId.mData);
  680. }
  681. // std::hash implementation for LLMeshRepoThread::UUIDBasedRequest
  682. namespace std
  683. {
  684. template<> struct hash<LLMeshRepoThread::UUIDBasedRequest>
  685. {
  686. LL_INLINE size_t operator()(const LLMeshRepoThread::UUIDBasedRequest& rhs) const noexcept
  687. {
  688. return *((size_t*)rhs.mId.mData);
  689. }
  690. };
  691. }
  692. // Also used by llfloatermodelpreview.cpp
  693. extern void dump_llsd_to_file(const LLSD& data, const std::string& filename);
  694. constexpr F32 ANIMATED_OBJECT_BASE_COST = 15.f;
  695. constexpr F32 ANIMATED_OBJECT_COST_PER_KTRI = 1.5f;
  696. #endif