llimagegl.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /**
  2. * @file llimagegl.h
  3. * @brief Object for managing images and their textures
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-2009, 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_LLIMAGEGL_H
  33. #define LL_LLIMAGEGL_H
  34. #include <vector>
  35. #include "llatomic.h"
  36. #include "llimage.h" // LL_IMAGE_AREANA_NEW_DELETE
  37. #include "llmutex.h"
  38. #include "llrefcount.h"
  39. #include "llrender.h"
  40. #include "llthreadpool.h"
  41. class LLGLTexture;
  42. class LLImageGLThread;
  43. class LLWindow;
  44. // Note: LLImageGL must now derive from LLThreadSafeRefCount instead of
  45. // LLRefCount because ref() and unref() are used in GL threads. HB
  46. class LLImageGL : public LLThreadSafeRefCount
  47. {
  48. friend class LLTexUnit;
  49. protected:
  50. LOG_CLASS(LLImageGL);
  51. virtual ~LLImageGL();
  52. void analyzeAlpha(const void* data_in, U32 w, U32 h);
  53. void calcAlphaChannelOffsetAndStride();
  54. public:
  55. #if LL_JEMALLOC
  56. // Take benefit of jemalloc arenas for images, especially since they are
  57. // used in various threads. HB
  58. LL_IMAGE_AREANA_NEW_DELETE
  59. #endif
  60. LLImageGL(bool usemipmaps = true);
  61. LLImageGL(U32 width, U32 height, U8 components, bool usemipmaps = true);
  62. LLImageGL(const LLImageRaw* imagerawp, bool usemipmaps = true);
  63. // For wrapping textures created via GL elsewhere with our API only. Use
  64. // with caution.
  65. LLImageGL(U32 tex_name, U32 components, U32 target, S32 internal_fmt,
  66. S32 primary_fmt, S32 format_type,
  67. LLTexUnit::eTextureAddressMode mode);
  68. // To allow tracking owners, for periodic image list cleanup. HB
  69. LL_INLINE void setOwner(LLGLTexture* ownerp) { mOwnerp = ownerp; }
  70. LL_INLINE LLGLTexture* getOwner() const { return mOwnerp; }
  71. static void initThread(LLWindow* windowp, S32 threads);
  72. static void stopThread();
  73. // These 2 functions replace glGenTextures() and glDeleteTextures()
  74. static void generateTextures(U32 num_textures, U32* textures);
  75. static void deleteTextures(U32 num_textures, const U32* textures);
  76. // Size calculation
  77. static U32 dataFormatBits(S32 dataformat);
  78. static S64 dataFormatBytes(S32 dataformat, U32 width, U32 height);
  79. static U32 dataFormatComponents(S32 dataformat);
  80. // The two following methods need to be called every frame
  81. static void freeDeletedTextures(bool delete_all = false);
  82. static void updateStats(F32 current_time);
  83. // When enabled, this queues the textures for bundled deletion after 4
  84. // render frames have elapsed, the hypothesis being it would avoid
  85. // synchronization issues with some GPUs.
  86. static void setDelayedTextureDelete(bool b) { sDelayedTextureDelete = b; }
  87. bool updateBindStats() const;
  88. LL_INLINE void forceUpdateBindStats() const
  89. {
  90. mLastBindTime = sLastFrameTime;
  91. }
  92. LL_INLINE F32 getTimePassedSinceLastBound()
  93. {
  94. return sLastFrameTime - mLastBindTime;
  95. }
  96. // Save off / restore GL textures
  97. static void destroyGL(bool save_state = true);
  98. static void restoreGL();
  99. static void dirtyTexOptions();
  100. static bool checkSize(S32 width, S32 height);
  101. virtual void dump(); // debugging info to llinfos
  102. bool setSize(U32 width, U32 height, U8 ncomponents,
  103. S32 discard_level = -1);
  104. LL_INLINE void setComponents(U8 comps) { mComponents = comps; }
  105. LL_INLINE void setAllowCompression(bool allow) { mAllowCompression = allow; }
  106. static void setManualImage(U32 target, S32 miplevel, S32 intformat,
  107. U32 width, U32 height,
  108. U32 pixformat, U32 pixtype,
  109. const void* pixels,
  110. bool allow_compression = true);
  111. bool createGLTexture();
  112. bool createGLTexture(S32 discard_level, const LLImageRaw* imagerawp,
  113. S32 usename = 0, bool to_create = true,
  114. bool defer_copy = false, U32* tex_name = NULL);
  115. bool createGLTexture(S32 discard_level, const U8* data,
  116. bool data_hasmips = false, S32 usename = 0,
  117. bool defer_copy = false, U32* tex_name = NULL);
  118. void setImage(const LLImageRaw* imagerawpp);
  119. bool setImage(const U8* data_in, bool data_hasmips = false,
  120. S32 usename = 0);
  121. bool setSubImage(const LLImageRaw* imagerawpp, S32 x_pos, S32 y_pos,
  122. U32 width, U32 height, bool force_fast_update = false,
  123. U32 use_name = 0);
  124. bool setSubImage(const U8* datap, U32 data_width, U32 data_height,
  125. S32 x_pos, S32 y_pos, U32 width, U32 height,
  126. bool force_fast_update = false,
  127. U32 use_name = 0);
  128. bool setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos,
  129. U32 width, U32 height);
  130. // Wait for GL commands to finish on current thread and push a lambda to
  131. // the main thread to set mTexName with the new name.
  132. void syncToMainThread(U32 new_tex_name);
  133. // Read back a raw image for this discard level, if it exists
  134. bool readBackRaw(S32 discard_level, LLImageRaw* imagerawp,
  135. bool compressed_ok) const;
  136. void destroyGLTexture();
  137. void forceToInvalidateGLTexture();
  138. void setExplicitFormat(S32 internal_format, U32 primary_format,
  139. U32 type_format = 0, bool swap_bytes = false);
  140. LL_INLINE void setComponents(S8 ncomponents) { mComponents = ncomponents; }
  141. LL_INLINE S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
  142. LL_INLINE S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
  143. LL_INLINE U32 getCurrentWidth() const { return mWidth;}
  144. LL_INLINE U32 getCurrentHeight() const { return mHeight;}
  145. U32 getWidth(S32 discard_level = -1) const;
  146. U32 getHeight(S32 discard_level = -1) const;
  147. LL_INLINE U8 getComponents() const { return mComponents; }
  148. S64 getBytes(S32 discard_level = -1) const;
  149. S64 getMipBytes(S32 discard_level = -1) const;
  150. LL_INLINE bool getBoundRecently() const
  151. {
  152. constexpr F32 MIN_TEXTURE_LIFETIME = 10.f;
  153. return sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME;
  154. }
  155. LL_INLINE bool isJustBound() const { return sLastFrameTime - mLastBindTime < 0.5f; }
  156. LL_INLINE bool hasExplicitFormat() const { return mHasExplicitFormat; }
  157. LL_INLINE U32 getPrimaryFormat() const { return mFormatPrimary; }
  158. LL_INLINE U32 getFormatType() const { return mFormatType; }
  159. bool isCompressed() const;
  160. LL_INLINE bool getHasGLTexture() const
  161. {
  162. const_cast<LLImageGL*>(this)->syncTexName();
  163. return mTexName != 0;
  164. }
  165. LL_INLINE U32 getTexName() const
  166. {
  167. const_cast<LLImageGL*>(this)->syncTexName();
  168. return mTexName;
  169. }
  170. // Used by LLGLTexture, LLCubeMap and LLCubeMapArray.
  171. void setTexName(U32 name);
  172. // Similar to setTexName(), but will call deleteTextures on mTexName if
  173. // mTexName is not 0 or texname.
  174. // Used by LLBumpImageList and LLViewerMediaImpl.
  175. void syncTexName(U32 texname);
  176. LL_INLINE bool getIsAlphaMask() const { return mIsMask; }
  177. void setTarget(U32 target, LLTexUnit::eTextureType bind_target);
  178. LL_INLINE LLTexUnit::eTextureType getTarget() const { return mBindTarget; }
  179. LL_INLINE bool isGLTextureCreated() const { return mGLTextureCreated; }
  180. LL_INLINE void setGLTextureCreated(bool b) { mGLTextureCreated = b; }
  181. LL_INLINE bool getUseMipMaps() const { return mUseMipMaps; }
  182. LL_INLINE void setUseMipMaps(bool b) { mUseMipMaps = b; }
  183. LL_INLINE void setHasMipMaps(bool b) { mHasMipMaps = b; }
  184. void updatePickMask(U32 width, U32 height, const U8* data_in);
  185. bool getMask(const LLVector2& tc);
  186. // Sets the addressing mode used to sample the texture (such as wrapping,
  187. // mirrored wrapping, and clamp).
  188. // Note: this actually gets set the next time the texture is bound.
  189. void setAddressMode(LLTexUnit::eTextureAddressMode mode);
  190. LL_INLINE LLTexUnit::eTextureAddressMode getAddressMode() const
  191. {
  192. return mAddressMode;
  193. }
  194. // Sets the filtering options used to sample the texture (such as point
  195. // sampling, bilinear interpolation, mipmapping and anisotropic filtering).
  196. // Note: this actually gets set the next time the texture is bound.
  197. void setFilteringOption(LLTexUnit::eTextureFilterOptions option);
  198. LL_INLINE LLTexUnit::eTextureFilterOptions getFilteringOption() const
  199. {
  200. return mFilterOption;
  201. }
  202. LL_INLINE U32 getTexTarget()const { return mTarget; }
  203. void init(bool usemipmaps);
  204. // Clean up the LLImageGL so it can be reinitialized. Be careful when
  205. // using this in derived class destructors
  206. virtual void cleanup();
  207. void setNeedsAlphaAndPickMask(bool need_mask);
  208. // Without regular calls to this method, the viewer piles up NO_DELETE
  209. // textures in memory (both RAM and, much worst, VRAM), causing a "leakage"
  210. // that ruins textures LoDs in the long term (since the discard bias must
  211. // then be kept high to avoid VRAM from overflowing), and even VRAM
  212. // exhaustion in the long term. HB
  213. static U32 activateStaleTextures();
  214. // For debugging, logs the stales images list. HB
  215. static void dumpStaleList();
  216. private:
  217. void syncTexName();
  218. U32 createPickMask(U32 width, U32 height);
  219. void freePickMask();
  220. private:
  221. LLPointer<LLImageRaw> mSaveData; // Used for destroyGL/restoreGL
  222. LLGLTexture* mOwnerp;
  223. LLAtomicBool mTexNameDirty;
  224. U32 mTexName;
  225. U32 mNewTexName;
  226. GLsync mTexNameSync;
  227. // Downsampled bitmap approximation of alpha channel. NULL if no alpha
  228. // channel:
  229. U8* mPickMask;
  230. U16 mPickMaskWidth;
  231. U16 mPickMaskHeight;
  232. U16 mWidth;
  233. U16 mHeight;
  234. bool mUseMipMaps;
  235. // If false (default), GL format is f(mComponents):
  236. bool mHasExplicitFormat;
  237. bool mAutoGenMips;
  238. bool mIsMask;
  239. bool mNeedsAlphaAndPickMask;
  240. S8 mAlphaStride;
  241. S8 mAlphaOffset;
  242. bool mGLTextureCreated;
  243. S8 mCurrentDiscardLevel;
  244. bool mAllowCompression;
  245. static std::vector<U32> sFreeList[4];
  246. // Current frame number.
  247. static U32 sCurrentFrame;
  248. static bool sDelayedTextureDelete;
  249. protected:
  250. bool mHasMipMaps;
  251. bool mTexOptionsDirty;
  252. // If true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1)
  253. bool mFormatSwapBytes;
  254. U8 mComponents;
  255. S8 mMaxDiscardLevel;
  256. // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps):
  257. U32 mTarget;
  258. // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
  259. LLTexUnit::eTextureType mBindTarget;
  260. S32 mMipLevels;
  261. // Defaults to TAM_WRAP
  262. LLTexUnit::eTextureAddressMode mAddressMode;
  263. // Defaults to TFO_ANISOTROPIC
  264. LLTexUnit::eTextureFilterOptions mFilterOption;
  265. S32 mFormatInternal; // = GL internal format
  266. U32 mFormatPrimary; // = GL pixel data format
  267. U32 mFormatType;
  268. public:
  269. // Various GL/Rendering options
  270. S64 mTextureMemory;
  271. // Last time this was bound, by discard level
  272. mutable F32 mLastBindTime;
  273. #if DEBUG_MISS
  274. bool mMissed // Missed on last bind ?
  275. #endif
  276. static S32 sCount;
  277. static F32 sLastFrameTime;
  278. static LLImageGL* sDefaultGLImagep;
  279. // Global memory statistics
  280. // Tracks main memory texmem (atomic since accessed from GL threads)
  281. static LLAtomicS64 sGlobalTexMemBytes;
  282. // Tracks bound texmem for last completed frame;
  283. static S64 sBoundTexMemBytes;
  284. // Tracks number of texture binds for current frame
  285. static U32 sBindCount;
  286. // Tracks number of unique texture binds for current frame
  287. static U32 sUniqueCount;
  288. // GL textures compression
  289. static U32 sCompressThreshold;
  290. static bool sCompressTextures;
  291. static bool sGlobalUseAnisotropic;
  292. // This flag *must* be set to true before stopping GL and can only be reset
  293. // to false again once GL is restarted (else, GL textures may get recreated
  294. // while GL is stopped, which leads to a crash !).
  295. static bool sPreserveDiscard;
  296. // When this is true, and in main thread, and the image is not compressed,
  297. // setSubImage() and setManualImage() set the image line by line to avoid
  298. // large data transfers in the GL queue.
  299. static bool sSetSubImagePerLine;
  300. // For NVIDIA, when this is true, we sync GL in the thread after the GL
  301. // image creation, to avoid stalling at all the main thread GL pipeline. HB
  302. static bool sSyncInThread;
  303. private:
  304. typedef fast_hset<LLImageGL*> glimage_list_t;
  305. static glimage_list_t sImageList;
  306. static LLImageGLThread* sThread;
  307. };
  308. class LLImageGLThread : public LLThreadPool
  309. {
  310. friend class LLImageGL;
  311. protected:
  312. LOG_CLASS(LLImageGLThread);
  313. LLImageGLThread(LLWindow* window, U32 threads);
  314. public:
  315. // LLThreadPool overrides
  316. void run() override;
  317. // This is a no-op since we must perform complex initialization during
  318. // run(), that *will* be interrupted by the OS scheduler at some point;
  319. // we instead call LLThreadPool::doIncStartedThreads() in run(), once
  320. // our initialization process is finished. HB
  321. LL_INLINE void maybeIncStartedThreads() override
  322. {
  323. }
  324. // Posts a function to be executed on the LLImageGL background thread
  325. template <typename CALLABLE>
  326. bool post(CALLABLE&& func)
  327. {
  328. return getQueue().postIfOpen(std::forward<CALLABLE>(func));
  329. }
  330. // App should call this method periodically to update the available VRAM
  331. static void updateFreeVRAM();
  332. LL_INLINE static S32 getFreeVRAMMegabytes() { return sFreeVRAMMegabytes; }
  333. // Use to destroy remaining instances after their shutdown is done. HB
  334. static void cleanup();
  335. private:
  336. static void readFreeVRAM();
  337. private:
  338. LLWindow* mWindow;
  339. // We need a mutex to avoid a race with GL context changes during the
  340. // threads initialization, which is itself a threaded operation. This mutex
  341. // also protects mTheadCounter, which is used in the same part of the code
  342. // and does not need to be made atomic as a result. HB
  343. LLMutex mThreadsMutex;
  344. std::vector<void*> mContexts;
  345. U32 mTheadCounter;
  346. public:
  347. // Free video memory in megabytes
  348. static LLAtomicS32 sFreeVRAMMegabytes;
  349. static bool sEnabled;
  350. };
  351. extern LLWorkQueue::weak_t gImageQueuep;
  352. #endif // LL_LLIMAGEGL_H