llimagegl.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:46k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llimagegl.cpp
  3.  * @brief Generic GL image handler
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-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. // TODO: create 2 classes for images w/ and w/o discard levels?
  33. #include "linden_common.h"
  34. #include "llimagegl.h"
  35. #include "llerror.h"
  36. #include "llimage.h"
  37. #include "llmath.h"
  38. #include "llgl.h"
  39. #include "llrender.h"
  40. //----------------------------------------------------------------------------
  41. const F32 MIN_TEXTURE_LIFETIME = 10.f;
  42. //statics
  43. LLGLuint LLImageGL::sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS] = { 0 };
  44. U32 LLImageGL::sUniqueCount = 0;
  45. U32 LLImageGL::sBindCount = 0;
  46. S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
  47. S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
  48. S32 LLImageGL::sCurBoundTextureMemory = 0;
  49. S32 LLImageGL::sCount = 0;
  50. std::list<U32> LLImageGL::sDeadTextureList;
  51. BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
  52. F32 LLImageGL::sLastFrameTime = 0.f;
  53. BOOL LLImageGL::sAllowReadBackRaw       = FALSE ;
  54. LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
  55. std::set<LLImageGL*> LLImageGL::sImageList;
  56. //****************************************************************************************************
  57. //The below for texture auditing use only
  58. //****************************************************************************************************
  59. //-----------------------
  60. //debug use
  61. BOOL gAuditTexture = FALSE ;
  62. #define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048
  63. std::vector<S32> LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
  64. std::vector<S32> LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
  65. std::vector<S32> LLImageGL::sTextureCurBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ;
  66. S32 LLImageGL::sCurTexSizeBar = -1 ;
  67. S32 LLImageGL::sCurTexPickSize = -1 ;
  68. LLPointer<LLImageGL> LLImageGL::sHighlightTexturep = NULL;
  69. S32 LLImageGL::sMaxCatagories = 1 ;
  70. std::vector<S32> LLImageGL::sTextureMemByCategory;
  71. std::vector<S32> LLImageGL::sTextureMemByCategoryBound ;
  72. std::vector<S32> LLImageGL::sTextureCurMemByCategoryBound ;
  73. //------------------------
  74. //****************************************************************************************************
  75. //End for texture auditing use only
  76. //****************************************************************************************************
  77. //**************************************************************************************
  78. //below are functions for debug use
  79. //do not delete them even though they are not currently being used.
  80. void check_all_images()
  81. {
  82. for (std::set<LLImageGL*>::iterator iter = LLImageGL::sImageList.begin();
  83.  iter != LLImageGL::sImageList.end(); iter++)
  84. {
  85. LLImageGL* glimage = *iter;
  86. if (glimage->getTexName() && glimage->isGLTextureCreated())
  87. {
  88. gGL.getTexUnit(0)->bind(glimage) ;
  89. glimage->checkTexSize() ;
  90. gGL.getTexUnit(0)->unbind(glimage->getTarget()) ;
  91. }
  92. }
  93. }
  94. void LLImageGL::checkTexSize() const
  95. {
  96. if (gDebugGL && mTarget == GL_TEXTURE_2D)
  97. {
  98. GLint texname;
  99. glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
  100. BOOL error = FALSE;
  101. if (texname != mTexName)
  102. {
  103. error = TRUE;
  104. if (gDebugSession)
  105. {
  106. gFailLog << "Invalid texture bound!" << std::endl;
  107. }
  108. else
  109. {
  110. llerrs << "Invalid texture bound!" << llendl;
  111. }
  112. }
  113. stop_glerror() ;
  114. LLGLint x = 0, y = 0 ;
  115. glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_WIDTH, (GLint*)&x);
  116. glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_HEIGHT, (GLint*)&y) ;
  117. stop_glerror() ;
  118. if(!x || !y)
  119. {
  120. return ;
  121. }
  122. if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
  123. {
  124. error = TRUE;
  125. if (gDebugSession)
  126. {
  127. gFailLog << "wrong texture size and discard level!" << std::endl;
  128. }
  129. else
  130. {
  131. llerrs << "wrong texture size and discard level!" << llendl ;
  132. }
  133. }
  134. if (error)
  135. {
  136. ll_fail("LLImageGL::checkTexSize failed.");
  137. }
  138. }
  139. }
  140. //end of debug functions
  141. //**************************************************************************************
  142. //----------------------------------------------------------------------------
  143. BOOL is_little_endian()
  144. {
  145. S32 a = 0x12345678;
  146.     U8 *c = (U8*)(&a);
  147.     
  148. return (*c == 0x78) ;
  149. }
  150. //static 
  151. void LLImageGL::initClass(S32 num_catagories) 
  152. {
  153. sMaxCatagories = num_catagories ;
  154. sTextureMemByCategory.resize(sMaxCatagories);
  155. sTextureMemByCategoryBound.resize(sMaxCatagories) ;
  156. sTextureCurMemByCategoryBound.resize(sMaxCatagories) ;
  157. }
  158. //static 
  159. void LLImageGL::cleanupClass() 
  160. {
  161. sTextureMemByCategory.clear() ;
  162. sTextureMemByCategoryBound.clear() ;
  163. sTextureCurMemByCategoryBound.clear() ;
  164. }
  165. //static 
  166. void LLImageGL::setHighlightTexture(S32 category) 
  167. {
  168. const S32 dim = 128;
  169. sHighlightTexturep = new LLImageGL() ;
  170. LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
  171. U8* data = image_raw->getData();
  172. for (S32 i = 0; i<dim; i++)
  173. {
  174. for (S32 j = 0; j<dim; j++)
  175. {
  176. const S32 border = 2;
  177. if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
  178. {
  179. *data++ = 0xff;
  180. *data++ = 0xff;
  181. *data++ = 0xff;
  182. }
  183. else
  184. {
  185. *data++ = 0xff;
  186. *data++ = 0xff;
  187. *data++ = 0x00;
  188. }
  189. }
  190. }
  191. sHighlightTexturep->createGLTexture(0, image_raw, 0, TRUE, category);
  192. image_raw = NULL;
  193. }
  194. //static
  195. S32 LLImageGL::dataFormatBits(S32 dataformat)
  196. {
  197. switch (dataformat)
  198. {
  199.   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 4;
  200.   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 8;
  201.   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 8;
  202.   case GL_LUMINANCE: return 8;
  203.   case GL_ALPHA: return 8;
  204.   case GL_COLOR_INDEX: return 8;
  205.   case GL_LUMINANCE_ALPHA: return 16;
  206.   case GL_RGB: return 24;
  207.   case GL_RGB8: return 24;
  208.   case GL_RGBA: return 32;
  209.   case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac
  210.   default:
  211. llerrs << "LLImageGL::Unknown format: " << dataformat << llendl;
  212. return 0;
  213. }
  214. }
  215. //static
  216. S32 LLImageGL::dataFormatBytes(S32 dataformat, S32 width, S32 height)
  217. {
  218. if (dataformat >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT &&
  219. dataformat <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
  220. {
  221. if (width < 4) width = 4;
  222. if (height < 4) height = 4;
  223. }
  224. S32 bytes ((width*height*dataFormatBits(dataformat)+7)>>3);
  225. S32 aligned = (bytes+3)&~3;
  226. return aligned;
  227. }
  228. //static
  229. S32 LLImageGL::dataFormatComponents(S32 dataformat)
  230. {
  231. switch (dataformat)
  232. {
  233.   case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return 3;
  234.   case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: return 4;
  235.   case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: return 4;
  236.   case GL_LUMINANCE: return 1;
  237.   case GL_ALPHA: return 1;
  238.   case GL_COLOR_INDEX: return 1;
  239.   case GL_LUMINANCE_ALPHA: return 2;
  240.   case GL_RGB: return 3;
  241.   case GL_RGBA: return 4;
  242.   case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac
  243.   default:
  244. llerrs << "LLImageGL::Unknown format: " << dataformat << llendl;
  245. return 0;
  246. }
  247. }
  248. //----------------------------------------------------------------------------
  249. // static
  250. void LLImageGL::updateStats(F32 current_time)
  251. {
  252. sLastFrameTime = current_time;
  253. sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
  254. sCurBoundTextureMemory = 0;
  255. if(gAuditTexture)
  256. {
  257. for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++)
  258. {
  259. sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ;
  260. sTextureCurBoundCounter[i] = 0 ;
  261. }
  262. for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++)
  263. {
  264. sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ;
  265. sTextureCurMemByCategoryBound[i] = 0 ;
  266. }
  267. }
  268. }
  269. //static
  270. S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category)
  271. {
  272. if(gAuditTexture && ncomponents > 0 && category > -1)
  273. {
  274. sTextureCurBoundCounter[getTextureCounterIndex(mem / ncomponents)]++ ;
  275. sTextureCurMemByCategoryBound[category] += mem ;
  276. }
  277. LLImageGL::sCurBoundTextureMemory += mem ;
  278. return LLImageGL::sCurBoundTextureMemory;
  279. }
  280. //----------------------------------------------------------------------------
  281. //static 
  282. void LLImageGL::destroyGL(BOOL save_state)
  283. {
  284. for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++)
  285. {
  286. gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
  287. }
  288. sAllowReadBackRaw = true ;
  289. for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
  290.  iter != sImageList.end(); iter++)
  291. {
  292. LLImageGL* glimage = *iter;
  293. if (glimage->mTexName)
  294. {
  295. if (save_state && glimage->isGLTextureCreated() && glimage->mComponents)
  296. {
  297. glimage->mSaveData = new LLImageRaw;
  298. if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it.
  299. {
  300. glimage->mSaveData = NULL ;
  301. }
  302. }
  303. glimage->destroyGLTexture();
  304. stop_glerror();
  305. }
  306. }
  307. sAllowReadBackRaw = false ;
  308. }
  309. //static 
  310. void LLImageGL::restoreGL()
  311. {
  312. for (std::set<LLImageGL*>::iterator iter = sImageList.begin();
  313.  iter != sImageList.end(); iter++)
  314. {
  315. LLImageGL* glimage = *iter;
  316. if(glimage->getTexName())
  317. {
  318. llerrs << "tex name is not 0." << llendl ;
  319. }
  320. if (glimage->mSaveData.notNull())
  321. {
  322. if (glimage->getComponents() && glimage->mSaveData->getComponents())
  323. {
  324. glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory());
  325. stop_glerror();
  326. }
  327. glimage->mSaveData = NULL; // deletes data
  328. }
  329. }
  330. }
  331. //----------------------------------------------------------------------------
  332. //for server side use only.
  333. //static 
  334. BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, BOOL usemipmaps)
  335. {
  336. dest = new LLImageGL(usemipmaps);
  337. return TRUE;
  338. }
  339. //for server side use only.
  340. BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, U32 width, U32 height, U8 components, BOOL usemipmaps)
  341. {
  342. dest = new LLImageGL(width, height, components, usemipmaps);
  343. return TRUE;
  344. }
  345. //for server side use only.
  346. BOOL LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, BOOL usemipmaps)
  347. {
  348. dest = new LLImageGL(imageraw, usemipmaps);
  349. return TRUE;
  350. }
  351. //----------------------------------------------------------------------------
  352. LLImageGL::LLImageGL(BOOL usemipmaps)
  353. : mSaveData(0)
  354. {
  355. init(usemipmaps);
  356. setSize(0, 0, 0);
  357. sImageList.insert(this);
  358. sCount++;
  359. }
  360. LLImageGL::LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps)
  361. : mSaveData(0)
  362. {
  363. llassert( components <= 4 );
  364. init(usemipmaps);
  365. setSize(width, height, components);
  366. sImageList.insert(this);
  367. sCount++;
  368. }
  369. LLImageGL::LLImageGL(const LLImageRaw* imageraw, BOOL usemipmaps)
  370. : mSaveData(0)
  371. {
  372. init(usemipmaps);
  373. setSize(0, 0, 0);
  374. sImageList.insert(this);
  375. sCount++;
  376. createGLTexture(0, imageraw); 
  377. }
  378. LLImageGL::~LLImageGL()
  379. {
  380. LLImageGL::cleanup();
  381. sImageList.erase(this);
  382. delete [] mPickMask;
  383. mPickMask = NULL;
  384. sCount--;
  385. }
  386. void LLImageGL::init(BOOL usemipmaps)
  387. {
  388. // keep these members in the same order as declared in llimagehl.h
  389. // so that it is obvious by visual inspection if we forgot to
  390. // init a field.
  391. mTextureMemory = 0;
  392. mLastBindTime = 0.f;
  393. mPickMask = NULL;
  394. mPickMaskWidth = 0;
  395. mPickMaskHeight = 0;
  396. mUseMipMaps = usemipmaps;
  397. mHasExplicitFormat = FALSE;
  398. mAutoGenMips = FALSE;
  399. mIsMask = FALSE;
  400. mNeedsAlphaAndPickMask = TRUE ;
  401. mAlphaStride = 0 ;
  402. mAlphaOffset = 0 ;
  403. mGLTextureCreated = FALSE ;
  404. mTexName = 0;
  405. mWidth = 0;
  406. mHeight = 0;
  407. mCurrentDiscardLevel = -1;
  408. mDiscardLevelInAtlas = -1 ;
  409. mTexelsInAtlas = 0 ;
  410. mTexelsInGLTexture = 0 ;
  411. mTarget = GL_TEXTURE_2D;
  412. mBindTarget = LLTexUnit::TT_TEXTURE;
  413. mHasMipMaps = false;
  414. mIsResident = 0;
  415. mComponents = 0;
  416. mMaxDiscardLevel = MAX_DISCARD_LEVEL;
  417. mTexOptionsDirty = true;
  418. mAddressMode = LLTexUnit::TAM_WRAP;
  419. mFilterOption = LLTexUnit::TFO_ANISOTROPIC;
  420. mFormatInternal = -1;
  421. mFormatPrimary = (LLGLenum) 0;
  422. mFormatType = GL_UNSIGNED_BYTE;
  423. mFormatSwapBytes = FALSE;
  424. #ifdef DEBUG_MISS
  425. mMissed = FALSE;
  426. #endif
  427. mCategory = -1;
  428. }
  429. void LLImageGL::cleanup()
  430. {
  431. if (!gGLManager.mIsDisabled)
  432. {
  433. destroyGLTexture();
  434. }
  435. mSaveData = NULL; // deletes data
  436. }
  437. //----------------------------------------------------------------------------
  438. //this function is used to check the size of a texture image.
  439. //so dim should be a positive number
  440. static bool check_power_of_two(S32 dim)
  441. {
  442. if(dim < 0)
  443. {
  444. return false ;
  445. }
  446. if(!dim)//0 is a power-of-two number
  447. {
  448. return true ;
  449. }
  450. return !(dim & (dim - 1)) ;
  451. }
  452. //static
  453. bool LLImageGL::checkSize(S32 width, S32 height)
  454. {
  455. return check_power_of_two(width) && check_power_of_two(height);
  456. }
  457. void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
  458. {
  459. if (width != mWidth || height != mHeight || ncomponents != mComponents)
  460. {
  461. // Check if dimensions are a power of two!
  462. if (!checkSize(width,height))
  463. {
  464. llerrs << llformat("Texture has non power of two dimension: %dx%d",width,height) << llendl;
  465. }
  466. if (mTexName)
  467. {
  468. //  llwarns << "Setting Size of LLImageGL with existing mTexName = " << mTexName << llendl;
  469. destroyGLTexture();
  470. }
  471. // pickmask validity depends on old image size, delete it
  472. delete [] mPickMask;
  473. mPickMask = NULL;
  474. mPickMaskWidth = mPickMaskHeight = 0;
  475. mWidth = width;
  476. mHeight = height;
  477. mComponents = ncomponents;
  478. if (ncomponents > 0)
  479. {
  480. mMaxDiscardLevel = 0;
  481. while (width > 1 && height > 1 && mMaxDiscardLevel < MAX_DISCARD_LEVEL)
  482. {
  483. mMaxDiscardLevel++;
  484. width >>= 1;
  485. height >>= 1;
  486. }
  487. }
  488. else
  489. {
  490. mMaxDiscardLevel = MAX_DISCARD_LEVEL;
  491. }
  492. }
  493. }
  494. //----------------------------------------------------------------------------
  495. // virtual
  496. void LLImageGL::dump()
  497. {
  498. llinfos << "mMaxDiscardLevel " << S32(mMaxDiscardLevel)
  499. << " mLastBindTime " << mLastBindTime
  500. << " mTarget " << S32(mTarget)
  501. << " mBindTarget " << S32(mBindTarget)
  502. << " mUseMipMaps " << S32(mUseMipMaps)
  503. << " mHasMipMaps " << S32(mHasMipMaps)
  504. << " mCurrentDiscardLevel " << S32(mCurrentDiscardLevel)
  505. << " mFormatInternal " << S32(mFormatInternal)
  506. << " mFormatPrimary " << S32(mFormatPrimary)
  507. << " mFormatType " << S32(mFormatType)
  508. << " mFormatSwapBytes " << S32(mFormatSwapBytes)
  509. << " mHasExplicitFormat " << S32(mHasExplicitFormat)
  510. #if DEBUG_MISS
  511. << " mMissed " << mMissed
  512. #endif
  513. << llendl;
  514. llinfos << " mTextureMemory " << mTextureMemory
  515. << " mTexNames " << mTexName
  516. << " mIsResident " << S32(mIsResident)
  517. << llendl;
  518. }
  519. //----------------------------------------------------------------------------
  520. void LLImageGL::forceUpdateBindStats(void) const
  521. {
  522. mLastBindTime = sLastFrameTime;
  523. }
  524. BOOL LLImageGL::updateBindStats(S32 tex_mem) const
  525. {
  526. if (mTexName != 0)
  527. {
  528. #ifdef DEBUG_MISS
  529. mMissed = ! getIsResident(TRUE);
  530. #endif
  531. sBindCount++;
  532. if (mLastBindTime != sLastFrameTime)
  533. {
  534. // we haven't accounted for this texture yet this frame
  535. sUniqueCount++;
  536. updateBoundTexMem(tex_mem, mComponents, mCategory);
  537. mLastBindTime = sLastFrameTime;
  538. return TRUE ;
  539. }
  540. }
  541. return FALSE ;
  542. }
  543. F32 LLImageGL::getTimePassedSinceLastBound()
  544. {
  545. return sLastFrameTime - mLastBindTime ;
  546. }
  547. void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes )
  548. {
  549. // Note: must be called before createTexture()
  550. // Note: it's up to the caller to ensure that the format matches the number of components.
  551. mHasExplicitFormat = TRUE;
  552. mFormatInternal = internal_format;
  553. mFormatPrimary = primary_format;
  554. if(type_format == 0)
  555. mFormatType = GL_UNSIGNED_BYTE;
  556. else
  557. mFormatType = type_format;
  558. mFormatSwapBytes = swap_bytes;
  559. calcAlphaChannelOffsetAndStride() ;
  560. }
  561. //----------------------------------------------------------------------------
  562. void LLImageGL::setImage(const LLImageRaw* imageraw)
  563. {
  564. llassert((imageraw->getWidth() == getWidth(mCurrentDiscardLevel)) &&
  565.  (imageraw->getHeight() == getHeight(mCurrentDiscardLevel)) &&
  566.  (imageraw->getComponents() == getComponents()));
  567. const U8* rawdata = imageraw->getData();
  568. setImage(rawdata, FALSE);
  569. }
  570. void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
  571. {
  572. bool is_compressed = false;
  573. if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
  574. {
  575. is_compressed = true;
  576. }
  577. llverify(gGL.getTexUnit(0)->bind(this));
  578. if (mUseMipMaps)
  579. {
  580. if (data_hasmips)
  581. {
  582. // NOTE: data_in points to largest image; smaller images
  583. // are stored BEFORE the largest image
  584. for (S32 d=mCurrentDiscardLevel; d<=mMaxDiscardLevel; d++)
  585. {
  586. S32 w = getWidth(d);
  587. S32 h = getHeight(d);
  588. S32 gl_level = d-mCurrentDiscardLevel;
  589. if (d > mCurrentDiscardLevel)
  590. {
  591. data_in -= dataFormatBytes(mFormatPrimary, w, h); // see above comment
  592. }
  593. if (is_compressed)
  594. {
  595.   S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
  596. glCompressedTexImage2DARB(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
  597. stop_glerror();
  598. }
  599. else
  600. {
  601. //  LLFastTimer t2(FTM_TEMP4);
  602. if(mFormatSwapBytes)
  603. {
  604. glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
  605. stop_glerror();
  606. }
  607. LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
  608. if (gl_level == 0)
  609. {
  610. analyzeAlpha(data_in, w, h);
  611. }
  612. updatePickMask(w, h, data_in);
  613. if(mFormatSwapBytes)
  614. {
  615. glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
  616. stop_glerror();
  617. }
  618. stop_glerror();
  619. }
  620. stop_glerror();
  621. }
  622. }
  623. else if (!is_compressed)
  624. {
  625. if (mAutoGenMips)
  626. {
  627. glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
  628. stop_glerror();
  629. {
  630. //  LLFastTimer t2(FTM_TEMP4);
  631. if(mFormatSwapBytes)
  632. {
  633. glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
  634. stop_glerror();
  635. }
  636. S32 w = getWidth(mCurrentDiscardLevel);
  637. S32 h = getHeight(mCurrentDiscardLevel);
  638. LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
  639.  w, h, 
  640.  mFormatPrimary, mFormatType,
  641.  data_in);
  642. analyzeAlpha(data_in, w, h);
  643. stop_glerror();
  644. updatePickMask(w, h, data_in);
  645. if(mFormatSwapBytes)
  646. {
  647. glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
  648. stop_glerror();
  649. }
  650. }
  651. }
  652. else
  653. {
  654. // Create mips by hand
  655. // about 30% faster than autogen on ATI 9800, 50% slower on nVidia 4800
  656. // ~4x faster than gluBuild2DMipmaps
  657. S32 width = getWidth(mCurrentDiscardLevel);
  658. S32 height = getHeight(mCurrentDiscardLevel);
  659. S32 nummips = mMaxDiscardLevel - mCurrentDiscardLevel + 1;
  660. S32 w = width, h = height;
  661. const U8* prev_mip_data = 0;
  662. const U8* cur_mip_data = 0;
  663. S32 prev_mip_size = 0;
  664. S32 cur_mip_size = 0;
  665. for (int m=0; m<nummips; m++)
  666. {
  667. if (m==0)
  668. {
  669. cur_mip_data = data_in;
  670. cur_mip_size = width * height * mComponents; 
  671. }
  672. else
  673. {
  674. S32 bytes = w * h * mComponents;
  675. llassert(prev_mip_data);
  676. llassert(prev_mip_size == bytes*4);
  677. U8* new_data = new U8[bytes];
  678. llassert_always(new_data);
  679. LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
  680. cur_mip_data = new_data;
  681. cur_mip_size = bytes; 
  682. }
  683. llassert(w > 0 && h > 0 && cur_mip_data);
  684. {
  685. //  LLFastTimer t1(FTM_TEMP4);
  686. if(mFormatSwapBytes)
  687. {
  688. glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
  689. stop_glerror();
  690. }
  691. LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
  692. if (m == 0)
  693. {
  694. analyzeAlpha(data_in, w, h);
  695. }
  696. stop_glerror();
  697. if (m == 0)
  698. {
  699. updatePickMask(w, h, cur_mip_data);
  700. }
  701. if(mFormatSwapBytes)
  702. {
  703. glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
  704. stop_glerror();
  705. }
  706. }
  707. if (prev_mip_data && prev_mip_data != data_in)
  708. {
  709. delete[] prev_mip_data;
  710. }
  711. prev_mip_data = cur_mip_data;
  712. prev_mip_size = cur_mip_size;
  713. w >>= 1;
  714. h >>= 1;
  715. }
  716. if (prev_mip_data && prev_mip_data != data_in)
  717. {
  718. delete[] prev_mip_data;
  719. prev_mip_data = NULL;
  720. }
  721. }
  722. }
  723. else
  724. {
  725. llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;
  726. }
  727. mHasMipMaps = true;
  728. }
  729. else
  730. {
  731. S32 w = getWidth();
  732. S32 h = getHeight();
  733. if (is_compressed)
  734. {
  735. S32 tex_size = dataFormatBytes(mFormatPrimary, w, h);
  736. glCompressedTexImage2DARB(mTarget, 0, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in);
  737. stop_glerror();
  738. }
  739. else
  740. {
  741. if(mFormatSwapBytes)
  742. {
  743. glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
  744. stop_glerror();
  745. }
  746. LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
  747.  mFormatPrimary, mFormatType, (GLvoid *)data_in);
  748. analyzeAlpha(data_in, w, h);
  749. updatePickMask(w, h, data_in);
  750. stop_glerror();
  751. if(mFormatSwapBytes)
  752. {
  753. glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
  754. stop_glerror();
  755. }
  756. }
  757. mHasMipMaps = false;
  758. }
  759. stop_glerror();
  760. mGLTextureCreated = true;
  761. }
  762. BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
  763. {
  764. if (gGLManager.mIsDisabled)
  765. {
  766. llwarns << "Trying to create a texture while GL is disabled!" << llendl;
  767. return FALSE;
  768. }
  769. llassert(gGLManager.mInited);
  770. stop_glerror();
  771. if (discard_level < 0)
  772. {
  773. llassert(mCurrentDiscardLevel >= 0);
  774. discard_level = mCurrentDiscardLevel;
  775. }
  776. discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
  777. // Actual image width/height = raw image width/height * 2^discard_level
  778. S32 w = raw_image->getWidth() << discard_level;
  779. S32 h = raw_image->getHeight() << discard_level;
  780. // setSize may call destroyGLTexture if the size does not match
  781. setSize(w, h, raw_image->getComponents());
  782. if( !mHasExplicitFormat )
  783. {
  784. switch (mComponents)
  785. {
  786.   case 1:
  787. // Use luminance alpha (for fonts)
  788. mFormatInternal = GL_LUMINANCE8;
  789. mFormatPrimary = GL_LUMINANCE;
  790. mFormatType = GL_UNSIGNED_BYTE;
  791. break;
  792.   case 2:
  793. // Use luminance alpha (for fonts)
  794. mFormatInternal = GL_LUMINANCE8_ALPHA8;
  795. mFormatPrimary = GL_LUMINANCE_ALPHA;
  796. mFormatType = GL_UNSIGNED_BYTE;
  797. break;
  798.   case 3:
  799. mFormatInternal = GL_RGB8;
  800. mFormatPrimary = GL_RGB;
  801. mFormatType = GL_UNSIGNED_BYTE;
  802. break;
  803.   case 4:
  804. mFormatInternal = GL_RGBA8;
  805. mFormatPrimary = GL_RGBA;
  806. mFormatType = GL_UNSIGNED_BYTE;
  807. break;
  808.   default:
  809. llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
  810. }
  811. }
  812. mCurrentDiscardLevel = discard_level;
  813. mDiscardLevelInAtlas = discard_level;
  814. mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ;
  815. mLastBindTime = sLastFrameTime;
  816. mGLTextureCreated = false ;
  817. glPixelStorei(GL_UNPACK_ROW_LENGTH, raw_image->getWidth());
  818. stop_glerror();
  819. if(mFormatSwapBytes)
  820. {
  821. glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
  822. stop_glerror();
  823. }
  824. return TRUE ;
  825. }
  826. void LLImageGL::postAddToAtlas()
  827. {
  828. if(mFormatSwapBytes)
  829. {
  830. glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
  831. stop_glerror();
  832. }
  833. glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  834. gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
  835. stop_glerror();
  836. }
  837. BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
  838. {
  839. if (!width || !height)
  840. {
  841. return TRUE;
  842. }
  843. if (mTexName == 0)
  844. {
  845. llwarns << "Setting subimage on image without GL texture" << llendl;
  846. return FALSE;
  847. }
  848. if (datap == NULL)
  849. {
  850. llwarns << "Setting subimage on image with NULL datap" << llendl;
  851. return FALSE;
  852. }
  853. // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture.
  854. if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height)
  855. {
  856. setImage(datap, FALSE);
  857. }
  858. else
  859. {
  860. if (mUseMipMaps)
  861. {
  862. dump();
  863. llerrs << "setSubImage called with mipmapped image (not supported)" << llendl;
  864. }
  865. llassert_always(mCurrentDiscardLevel == 0);
  866. llassert_always(x_pos >= 0 && y_pos >= 0);
  867. if (((x_pos + width) > getWidth()) || 
  868. (y_pos + height) > getHeight())
  869. {
  870. dump();
  871. llerrs << "Subimage not wholly in target image!" 
  872.    << " x_pos " << x_pos
  873.    << " y_pos " << y_pos
  874.    << " width " << width
  875.    << " height " << height
  876.    << " getWidth() " << getWidth()
  877.    << " getHeight() " << getHeight()
  878.    << llendl;
  879. }
  880. if ((x_pos + width) > data_width || 
  881. (y_pos + height) > data_height)
  882. {
  883. dump();
  884. llerrs << "Subimage not wholly in source image!" 
  885.    << " x_pos " << x_pos
  886.    << " y_pos " << y_pos
  887.    << " width " << width
  888.    << " height " << height
  889.    << " source_width " << data_width
  890.    << " source_height " << data_height
  891.    << llendl;
  892. }
  893. glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width);
  894. stop_glerror();
  895. if(mFormatSwapBytes)
  896. {
  897. glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
  898. stop_glerror();
  899. }
  900. datap += (y_pos * data_width + x_pos) * getComponents();
  901. // Update the GL texture
  902. BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName);
  903. if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl;
  904. stop_glerror();
  905. glTexSubImage2D(mTarget, 0, x_pos, y_pos, 
  906. width, height, mFormatPrimary, mFormatType, datap);
  907. gGL.getTexUnit(0)->disable();
  908. stop_glerror();
  909. if(mFormatSwapBytes)
  910. {
  911. glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
  912. stop_glerror();
  913. }
  914. glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  915. stop_glerror();
  916. mGLTextureCreated = true;
  917. }
  918. return TRUE;
  919. }
  920. BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update)
  921. {
  922. return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update);
  923. }
  924. // Copy sub image from frame buffer
  925. BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height)
  926. {
  927. if (gGL.getTexUnit(0)->bind(this, false, true))
  928. {
  929. //checkTexSize() ;
  930. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
  931. mGLTextureCreated = true;
  932. stop_glerror();
  933. return TRUE;
  934. }
  935. else
  936. {
  937. return FALSE;
  938. }
  939. }
  940. // static
  941. void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
  942. {
  943. glGenTextures(numTextures, (GLuint*)textures);
  944. }
  945. // static
  946. void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
  947. {
  948. for (S32 i = 0; i < numTextures; i++)
  949. {
  950. sDeadTextureList.push_back(textures[i]);
  951. }
  952. }
  953. // static
  954. void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
  955. {
  956. glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
  957. stop_glerror();
  958. }
  959. //create an empty GL texture: just create a texture name
  960. //the texture is assiciate with some image by calling glTexImage outside LLImageGL
  961. BOOL LLImageGL::createGLTexture()
  962. {
  963. if (gGLManager.mIsDisabled)
  964. {
  965. llwarns << "Trying to create a texture while GL is disabled!" << llendl;
  966. return FALSE;
  967. }
  968. mGLTextureCreated = false ; //do not save this texture when gl is destroyed.
  969. llassert(gGLManager.mInited);
  970. stop_glerror();
  971. if(mTexName)
  972. {
  973. glDeleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
  974. }
  975. glGenTextures(1, (GLuint*)&mTexName);
  976. stop_glerror();
  977. if (!mTexName)
  978. {
  979. llerrs << "LLImageGL::createGLTexture failed to make an empty texture" << llendl;
  980. }
  981. return TRUE ;
  982. }
  983. BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
  984. {
  985. if (gGLManager.mIsDisabled)
  986. {
  987. llwarns << "Trying to create a texture while GL is disabled!" << llendl;
  988. return FALSE;
  989. }
  990. mGLTextureCreated = false ;
  991. llassert(gGLManager.mInited);
  992. stop_glerror();
  993. if (discard_level < 0)
  994. {
  995. llassert(mCurrentDiscardLevel >= 0);
  996. discard_level = mCurrentDiscardLevel;
  997. }
  998. discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
  999. // Actual image width/height = raw image width/height * 2^discard_level
  1000. S32 raw_w = imageraw->getWidth() ;
  1001. S32 raw_h = imageraw->getHeight() ;
  1002. S32 w = raw_w << discard_level;
  1003. S32 h = raw_h << discard_level;
  1004. // setSize may call destroyGLTexture if the size does not match
  1005. setSize(w, h, imageraw->getComponents());
  1006. if( !mHasExplicitFormat )
  1007. {
  1008. switch (mComponents)
  1009. {
  1010.   case 1:
  1011. // Use luminance alpha (for fonts)
  1012. mFormatInternal = GL_LUMINANCE8;
  1013. mFormatPrimary = GL_LUMINANCE;
  1014. mFormatType = GL_UNSIGNED_BYTE;
  1015. break;
  1016.   case 2:
  1017. // Use luminance alpha (for fonts)
  1018. mFormatInternal = GL_LUMINANCE8_ALPHA8;
  1019. mFormatPrimary = GL_LUMINANCE_ALPHA;
  1020. mFormatType = GL_UNSIGNED_BYTE;
  1021. break;
  1022.   case 3:
  1023. mFormatInternal = GL_RGB8;
  1024. mFormatPrimary = GL_RGB;
  1025. mFormatType = GL_UNSIGNED_BYTE;
  1026. break;
  1027.   case 4:
  1028. mFormatInternal = GL_RGBA8;
  1029. mFormatPrimary = GL_RGBA;
  1030. mFormatType = GL_UNSIGNED_BYTE;
  1031. break;
  1032.   default:
  1033. llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
  1034. }
  1035. calcAlphaChannelOffsetAndStride() ;
  1036. }
  1037. if(!to_create) //not create a gl texture
  1038. {
  1039. destroyGLTexture();
  1040. mCurrentDiscardLevel = discard_level;
  1041. mLastBindTime = sLastFrameTime;
  1042. return TRUE ;
  1043. }
  1044. setCategory(category) ;
  1045.   const U8* rawdata = imageraw->getData();
  1046. return createGLTexture(discard_level, rawdata, FALSE, usename);
  1047. }
  1048. BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
  1049. {
  1050. llassert(data_in);
  1051. if (discard_level < 0)
  1052. {
  1053. llassert(mCurrentDiscardLevel >= 0);
  1054. discard_level = mCurrentDiscardLevel;
  1055. }
  1056. discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
  1057. if (mTexName != 0 && discard_level == mCurrentDiscardLevel)
  1058. {
  1059. // This will only be true if the size has not changed
  1060. setImage(data_in, data_hasmips);
  1061. return TRUE;
  1062. }
  1063. U32 old_name = mTexName;
  1064. //  S32 old_discard = mCurrentDiscardLevel;
  1065. if (usename != 0)
  1066. {
  1067. mTexName = usename;
  1068. }
  1069. else
  1070. {
  1071. LLImageGL::generateTextures(1, &mTexName);
  1072. stop_glerror();
  1073. {
  1074. llverify(gGL.getTexUnit(0)->bind(this));
  1075. glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
  1076. glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL,  mMaxDiscardLevel-discard_level);
  1077. }
  1078. }
  1079. if (!mTexName)
  1080. {
  1081. llerrs << "LLImageGL::createGLTexture failed to make texture" << llendl;
  1082. }
  1083. if (mUseMipMaps)
  1084. {
  1085. mAutoGenMips = gGLManager.mHasMipMapGeneration;
  1086. #if LL_DARWIN
  1087. // On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures.
  1088. if(gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA))
  1089. {
  1090. mAutoGenMips = FALSE;
  1091. }
  1092. #endif
  1093. }
  1094. mCurrentDiscardLevel = discard_level;
  1095. setImage(data_in, data_hasmips);
  1096. // Set texture options to our defaults.
  1097. gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps);
  1098. gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode);
  1099. gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption);
  1100. // things will break if we don't unbind after creation
  1101. gGL.getTexUnit(0)->unbind(mBindTarget);
  1102. stop_glerror();
  1103. if (old_name != 0)
  1104. {
  1105. sGlobalTextureMemoryInBytes -= mTextureMemory;
  1106. if(gAuditTexture)
  1107. {
  1108. decTextureCounter(mTextureMemory, mComponents, mCategory) ;
  1109. }
  1110. LLImageGL::deleteTextures(1, &old_name);
  1111. stop_glerror();
  1112. }
  1113. mTextureMemory = getMipBytes(discard_level);
  1114. sGlobalTextureMemoryInBytes += mTextureMemory;
  1115. mTexelsInGLTexture = getWidth() * getHeight() ;
  1116. if(gAuditTexture)
  1117. {
  1118. incTextureCounter(mTextureMemory, mComponents, mCategory) ;
  1119. }
  1120. // mark this as bound at this point, so we don't throw it out immediately
  1121. mLastBindTime = sLastFrameTime;
  1122. return TRUE;
  1123. }
  1124. BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const
  1125. {
  1126. llassert_always(sAllowReadBackRaw) ;
  1127. //llerrs << "should not call this function!" << llendl ;
  1128. if (discard_level < 0)
  1129. {
  1130. discard_level = mCurrentDiscardLevel;
  1131. }
  1132. if (mTexName == 0 || discard_level < mCurrentDiscardLevel || discard_level > mMaxDiscardLevel )
  1133. {
  1134. return FALSE;
  1135. }
  1136. S32 gl_discard = discard_level - mCurrentDiscardLevel;
  1137. //explicitly unbind texture 
  1138. gGL.getTexUnit(0)->unbind(mBindTarget);
  1139. llverify(gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName));
  1140. //debug code, leave it there commented.
  1141. //checkTexSize() ;
  1142. LLGLint glwidth = 0;
  1143. glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth);
  1144. if (glwidth == 0)
  1145. {
  1146. // No mip data smaller than current discard level
  1147. return FALSE;
  1148. }
  1149. S32 width = getWidth(discard_level);
  1150. S32 height = getHeight(discard_level);
  1151. S32 ncomponents = getComponents();
  1152. if (ncomponents == 0)
  1153. {
  1154. return FALSE;
  1155. }
  1156. if(width < glwidth)
  1157. {
  1158. llwarns << "texture size is smaller than it should be." << llendl ;
  1159. llwarns << "width: " << width << " glwidth: " << glwidth << " mWidth: " << mWidth << 
  1160. " mCurrentDiscardLevel: " << (S32)mCurrentDiscardLevel << " discard_level: " << (S32)discard_level << llendl ;
  1161. return FALSE ;
  1162. }
  1163. if (width <= 0 || width > 2048 || height <= 0 || height > 2048 || ncomponents < 1 || ncomponents > 4)
  1164. {
  1165. llerrs << llformat("LLImageGL::readBackRaw: bogus params: %d x %d x %d",width,height,ncomponents) << llendl;
  1166. }
  1167. LLGLint is_compressed = 0;
  1168. if (compressed_ok)
  1169. {
  1170. glGetTexLevelParameteriv(mTarget, is_compressed, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed);
  1171. }
  1172. //-----------------------------------------------------------------------------------------------
  1173. GLenum error ;
  1174. while((error = glGetError()) != GL_NO_ERROR)
  1175. {
  1176. llwarns << "GL Error happens before reading back texture. Error code: " << error << llendl ;
  1177. }
  1178. //-----------------------------------------------------------------------------------------------
  1179. if (is_compressed)
  1180. {
  1181. LLGLint glbytes;
  1182. glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes);
  1183. if(!imageraw->allocateDataSize(width, height, ncomponents, glbytes))
  1184. {
  1185. llwarns << "Memory allocation failed for reading back texture. Size is: " << glbytes << llendl ;
  1186. llwarns << "width: " << width << "height: " << height << "components: " << ncomponents << llendl ;
  1187. return FALSE ;
  1188. }
  1189. glGetCompressedTexImageARB(mTarget, gl_discard, (GLvoid*)(imageraw->getData()));
  1190. //stop_glerror();
  1191. }
  1192. else
  1193. {
  1194. if(!imageraw->allocateDataSize(width, height, ncomponents))
  1195. {
  1196. llwarns << "Memory allocation failed for reading back texture." << llendl ;
  1197. llwarns << "width: " << width << "height: " << height << "components: " << ncomponents << llendl ;
  1198. return FALSE ;
  1199. }
  1200. glGetTexImage(GL_TEXTURE_2D, gl_discard, mFormatPrimary, mFormatType, (GLvoid*)(imageraw->getData()));
  1201. //stop_glerror();
  1202. }
  1203. //-----------------------------------------------------------------------------------------------
  1204. if((error = glGetError()) != GL_NO_ERROR)
  1205. {
  1206. llwarns << "GL Error happens after reading back texture. Error code: " << error << llendl ;
  1207. imageraw->deleteData() ;
  1208. while((error = glGetError()) != GL_NO_ERROR)
  1209. {
  1210. llwarns << "GL Error happens after reading back texture. Error code: " << error << llendl ;
  1211. }
  1212. return FALSE ;
  1213. }
  1214. //-----------------------------------------------------------------------------------------------
  1215. return TRUE ;
  1216. }
  1217. void LLImageGL::deleteDeadTextures()
  1218. {
  1219. while (!sDeadTextureList.empty())
  1220. {
  1221. GLuint tex = sDeadTextureList.front();
  1222. sDeadTextureList.pop_front();
  1223. for (int i = 0; i < gGLManager.mNumTextureUnits; i++)
  1224. {
  1225. if (sCurrentBoundTextures[i] == tex)
  1226. {
  1227. gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE);
  1228. stop_glerror();
  1229. }
  1230. }
  1231. glDeleteTextures(1, &tex);
  1232. stop_glerror();
  1233. }
  1234. }
  1235. void LLImageGL::destroyGLTexture()
  1236. {
  1237. if (mTexName != 0)
  1238. {
  1239. if(mTextureMemory)
  1240. {
  1241. if(gAuditTexture)
  1242. {
  1243. decTextureCounter(mTextureMemory, mComponents, mCategory) ;
  1244. }
  1245. sGlobalTextureMemoryInBytes -= mTextureMemory;
  1246. mTextureMemory = 0;
  1247. }
  1248. LLImageGL::deleteTextures(1, &mTexName);
  1249. mTexName = 0;
  1250. mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
  1251. mGLTextureCreated = FALSE ;
  1252. }
  1253. }
  1254. //----------------------------------------------------------------------------
  1255. void LLImageGL::setAddressMode(LLTexUnit::eTextureAddressMode mode)
  1256. {
  1257. if (mAddressMode != mode)
  1258. {
  1259. mTexOptionsDirty = true;
  1260. mAddressMode = mode;
  1261. }
  1262. if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
  1263. {
  1264. gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureAddressMode(mode);
  1265. mTexOptionsDirty = false;
  1266. }
  1267. }
  1268. void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
  1269. {
  1270. if (mFilterOption != option)
  1271. {
  1272. mTexOptionsDirty = true;
  1273. mFilterOption = option;
  1274. }
  1275. if (mTexName != 0 && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName)
  1276. {
  1277. gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option);
  1278. mTexOptionsDirty = false;
  1279. stop_glerror();
  1280. }
  1281. }
  1282. BOOL LLImageGL::getIsResident(BOOL test_now)
  1283. {
  1284. if (test_now)
  1285. {
  1286. if (mTexName != 0)
  1287. {
  1288. glAreTexturesResident(1, (GLuint*)&mTexName, &mIsResident);
  1289. }
  1290. else
  1291. {
  1292. mIsResident = FALSE;
  1293. }
  1294. }
  1295. return mIsResident;
  1296. }
  1297. S32 LLImageGL::getHeight(S32 discard_level) const
  1298. {
  1299. if (discard_level < 0)
  1300. {
  1301. discard_level = mCurrentDiscardLevel;
  1302. }
  1303. S32 height = mHeight >> discard_level;
  1304. if (height < 1) height = 1;
  1305. return height;
  1306. }
  1307. S32 LLImageGL::getWidth(S32 discard_level) const
  1308. {
  1309. if (discard_level < 0)
  1310. {
  1311. discard_level = mCurrentDiscardLevel;
  1312. }
  1313. S32 width = mWidth >> discard_level;
  1314. if (width < 1) width = 1;
  1315. return width;
  1316. }
  1317. S32 LLImageGL::getBytes(S32 discard_level) const
  1318. {
  1319. if (discard_level < 0)
  1320. {
  1321. discard_level = mCurrentDiscardLevel;
  1322. }
  1323. S32 w = mWidth>>discard_level;
  1324. S32 h = mHeight>>discard_level;
  1325. if (w == 0) w = 1;
  1326. if (h == 0) h = 1;
  1327. return dataFormatBytes(mFormatPrimary, w, h);
  1328. }
  1329. S32 LLImageGL::getMipBytes(S32 discard_level) const
  1330. {
  1331. if (discard_level < 0)
  1332. {
  1333. discard_level = mCurrentDiscardLevel;
  1334. }
  1335. S32 w = mWidth>>discard_level;
  1336. S32 h = mHeight>>discard_level;
  1337. S32 res = dataFormatBytes(mFormatPrimary, w, h);
  1338. if (mUseMipMaps)
  1339. {
  1340. while (w > 1 && h > 1)
  1341. {
  1342. w >>= 1; if (w == 0) w = 1;
  1343. h >>= 1; if (h == 0) h = 1;
  1344. res += dataFormatBytes(mFormatPrimary, w, h);
  1345. }
  1346. }
  1347. return res;
  1348. }
  1349. BOOL LLImageGL::isJustBound() const
  1350. {
  1351. return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f);
  1352. }
  1353. BOOL LLImageGL::getBoundRecently() const
  1354. {
  1355. return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
  1356. }
  1357. void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
  1358. {
  1359. mTarget = target;
  1360. mBindTarget = bind_target;
  1361. }
  1362. const S8 INVALID_OFFSET = -99 ;
  1363. void LLImageGL::setNeedsAlphaAndPickMask(BOOL need_mask) 
  1364. {
  1365. if(mNeedsAlphaAndPickMask != need_mask)
  1366. {
  1367. mNeedsAlphaAndPickMask = need_mask;
  1368. if(mNeedsAlphaAndPickMask)
  1369. {
  1370. mAlphaOffset = 0 ;
  1371. }
  1372. else //do not need alpha mask
  1373. {
  1374. mAlphaOffset = INVALID_OFFSET ;
  1375. mIsMask = FALSE;
  1376. }
  1377. }
  1378. }
  1379. void LLImageGL::calcAlphaChannelOffsetAndStride()
  1380. {
  1381. if(mAlphaOffset == INVALID_OFFSET)//do not need alpha mask
  1382. {
  1383. return ;
  1384. }
  1385. mAlphaStride = -1 ;
  1386. switch (mFormatPrimary)
  1387. {
  1388. case GL_LUMINANCE:
  1389. case GL_ALPHA:
  1390. mAlphaStride = 1;
  1391. break;
  1392. case GL_LUMINANCE_ALPHA:
  1393. mAlphaStride = 2;
  1394. break;
  1395. case GL_RGB:
  1396. mNeedsAlphaAndPickMask = FALSE ;
  1397. mIsMask = FALSE;
  1398. return ; //no alpha channel.
  1399. case GL_RGBA:
  1400. mAlphaStride = 4;
  1401. break;
  1402. case GL_BGRA_EXT:
  1403. mAlphaStride = 4;
  1404. break;
  1405. default:
  1406. break;
  1407. }
  1408. mAlphaOffset = -1 ;
  1409. if (mFormatType == GL_UNSIGNED_BYTE)
  1410. {
  1411. mAlphaOffset = mAlphaStride - 1 ;
  1412. }
  1413. else if(is_little_endian())
  1414. {
  1415. if (mFormatType == GL_UNSIGNED_INT_8_8_8_8)
  1416. {
  1417. mAlphaOffset = 0 ;
  1418. }
  1419. else if (mFormatType == GL_UNSIGNED_INT_8_8_8_8_REV)
  1420. {
  1421. mAlphaOffset = 3 ;
  1422. }
  1423. }
  1424. else //big endian
  1425. {
  1426. if (mFormatType == GL_UNSIGNED_INT_8_8_8_8)
  1427. {
  1428. mAlphaOffset = 3 ;
  1429. }
  1430. else if (mFormatType == GL_UNSIGNED_INT_8_8_8_8_REV)
  1431. {
  1432. mAlphaOffset = 0 ;
  1433. }
  1434. }
  1435. if( mAlphaStride < 1 || //unsupported format
  1436. mAlphaOffset < 0 || //unsupported type
  1437. (mFormatPrimary == GL_BGRA_EXT && mFormatType != GL_UNSIGNED_BYTE)) //unknown situation
  1438. {
  1439. llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl;
  1440. mNeedsAlphaAndPickMask = FALSE ;
  1441. mIsMask = FALSE;
  1442. }
  1443. }
  1444. void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
  1445. {
  1446. if(!mNeedsAlphaAndPickMask)
  1447. {
  1448. return ;
  1449. }
  1450. U32 length = w * h;
  1451. const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset ;
  1452. S32 sample[16];
  1453. memset(sample, 0, sizeof(S32)*16);
  1454. for (U32 i = 0; i < length; i++)
  1455. {
  1456. ++sample[*current/16];
  1457. current += mAlphaStride ;
  1458. }
  1459. U32 total = 0;
  1460. for (U32 i = 4; i < 11; i++)
  1461. {
  1462. total += sample[i];
  1463. }
  1464. if (total > length/16)
  1465. {
  1466. mIsMask = FALSE;
  1467. }
  1468. else
  1469. {
  1470. mIsMask = TRUE;
  1471. }
  1472. }
  1473. //----------------------------------------------------------------------------
  1474. void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
  1475. {
  1476. if(!mNeedsAlphaAndPickMask)
  1477. {
  1478. return ;
  1479. }
  1480. delete [] mPickMask;
  1481. mPickMask = NULL;
  1482. mPickMaskWidth = mPickMaskHeight = 0;
  1483. if (mFormatType != GL_UNSIGNED_BYTE ||
  1484.     mFormatPrimary != GL_RGBA)
  1485. {
  1486. //cannot generate a pick mask for this texture
  1487. return;
  1488. }
  1489. U32 pick_width = width/2 + 1;
  1490. U32 pick_height = height/2 + 1;
  1491. U32 size = pick_width * pick_height;
  1492. size = (size + 7) / 8; // pixelcount-to-bits
  1493. mPickMask = new U8[size];
  1494. mPickMaskWidth = pick_width;
  1495. mPickMaskHeight = pick_height;
  1496. memset(mPickMask, 0, sizeof(U8) * size);
  1497. U32 pick_bit = 0;
  1498. for (S32 y = 0; y < height; y += 2)
  1499. {
  1500. for (S32 x = 0; x < width; x += 2)
  1501. {
  1502. U8 alpha = data_in[(y*width+x)*4+3];
  1503. if (alpha > 32)
  1504. {
  1505. U32 pick_idx = pick_bit/8;
  1506. U32 pick_offset = pick_bit%8;
  1507. llassert(pick_idx < size);
  1508. mPickMask[pick_idx] |= 1 << pick_offset;
  1509. }
  1510. ++pick_bit;
  1511. }
  1512. }
  1513. }
  1514. BOOL LLImageGL::getMask(const LLVector2 &tc)
  1515. {
  1516. BOOL res = TRUE;
  1517. if (mPickMask)
  1518. {
  1519. F32 u = tc.mV[0] - floorf(tc.mV[0]);
  1520. F32 v = tc.mV[1] - floorf(tc.mV[1]);
  1521. if (LL_UNLIKELY(u < 0.f || u > 1.f ||
  1522. v < 0.f || v > 1.f))
  1523. {
  1524. LL_WARNS_ONCE("render") << "Ugh, u/v out of range in image mask pick" << LL_ENDL;
  1525. u = v = 0.f;
  1526. llassert(false);
  1527. }
  1528. llassert(mPickMaskWidth > 0 && mPickMaskHeight > 0);
  1529. S32 x = llfloor(u * mPickMaskWidth);
  1530. S32 y = llfloor(v * mPickMaskHeight);
  1531. if (LL_UNLIKELY(x >= mPickMaskWidth))
  1532. {
  1533. LL_WARNS_ONCE("render") << "Ooh, width overrun on pick mask read, that coulda been bad." << LL_ENDL;
  1534. x = llmax(0, mPickMaskWidth-1);
  1535. }
  1536. if (LL_UNLIKELY(y >= mPickMaskHeight))
  1537. {
  1538. LL_WARNS_ONCE("render") << "Ooh, height overrun on pick mask read, that woulda been bad." << LL_ENDL;
  1539. y = llmax(0, mPickMaskHeight-1);
  1540. }
  1541. S32 idx = y*mPickMaskWidth+x;
  1542. S32 offset = idx%8;
  1543. res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE;
  1544. }
  1545. return res;
  1546. }
  1547. void LLImageGL::setCategory(S32 category) 
  1548. {
  1549. if(!gAuditTexture)
  1550. {
  1551. return ;
  1552. }
  1553. if(mCategory != category)
  1554. {
  1555. if(mCategory > -1)
  1556. {
  1557. sTextureMemByCategory[mCategory] -= mTextureMemory ;
  1558. }
  1559. if(category > -1 && category < sMaxCatagories)
  1560. {
  1561. sTextureMemByCategory[category] += mTextureMemory ;
  1562. mCategory = category;
  1563. }
  1564. else
  1565. {
  1566. mCategory = -1 ;
  1567. }
  1568. }
  1569. }
  1570. //for debug use 
  1571. //val is a "power of two" number
  1572. S32 LLImageGL::getTextureCounterIndex(U32 val) 
  1573. {
  1574. //index range is [0, MAX_TEXTURE_LOG_SIZE].
  1575. if(val < 2)
  1576. {
  1577. return 0 ;
  1578. }
  1579. else if(val >= (1 << MAX_TEXTURE_LOG_SIZE))
  1580. {
  1581. return MAX_TEXTURE_LOG_SIZE ;
  1582. }
  1583. else
  1584. {
  1585. S32 ret = 0 ;
  1586. while(val >>= 1)
  1587. {
  1588. ++ret;
  1589. }
  1590. return ret ;
  1591. }
  1592. }
  1593. //static
  1594. void LLImageGL::incTextureCounter(U32 val, S32 ncomponents, S32 category) 
  1595. {
  1596. sTextureLoadedCounter[getTextureCounterIndex(val)]++ ;
  1597. sTextureMemByCategory[category] += (S32)val * ncomponents ;
  1598. }
  1599. //static
  1600. void LLImageGL::decTextureCounter(U32 val, S32 ncomponents, S32 category) 
  1601. {
  1602. sTextureLoadedCounter[getTextureCounterIndex(val)]-- ;
  1603. sTextureMemByCategory[category] += (S32)val * ncomponents ;
  1604. }
  1605. void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size)
  1606. {
  1607. sCurTexSizeBar = index ;
  1608. if(set_pick_size)
  1609. {
  1610. sCurTexPickSize = (1 << index) ;
  1611. }
  1612. else
  1613. {
  1614. sCurTexPickSize = -1 ;
  1615. }
  1616. }
  1617. void LLImageGL::resetCurTexSizebar()
  1618. {
  1619. sCurTexSizeBar = -1 ;
  1620. sCurTexPickSize = -1 ;
  1621. }
  1622. //----------------------------------------------------------------------------
  1623. //----------------------------------------------------------------------------
  1624. // Manual Mip Generation
  1625. /*
  1626. S32 width = getWidth(discard_level);
  1627. S32 height = getHeight(discard_level);
  1628. S32 w = width, h = height;
  1629. S32 nummips = 1;
  1630. while (w > 4 && h > 4)
  1631. {
  1632. w >>= 1; h >>= 1;
  1633. nummips++;
  1634. }
  1635. stop_glerror();
  1636. w = width, h = height;
  1637. const U8* prev_mip_data = 0;
  1638. const U8* cur_mip_data = 0;
  1639. for (int m=0; m<nummips; m++)
  1640. {
  1641. if (m==0)
  1642. {
  1643. cur_mip_data = rawdata;
  1644. }
  1645. else
  1646. {
  1647. S32 bytes = w * h * mComponents;
  1648. U8* new_data = new U8[bytes];
  1649. LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
  1650. cur_mip_data = new_data;
  1651. }
  1652. llassert(w > 0 && h > 0 && cur_mip_data);
  1653. U8 test = cur_mip_data[w*h*mComponents-1];
  1654. {
  1655. LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
  1656. stop_glerror();
  1657. }
  1658. if (prev_mip_data && prev_mip_data != rawdata)
  1659. {
  1660. delete prev_mip_data;
  1661. }
  1662. prev_mip_data = cur_mip_data;
  1663. w >>= 1;
  1664. h >>= 1;
  1665. }
  1666. if (prev_mip_data && prev_mip_data != rawdata)
  1667. {
  1668. delete prev_mip_data;
  1669. }
  1670. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
  1671. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,  nummips);
  1672. */