llgltexture.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /**
  2. * @file llgltexture.cpp
  3. * @brief OpenGL texture implementation
  4. *
  5. * $LicenseInfo:firstyear=2012&license=viewergpl$
  6. *
  7. * Copyright (c) 2012, 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. #include "linden_common.h"
  33. #include "llgltexture.h"
  34. #include "llimagegl.h"
  35. // Made this a global variable to cover differences between grids (SL or
  36. // OpenSim). HB
  37. S32 gMaxImageSizeDefault = 1024;
  38. LLGLTexture::LLGLTexture(bool usemipmaps)
  39. {
  40. init();
  41. mUseMipMaps = usemipmaps;
  42. }
  43. LLGLTexture::LLGLTexture(U32 width, U32 height, U8 components, bool usemipmaps)
  44. {
  45. init();
  46. mFullWidth = width;
  47. mFullHeight = height;
  48. mUseMipMaps = usemipmaps;
  49. mComponents = components;
  50. setTexelsPerImage();
  51. }
  52. LLGLTexture::LLGLTexture(const LLImageRaw* rawp, bool usemipmaps)
  53. {
  54. init();
  55. mUseMipMaps = usemipmaps;
  56. // Create an empty image of the specified size and width
  57. mImageGLp = new LLImageGL(rawp, usemipmaps);
  58. mImageGLp->setOwner(this);
  59. mFullWidth = mImageGLp->getWidth();
  60. mFullHeight = mImageGLp->getHeight();
  61. mComponents = mImageGLp->getComponents();
  62. setTexelsPerImage();
  63. }
  64. LLGLTexture::~LLGLTexture()
  65. {
  66. cleanup();
  67. mImageGLp = NULL;
  68. }
  69. void LLGLTexture::init()
  70. {
  71. mBoostLevel = BOOST_NONE;
  72. mFullWidth = 0;
  73. mFullHeight = 0;
  74. mTexelsPerImage = 0;
  75. mUseMipMaps = false;
  76. mComponents = 0;
  77. mTextureState = NO_DELETE;
  78. mDontDiscard = false;
  79. mNeedsGLTexture = false;
  80. mIsMegaTexture = false;
  81. }
  82. void LLGLTexture::cleanup()
  83. {
  84. if (mImageGLp)
  85. {
  86. mImageGLp->cleanup();
  87. }
  88. }
  89. // virtual
  90. void LLGLTexture::dump()
  91. {
  92. if (mImageGLp)
  93. {
  94. mImageGLp->dump();
  95. }
  96. }
  97. void LLGLTexture::setBoostLevel(U32 level)
  98. {
  99. // Do not downgrade UI textures, ever ! HB
  100. if (mBoostLevel == BOOST_UI)
  101. {
  102. return;
  103. }
  104. if (level == BOOST_UI)
  105. {
  106. mBoostLevel = level;
  107. // UI textures must always be kept in memory for the whole duration of
  108. // the viewer session. HB
  109. mTextureState = ALWAYS_KEEP;
  110. // Also, never allow to discard UI textures. HB
  111. mDontDiscard = true;
  112. return;
  113. }
  114. mBoostLevel = level;
  115. #if LL_IMPLICIT_SETNODELETE
  116. if (level != BOOST_NONE && level != BOOST_ALM && level != BOOST_SELECTED)
  117. {
  118. mTextureState = NO_DELETE;
  119. }
  120. #else
  121. // Make map textures no-delete, always.
  122. if (level == BOOST_MAP)
  123. {
  124. mTextureState = NO_DELETE;
  125. }
  126. #endif
  127. }
  128. void LLGLTexture::generateGLTexture()
  129. {
  130. if (mImageGLp.isNull())
  131. {
  132. mImageGLp = new LLImageGL(mFullWidth, mFullHeight, mComponents,
  133. mUseMipMaps);
  134. mImageGLp->setOwner(this);
  135. }
  136. }
  137. LLImageGL* LLGLTexture::getGLImage() const
  138. {
  139. llassert(mImageGLp.notNull());
  140. return mImageGLp;
  141. }
  142. bool LLGLTexture::createGLTexture()
  143. {
  144. if (mImageGLp.isNull())
  145. {
  146. generateGLTexture();
  147. }
  148. return mImageGLp->createGLTexture();
  149. }
  150. bool LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* rawimg,
  151. S32 usename, bool to_create, bool defer_copy,
  152. U32* tex_name)
  153. {
  154. if (mImageGLp.isNull())
  155. {
  156. llwarns << "NULL GL image for GL texture 0x" << std::hex
  157. << (intptr_t)this << std::dec << llendl;
  158. llassert(false);
  159. return false;
  160. }
  161. bool ret = mImageGLp->createGLTexture(discard_level, rawimg, usename,
  162. to_create, defer_copy, tex_name);
  163. if (ret)
  164. {
  165. mFullWidth = mImageGLp->getCurrentWidth();
  166. mFullHeight = mImageGLp->getCurrentHeight();
  167. mComponents = mImageGLp->getComponents();
  168. setTexelsPerImage();
  169. }
  170. return ret;
  171. }
  172. void LLGLTexture::setExplicitFormat(S32 internal_format, U32 primary_format,
  173. U32 type_format, bool swap_bytes)
  174. {
  175. llassert_always(mImageGLp.notNull());
  176. mImageGLp->setExplicitFormat(internal_format, primary_format, type_format,
  177. swap_bytes);
  178. }
  179. void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
  180. {
  181. llassert_always(mImageGLp.notNull());
  182. mImageGLp->setAddressMode(mode);
  183. }
  184. void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
  185. {
  186. llassert_always(mImageGLp.notNull());
  187. mImageGLp->setFilteringOption(option);
  188. }
  189. //virtual
  190. S32 LLGLTexture::getWidth(S32 discard_level) const
  191. {
  192. llassert_always(mImageGLp.notNull());
  193. return mImageGLp->getWidth(discard_level);
  194. }
  195. //virtual
  196. S32 LLGLTexture::getHeight(S32 discard_level) const
  197. {
  198. llassert_always(mImageGLp.notNull());
  199. return mImageGLp->getHeight(discard_level);
  200. }
  201. S32 LLGLTexture::getMaxDiscardLevel() const
  202. {
  203. llassert_always(mImageGLp.notNull());
  204. return mImageGLp->getMaxDiscardLevel();
  205. }
  206. S32 LLGLTexture::getDiscardLevel() const
  207. {
  208. llassert_always(mImageGLp.notNull());
  209. return mImageGLp->getDiscardLevel();
  210. }
  211. S8 LLGLTexture::getComponents() const
  212. {
  213. llassert_always(mImageGLp.notNull());
  214. return mImageGLp->getComponents();
  215. }
  216. U32 LLGLTexture::getTexName() const
  217. {
  218. return mImageGLp.notNull() ? mImageGLp->getTexName() : 0;
  219. }
  220. bool LLGLTexture::hasGLTexture() const
  221. {
  222. return mImageGLp.notNull() && mImageGLp->getHasGLTexture();
  223. }
  224. bool LLGLTexture::getBoundRecently() const
  225. {
  226. return mImageGLp.notNull() && mImageGLp->getBoundRecently();
  227. }
  228. LLTexUnit::eTextureType LLGLTexture::getTarget() const
  229. {
  230. llassert_always(mImageGLp.notNull());
  231. return mImageGLp->getTarget();
  232. }
  233. bool LLGLTexture::setSubImage(const LLImageRaw* rawimg, S32 x_pos, S32 y_pos,
  234. S32 width, S32 height, U32 use_name)
  235. {
  236. llassert_always(mImageGLp.notNull());
  237. return mImageGLp->setSubImage(rawimg, x_pos, y_pos, width, height, 0,
  238. use_name);
  239. }
  240. bool LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height,
  241. S32 x_pos, S32 y_pos, S32 width, S32 height,
  242. U32 use_name)
  243. {
  244. llassert_always(mImageGLp.notNull());
  245. return mImageGLp->setSubImage(datap, data_width, data_height, x_pos, y_pos,
  246. width, height, 0, use_name);
  247. }
  248. void LLGLTexture::setGLTextureCreated (bool initialized)
  249. {
  250. llassert_always(mImageGLp.notNull());
  251. mImageGLp->setGLTextureCreated (initialized);
  252. }
  253. #if 0 // Not used
  254. void LLGLTexture::setTexName(U32 name)
  255. {
  256. llassert_always(mImageGLp.notNull());
  257. mImageGLp->setTexName(name);
  258. }
  259. void LLGLTexture::setTarget(U32 target, LLTexUnit::eTextureType bind_target)
  260. {
  261. llassert_always(mImageGLp.notNull());
  262. mImageGLp->setTarget(target, bind_target);
  263. }
  264. #endif
  265. LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode() const
  266. {
  267. llassert_always(mImageGLp.notNull());
  268. return mImageGLp->getAddressMode();
  269. }
  270. S32 LLGLTexture::getTextureMemory() const
  271. {
  272. llassert_always(mImageGLp.notNull());
  273. return mImageGLp->mTextureMemory;
  274. }
  275. U32 LLGLTexture::getPrimaryFormat() const
  276. {
  277. llassert_always(mImageGLp.notNull());
  278. return mImageGLp->getPrimaryFormat();
  279. }
  280. bool LLGLTexture::getIsAlphaMask() const
  281. {
  282. llassert_always(mImageGLp.notNull());
  283. return mImageGLp->getIsAlphaMask();
  284. }
  285. bool LLGLTexture::getMask(const LLVector2 &tc)
  286. {
  287. llassert_always(mImageGLp.notNull());
  288. return mImageGLp->getMask(tc);
  289. }
  290. F32 LLGLTexture::getTimePassedSinceLastBound()
  291. {
  292. llassert_always(mImageGLp.notNull());
  293. return mImageGLp->getTimePassedSinceLastBound();
  294. }
  295. bool LLGLTexture::isJustBound() const
  296. {
  297. llassert_always(mImageGLp.notNull());
  298. return mImageGLp->isJustBound();
  299. }
  300. void LLGLTexture::forceUpdateBindStats() const
  301. {
  302. llassert_always(mImageGLp.notNull());
  303. mImageGLp->forceUpdateBindStats();
  304. }
  305. void LLGLTexture::destroyGLTexture()
  306. {
  307. if (mImageGLp.notNull() && mImageGLp->getHasGLTexture())
  308. {
  309. mImageGLp->destroyGLTexture();
  310. }
  311. mTextureState = DELETED;
  312. }
  313. void LLGLTexture::setTexelsPerImage()
  314. {
  315. S32 fullwidth = llmin(mFullWidth, (S32)gMaxImageSizeDefault);
  316. S32 fullheight = llmin(mFullHeight, (S32)gMaxImageSizeDefault);
  317. mTexelsPerImage = fullwidth * fullheight;
  318. }
  319. // Returns the minimum discard level to apply to this image, depending on its
  320. // dimensions and the gMaxImageSizeDefault limit. HB
  321. S32 LLGLTexture::getMinDiscardLevel() const
  322. {
  323. S32 max_size = llmax(mFullWidth, mFullHeight);
  324. if (max_size <= gMaxImageSizeDefault)
  325. {
  326. return 0;
  327. }
  328. if (max_size > 2 * gMaxImageSizeDefault)
  329. {
  330. // E.g. 4K image and 1K max size. HB
  331. return 2;
  332. }
  333. // E.g. 2K image and 1K max size. HB
  334. return 1;
  335. }