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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llvertexbuffer.cpp
  3.  * @brief LLVertexBuffer implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2003&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2003-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. #include "linden_common.h"
  33. #include <boost/static_assert.hpp>
  34. #include "llvertexbuffer.h"
  35. // #include "llrender.h"
  36. #include "llglheaders.h"
  37. #include "llmemtype.h"
  38. #include "llrender.h"
  39. //============================================================================
  40. //static
  41. LLVBOPool LLVertexBuffer::sStreamVBOPool;
  42. LLVBOPool LLVertexBuffer::sDynamicVBOPool;
  43. LLVBOPool LLVertexBuffer::sStreamIBOPool;
  44. LLVBOPool LLVertexBuffer::sDynamicIBOPool;
  45. U32 LLVertexBuffer::sBindCount = 0;
  46. U32 LLVertexBuffer::sSetCount = 0;
  47. S32 LLVertexBuffer::sCount = 0;
  48. S32 LLVertexBuffer::sGLCount = 0;
  49. S32 LLVertexBuffer::sMappedCount = 0;
  50. BOOL LLVertexBuffer::sEnableVBOs = TRUE;
  51. U32 LLVertexBuffer::sGLRenderBuffer = 0;
  52. U32 LLVertexBuffer::sGLRenderIndices = 0;
  53. U32 LLVertexBuffer::sLastMask = 0;
  54. BOOL LLVertexBuffer::sVBOActive = FALSE;
  55. BOOL LLVertexBuffer::sIBOActive = FALSE;
  56. U32 LLVertexBuffer::sAllocatedBytes = 0;
  57. BOOL LLVertexBuffer::sMapped = FALSE;
  58. std::vector<U32> LLVertexBuffer::sDeleteList;
  59. S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] =
  60. {
  61. sizeof(LLVector3), // TYPE_VERTEX,
  62. sizeof(LLVector3), // TYPE_NORMAL,
  63. sizeof(LLVector2), // TYPE_TEXCOORD0,
  64. sizeof(LLVector2), // TYPE_TEXCOORD1,
  65. sizeof(LLVector2), // TYPE_TEXCOORD2,
  66. sizeof(LLVector2), // TYPE_TEXCOORD3,
  67. sizeof(LLColor4U), // TYPE_COLOR,
  68. sizeof(LLVector3), // TYPE_BINORMAL,
  69. sizeof(F32),    // TYPE_WEIGHT,
  70. sizeof(LLVector4), // TYPE_CLOTHWEIGHT,
  71. };
  72. U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = 
  73. {
  74. GL_TRIANGLES,
  75. GL_TRIANGLE_STRIP,
  76. GL_TRIANGLE_FAN,
  77. GL_POINTS,
  78. GL_LINES,
  79. GL_LINE_STRIP,
  80. GL_QUADS,
  81. GL_LINE_LOOP,
  82. };
  83. //static
  84. void LLVertexBuffer::setupClientArrays(U32 data_mask)
  85. {
  86. /*if (LLGLImmediate::sStarted)
  87. {
  88. llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl;
  89. }*/
  90. if (sLastMask != data_mask)
  91. {
  92. U32 mask[] =
  93. {
  94. MAP_VERTEX,
  95. MAP_NORMAL,
  96. MAP_TEXCOORD0,
  97. MAP_COLOR,
  98. };
  99. GLenum array[] =
  100. {
  101. GL_VERTEX_ARRAY,
  102. GL_NORMAL_ARRAY,
  103. GL_TEXTURE_COORD_ARRAY,
  104. GL_COLOR_ARRAY,
  105. };
  106. BOOL error = FALSE;
  107. for (U32 i = 0; i < 4; ++i)
  108. {
  109. if (sLastMask & mask[i])
  110. { //was enabled
  111. if (!(data_mask & mask[i]) && i > 0)
  112. { //needs to be disabled
  113. glDisableClientState(array[i]);
  114. }
  115. else if (gDebugGL)
  116. { //needs to be enabled, make sure it was (DEBUG TEMPORARY)
  117. if (i > 0 && !glIsEnabled(array[i]))
  118. {
  119. if (gDebugSession)
  120. {
  121. error = TRUE;
  122. gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
  123. }
  124. else
  125. {
  126. llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
  127. }
  128. }
  129. }
  130. }
  131. else 
  132. { //was disabled
  133. if (data_mask & mask[i])
  134. { //needs to be enabled
  135. glEnableClientState(array[i]);
  136. }
  137. else if (gDebugGL && glIsEnabled(array[i]))
  138. { //needs to be disabled, make sure it was (DEBUG TEMPORARY)
  139. if (gDebugSession)
  140. {
  141. error = TRUE;
  142. gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
  143. }
  144. else
  145. {
  146. llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
  147. }
  148. }
  149. }
  150. }
  151. if (error)
  152. {
  153. ll_fail("LLVertexBuffer::setupClientArrays failed");
  154. }
  155. U32 map_tc[] = 
  156. {
  157. MAP_TEXCOORD1,
  158. MAP_TEXCOORD2,
  159. MAP_TEXCOORD3
  160. };
  161. for (U32 i = 0; i < 3; i++)
  162. {
  163. if (sLastMask & map_tc[i])
  164. {
  165. if (!(data_mask & map_tc[i]))
  166. {
  167. glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
  168. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  169. glClientActiveTextureARB(GL_TEXTURE0_ARB);
  170. }
  171. }
  172. else if (data_mask & map_tc[i])
  173. {
  174. glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
  175. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  176. glClientActiveTextureARB(GL_TEXTURE0_ARB);
  177. }
  178. }
  179. if (sLastMask & MAP_BINORMAL)
  180. {
  181. if (!(data_mask & MAP_BINORMAL))
  182. {
  183. glClientActiveTextureARB(GL_TEXTURE2_ARB);
  184. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  185. glClientActiveTextureARB(GL_TEXTURE0_ARB);
  186. }
  187. }
  188. else if (data_mask & MAP_BINORMAL)
  189. {
  190. glClientActiveTextureARB(GL_TEXTURE2_ARB);
  191. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  192. glClientActiveTextureARB(GL_TEXTURE0_ARB);
  193. }
  194. sLastMask = data_mask;
  195. }
  196. }
  197. void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
  198. {
  199. llassert(mRequestedNumVerts >= 0);
  200. if (start >= (U32) mRequestedNumVerts ||
  201.     end >= (U32) mRequestedNumVerts)
  202. {
  203. llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl;
  204. }
  205. llassert(mRequestedNumIndices >= 0);
  206. if (indices_offset >= (U32) mRequestedNumIndices ||
  207.     indices_offset + count > (U32) mRequestedNumIndices)
  208. {
  209. llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
  210. }
  211. if (mGLIndices != sGLRenderIndices)
  212. {
  213. llerrs << "Wrong index buffer bound." << llendl;
  214. }
  215. if (mGLBuffer != sGLRenderBuffer)
  216. {
  217. llerrs << "Wrong vertex buffer bound." << llendl;
  218. }
  219. if (mode >= LLRender::NUM_MODES)
  220. {
  221. llerrs << "Invalid draw mode: " << mode << llendl;
  222. return;
  223. }
  224. stop_glerror();
  225. glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, 
  226. ((U16*) getIndicesPointer()) + indices_offset);
  227. stop_glerror();
  228. }
  229. void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
  230. {
  231. llassert(mRequestedNumIndices >= 0);
  232. if (indices_offset >= (U32) mRequestedNumIndices ||
  233.     indices_offset + count > (U32) mRequestedNumIndices)
  234. {
  235. llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl;
  236. }
  237. if (mGLIndices != sGLRenderIndices)
  238. {
  239. llerrs << "Wrong index buffer bound." << llendl;
  240. }
  241. if (mGLBuffer != sGLRenderBuffer)
  242. {
  243. llerrs << "Wrong vertex buffer bound." << llendl;
  244. }
  245. if (mode >= LLRender::NUM_MODES)
  246. {
  247. llerrs << "Invalid draw mode: " << mode << llendl;
  248. return;
  249. }
  250. stop_glerror();
  251. glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT,
  252. ((U16*) getIndicesPointer()) + indices_offset);
  253. stop_glerror();
  254. }
  255. void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
  256. {
  257. llassert(mRequestedNumVerts >= 0);
  258. if (first >= (U32) mRequestedNumVerts ||
  259.     first + count > (U32) mRequestedNumVerts)
  260. {
  261. llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl;
  262. }
  263. if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive)
  264. {
  265. llerrs << "Wrong vertex buffer bound." << llendl;
  266. }
  267. if (mode >= LLRender::NUM_MODES)
  268. {
  269. llerrs << "Invalid draw mode: " << mode << llendl;
  270. return;
  271. }
  272. stop_glerror();
  273. glDrawArrays(sGLMode[mode], first, count);
  274. stop_glerror();
  275. }
  276. //static
  277. void LLVertexBuffer::initClass(bool use_vbo)
  278. {
  279. sEnableVBOs = use_vbo;
  280. LLGLNamePool::registerPool(&sDynamicVBOPool);
  281. LLGLNamePool::registerPool(&sDynamicIBOPool);
  282. LLGLNamePool::registerPool(&sStreamVBOPool);
  283. LLGLNamePool::registerPool(&sStreamIBOPool);
  284. }
  285. //static 
  286. void LLVertexBuffer::unbind()
  287. {
  288. if (sVBOActive)
  289. {
  290. glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
  291. sVBOActive = FALSE;
  292. }
  293. if (sIBOActive)
  294. {
  295. glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
  296. sIBOActive = FALSE;
  297. }
  298. sGLRenderBuffer = 0;
  299. sGLRenderIndices = 0;
  300. setupClientArrays(0);
  301. }
  302. //static
  303. void LLVertexBuffer::cleanupClass()
  304. {
  305. LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS);
  306. unbind();
  307. clientCopy(); // deletes GL buffers
  308. }
  309. void LLVertexBuffer::clientCopy(F64 max_time)
  310. {
  311. if (!sDeleteList.empty())
  312. {
  313. glDeleteBuffersARB(sDeleteList.size(), (GLuint*) &(sDeleteList[0]));
  314. sDeleteList.clear();
  315. }
  316. }
  317. //----------------------------------------------------------------------------
  318. LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
  319. LLRefCount(),
  320. mNumVerts(0),
  321. mNumIndices(0),
  322. mRequestedNumVerts(-1),
  323. mRequestedNumIndices(-1),
  324. mUsage(usage),
  325. mGLBuffer(0),
  326. mGLIndices(0), 
  327. mMappedData(NULL),
  328. mMappedIndexData(NULL), mLocked(FALSE),
  329. mFinal(FALSE),
  330. mFilthy(FALSE),
  331. mEmpty(TRUE),
  332. mResized(FALSE),
  333. mDynamicSize(FALSE)
  334. {
  335. LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR);
  336. if (!sEnableVBOs)
  337. {
  338. mUsage = 0 ; 
  339. }
  340. S32 stride = calcStride(typemask, mOffsets);
  341. mTypeMask = typemask;
  342. mStride = stride;
  343. sCount++;
  344. }
  345. //static
  346. S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
  347. {
  348. S32 stride = 0;
  349. for (S32 i=0; i<TYPE_MAX; i++)
  350. {
  351. U32 mask = 1<<i;
  352. if (typemask & mask)
  353. {
  354. if (offsets)
  355. {
  356. offsets[i] = stride;
  357. }
  358. stride += sTypeOffsets[i];
  359. }
  360. }
  361. return stride;
  362. }
  363. // protected, use unref()
  364. //virtual
  365. LLVertexBuffer::~LLVertexBuffer()
  366. {
  367. LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR);
  368. destroyGLBuffer();
  369. destroyGLIndices();
  370. sCount--;
  371. };
  372. //----------------------------------------------------------------------------
  373. void LLVertexBuffer::genBuffer()
  374. {
  375. if (mUsage == GL_STREAM_DRAW_ARB)
  376. {
  377. mGLBuffer = sStreamVBOPool.allocate();
  378. }
  379. else if (mUsage == GL_DYNAMIC_DRAW_ARB)
  380. {
  381. mGLBuffer = sDynamicVBOPool.allocate();
  382. }
  383. else
  384. {
  385. BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint));
  386. glGenBuffersARB(1, (GLuint*)&mGLBuffer);
  387. }
  388. sGLCount++;
  389. }
  390. void LLVertexBuffer::genIndices()
  391. {
  392. if (mUsage == GL_STREAM_DRAW_ARB)
  393. {
  394. mGLIndices = sStreamIBOPool.allocate();
  395. }
  396. else if (mUsage == GL_DYNAMIC_DRAW_ARB)
  397. {
  398. mGLIndices = sDynamicIBOPool.allocate();
  399. }
  400. else
  401. {
  402. BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint));
  403. glGenBuffersARB(1, (GLuint*)&mGLIndices);
  404. }
  405. sGLCount++;
  406. }
  407. void LLVertexBuffer::releaseBuffer()
  408. {
  409. if (mUsage == GL_STREAM_DRAW_ARB)
  410. {
  411. sStreamVBOPool.release(mGLBuffer);
  412. }
  413. else if (mUsage == GL_DYNAMIC_DRAW_ARB)
  414. {
  415. sDynamicVBOPool.release(mGLBuffer);
  416. }
  417. else
  418. {
  419. sDeleteList.push_back(mGLBuffer);
  420. }
  421. sGLCount--;
  422. }
  423. void LLVertexBuffer::releaseIndices()
  424. {
  425. if (mUsage == GL_STREAM_DRAW_ARB)
  426. {
  427. sStreamIBOPool.release(mGLIndices);
  428. }
  429. else if (mUsage == GL_DYNAMIC_DRAW_ARB)
  430. {
  431. sDynamicIBOPool.release(mGLIndices);
  432. }
  433. else
  434. {
  435. sDeleteList.push_back(mGLIndices);
  436. }
  437. sGLCount--;
  438. }
  439. void LLVertexBuffer::createGLBuffer()
  440. {
  441. LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES);
  442. U32 size = getSize();
  443. if (mGLBuffer)
  444. {
  445. destroyGLBuffer();
  446. }
  447. if (size == 0)
  448. {
  449. return;
  450. }
  451. mEmpty = TRUE;
  452. if (useVBOs())
  453. {
  454. mMappedData = NULL;
  455. genBuffer();
  456. mResized = TRUE;
  457. }
  458. else
  459. {
  460. static int gl_buffer_idx = 0;
  461. mGLBuffer = ++gl_buffer_idx;
  462. mMappedData = new U8[size];
  463. memset(mMappedData, 0, size);
  464. }
  465. }
  466. void LLVertexBuffer::createGLIndices()
  467. {
  468. LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES);
  469. U32 size = getIndicesSize();
  470. if (mGLIndices)
  471. {
  472. destroyGLIndices();
  473. }
  474. if (size == 0)
  475. {
  476. return;
  477. }
  478. mEmpty = TRUE;
  479. if (useVBOs())
  480. {
  481. mMappedIndexData = NULL;
  482. genIndices();
  483. mResized = TRUE;
  484. }
  485. else
  486. {
  487. mMappedIndexData = new U8[size];
  488. memset(mMappedIndexData, 0, size);
  489. static int gl_buffer_idx = 0;
  490. mGLIndices = ++gl_buffer_idx;
  491. }
  492. }
  493. void LLVertexBuffer::destroyGLBuffer()
  494. {
  495. LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER);
  496. if (mGLBuffer)
  497. {
  498. if (useVBOs())
  499. {
  500. if (mMappedData || mMappedIndexData)
  501. {
  502. llerrs << "Vertex buffer destroyed while mapped!" << llendl;
  503. }
  504. releaseBuffer();
  505. }
  506. else
  507. {
  508. delete [] mMappedData;
  509. mMappedData = NULL;
  510. mEmpty = TRUE;
  511. }
  512. sAllocatedBytes -= getSize();
  513. }
  514. mGLBuffer = 0;
  515. unbind();
  516. }
  517. void LLVertexBuffer::destroyGLIndices()
  518. {
  519. LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_INDICES);
  520. if (mGLIndices)
  521. {
  522. if (useVBOs())
  523. {
  524. if (mMappedData || mMappedIndexData)
  525. {
  526. llerrs << "Vertex buffer destroyed while mapped." << llendl;
  527. }
  528. releaseIndices();
  529. }
  530. else
  531. {
  532. delete [] mMappedIndexData;
  533. mMappedIndexData = NULL;
  534. mEmpty = TRUE;
  535. }
  536. sAllocatedBytes -= getIndicesSize();
  537. }
  538. mGLIndices = 0;
  539. unbind();
  540. }
  541. void LLVertexBuffer::updateNumVerts(S32 nverts)
  542. {
  543. LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_VERTS);
  544. llassert(nverts >= 0);
  545. if (nverts >= 65535)
  546. {
  547. llwarns << "Vertex buffer overflow!" << llendl;
  548. nverts = 65535;
  549. }
  550. mRequestedNumVerts = nverts;
  551. if (!mDynamicSize)
  552. {
  553. mNumVerts = nverts;
  554. }
  555. else if (mUsage == GL_STATIC_DRAW_ARB ||
  556. nverts > mNumVerts ||
  557. nverts < mNumVerts/2)
  558. {
  559. if (mUsage != GL_STATIC_DRAW_ARB && nverts + nverts/4 <= 65535)
  560. {
  561. nverts += nverts/4;
  562. }
  563. mNumVerts = nverts;
  564. }
  565. }
  566. void LLVertexBuffer::updateNumIndices(S32 nindices)
  567. {
  568. LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_INDICES);
  569. llassert(nindices >= 0);
  570. mRequestedNumIndices = nindices;
  571. if (!mDynamicSize)
  572. {
  573. mNumIndices = nindices;
  574. }
  575. else if (mUsage == GL_STATIC_DRAW_ARB ||
  576. nindices > mNumIndices ||
  577. nindices < mNumIndices/2)
  578. {
  579. if (mUsage != GL_STATIC_DRAW_ARB)
  580. {
  581. nindices += nindices/4;
  582. }
  583. mNumIndices = nindices;
  584. }
  585. }
  586. void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
  587. {
  588. LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
  589. updateNumVerts(nverts);
  590. updateNumIndices(nindices);
  591. if (mMappedData)
  592. {
  593. llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl;
  594. }
  595. if (create && (nverts || nindices))
  596. {
  597. createGLBuffer();
  598. createGLIndices();
  599. }
  600. sAllocatedBytes += getSize() + getIndicesSize();
  601. }
  602. void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
  603. {
  604. llassert(newnverts >= 0);
  605. llassert(newnindices >= 0);
  606. mRequestedNumVerts = newnverts;
  607. mRequestedNumIndices = newnindices;
  608. LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER);
  609. mDynamicSize = TRUE;
  610. if (mUsage == GL_STATIC_DRAW_ARB)
  611. { //always delete/allocate static buffers on resize
  612. destroyGLBuffer();
  613. destroyGLIndices();
  614. allocateBuffer(newnverts, newnindices, TRUE);
  615. mFinal = FALSE;
  616. }
  617. else if (newnverts > mNumVerts || newnindices > mNumIndices ||
  618.  newnverts < mNumVerts/2 || newnindices < mNumIndices/2)
  619. {
  620. sAllocatedBytes -= getSize() + getIndicesSize();
  621. S32 oldsize = getSize();
  622. S32 old_index_size = getIndicesSize();
  623. updateNumVerts(newnverts);
  624. updateNumIndices(newnindices);
  625. S32 newsize = getSize();
  626. S32 new_index_size = getIndicesSize();
  627. sAllocatedBytes += newsize + new_index_size;
  628. if (newsize)
  629. {
  630. if (!mGLBuffer)
  631. { //no buffer exists, create a new one
  632. createGLBuffer();
  633. }
  634. else
  635. {
  636. //delete old buffer, keep GL buffer for now
  637. if (!useVBOs())
  638. {
  639. U8* old = mMappedData;
  640. mMappedData = new U8[newsize];
  641. if (old)
  642. {
  643. memcpy(mMappedData, old, llmin(newsize, oldsize));
  644. if (newsize > oldsize)
  645. {
  646. memset(mMappedData+oldsize, 0, newsize-oldsize);
  647. }
  648. delete [] old;
  649. }
  650. else
  651. {
  652. memset(mMappedData, 0, newsize);
  653. mEmpty = TRUE;
  654. }
  655. }
  656. mResized = TRUE;
  657. }
  658. }
  659. else if (mGLBuffer)
  660. {
  661. destroyGLBuffer();
  662. }
  663. if (new_index_size)
  664. {
  665. if (!mGLIndices)
  666. {
  667. createGLIndices();
  668. }
  669. else
  670. {
  671. if (!useVBOs())
  672. {
  673. //delete old buffer, keep GL buffer for now
  674. U8* old = mMappedIndexData;
  675. mMappedIndexData = new U8[new_index_size];
  676. if (old)
  677. {
  678. memcpy(mMappedIndexData, old, llmin(new_index_size, old_index_size));
  679. if (new_index_size > old_index_size)
  680. {
  681. memset(mMappedIndexData+old_index_size, 0, new_index_size - old_index_size);
  682. }
  683. delete [] old;
  684. }
  685. else
  686. {
  687. memset(mMappedIndexData, 0, new_index_size);
  688. mEmpty = TRUE;
  689. }
  690. }
  691. mResized = TRUE;
  692. }
  693. }
  694. else if (mGLIndices)
  695. {
  696. destroyGLIndices();
  697. }
  698. }
  699. if (mResized && useVBOs())
  700. {
  701. setBuffer(0);
  702. }
  703. }
  704. BOOL LLVertexBuffer::useVBOs() const
  705. {
  706. //it's generally ineffective to use VBO for things that are streaming on apple
  707. #if LL_DARWIN
  708. if (!mUsage || mUsage == GL_STREAM_DRAW_ARB)
  709. {
  710. return FALSE;
  711. }
  712. #else
  713. if (!mUsage)
  714. {
  715. return FALSE;
  716. }
  717. #endif
  718. return sEnableVBOs;
  719. }
  720. //----------------------------------------------------------------------------
  721. // Map for data access
  722. U8* LLVertexBuffer::mapBuffer(S32 access)
  723. {
  724. LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
  725. if (mFinal)
  726. {
  727. llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
  728. }
  729. if (!useVBOs() && !mMappedData && !mMappedIndexData)
  730. {
  731. llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
  732. }
  733. if (!mLocked && useVBOs())
  734. {
  735. {
  736. LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
  737. setBuffer(0);
  738. mLocked = TRUE;
  739. stop_glerror();
  740. mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
  741. stop_glerror();
  742. }
  743. {
  744. LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
  745. mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
  746. stop_glerror();
  747. }
  748. if (!mMappedData)
  749. {
  750. //--------------------
  751. //print out more debug info before crash
  752. llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
  753. GLint size ;
  754. glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
  755. llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
  756. //--------------------
  757. GLint buff;
  758. glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
  759. if ((GLuint)buff != mGLBuffer)
  760. {
  761. llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
  762. }
  763. llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
  764. }
  765. if (!mMappedIndexData)
  766. {
  767. GLint buff;
  768. glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
  769. if ((GLuint)buff != mGLIndices)
  770. {
  771. llerrs << "Invalid GL index buffer bound: " << buff << llendl;
  772. }
  773. llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
  774. }
  775. sMappedCount++;
  776. }
  777. return mMappedData;
  778. }
  779. void LLVertexBuffer::unmapBuffer()
  780. {
  781. LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
  782. if (mMappedData || mMappedIndexData)
  783. {
  784. if (useVBOs() && mLocked)
  785. {
  786. stop_glerror();
  787. glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
  788. stop_glerror();
  789. glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
  790. stop_glerror();
  791. /*if (!sMapped)
  792. {
  793. llerrs << "Redundantly unmapped VBO!" << llendl;
  794. }
  795. sMapped = FALSE;*/
  796. sMappedCount--;
  797. if (mUsage == GL_STATIC_DRAW_ARB)
  798. { //static draw buffers can only be mapped a single time
  799. //throw out client data (we won't be using it again)
  800. mEmpty = TRUE;
  801. mFinal = TRUE;
  802. }
  803. else
  804. {
  805. mEmpty = FALSE;
  806. }
  807. mMappedIndexData = NULL;
  808. mMappedData = NULL;
  809. mLocked = FALSE;
  810. }
  811. }
  812. }
  813. //----------------------------------------------------------------------------
  814. template <class T,S32 type> struct VertexBufferStrider
  815. {
  816. typedef LLStrider<T> strider_t;
  817. static bool get(LLVertexBuffer& vbo, 
  818. strider_t& strider, 
  819. S32 index)
  820. {
  821. if (vbo.mapBuffer() == NULL)
  822. {
  823. llwarns << "mapBuffer failed!" << llendl;
  824. return FALSE;
  825. }
  826. if (type == LLVertexBuffer::TYPE_INDEX)
  827. {
  828. S32 stride = sizeof(T);
  829. strider = (T*)(vbo.getMappedIndices() + index*stride);
  830. strider.setStride(0);
  831. return TRUE;
  832. }
  833. else if (vbo.hasDataType(type))
  834. {
  835. S32 stride = vbo.getStride();
  836. strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride);
  837. strider.setStride(stride);
  838. return TRUE;
  839. }
  840. else
  841. {
  842. llerrs << "VertexBufferStrider could not find valid vertex data." << llendl;
  843. }
  844. return FALSE;
  845. }
  846. };
  847. bool LLVertexBuffer::getVertexStrider(LLStrider<LLVector3>& strider, S32 index)
  848. {
  849. return VertexBufferStrider<LLVector3,TYPE_VERTEX>::get(*this, strider, index);
  850. }
  851. bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index)
  852. {
  853. return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index);
  854. }
  855. bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index)
  856. {
  857. return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index);
  858. }
  859. bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index)
  860. {
  861. return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index);
  862. }
  863. /*bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index)
  864. {
  865. return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index);
  866. }
  867. bool LLVertexBuffer::getTexCoord3Strider(LLStrider<LLVector2>& strider, S32 index)
  868. {
  869. return VertexBufferStrider<LLVector2,TYPE_TEXCOORD3>::get(*this, strider, index);
  870. }*/
  871. bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index)
  872. {
  873. return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index);
  874. }
  875. bool LLVertexBuffer::getBinormalStrider(LLStrider<LLVector3>& strider, S32 index)
  876. {
  877. return VertexBufferStrider<LLVector3,TYPE_BINORMAL>::get(*this, strider, index);
  878. }
  879. bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index)
  880. {
  881. return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index);
  882. }
  883. bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index)
  884. {
  885. return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index);
  886. }
  887. bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index)
  888. {
  889. return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index);
  890. }
  891. void LLVertexBuffer::setStride(S32 type, S32 new_stride)
  892. {
  893. LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_STRIDE);
  894. if (mNumVerts)
  895. {
  896. llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl;
  897. }
  898. // This code assumes that setStride() will only be called once per VBO per type.
  899. S32 delta = new_stride - sTypeOffsets[type];
  900. for (S32 i=type+1; i<TYPE_MAX; i++)
  901. {
  902. if (mTypeMask & (1<<i))
  903. {
  904. mOffsets[i] += delta;
  905. }
  906. }
  907. mStride += delta;
  908. }
  909. //----------------------------------------------------------------------------
  910. // Set for rendering
  911. void LLVertexBuffer::setBuffer(U32 data_mask)
  912. {
  913. LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
  914. //set up pointers if the data mask is different ...
  915. BOOL setup = (sLastMask != data_mask);
  916. if (useVBOs())
  917. {
  918. if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))
  919. {
  920. /*if (sMapped)
  921. {
  922. llerrs << "VBO bound while another VBO mapped!" << llendl;
  923. }*/
  924. stop_glerror();
  925. glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
  926. stop_glerror();
  927. sBindCount++;
  928. sVBOActive = TRUE;
  929. setup = TRUE; // ... or the bound buffer changed
  930. }
  931. if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))
  932. {
  933. /*if (sMapped)
  934. {
  935. llerrs << "VBO bound while another VBO mapped!" << llendl;
  936. }*/
  937. stop_glerror();
  938. glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
  939. stop_glerror();
  940. sBindCount++;
  941. sIBOActive = TRUE;
  942. }
  943. BOOL error = FALSE;
  944. if (gDebugGL)
  945. {
  946. GLint buff;
  947. glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
  948. if ((GLuint)buff != mGLBuffer)
  949. {
  950. if (gDebugSession)
  951. {
  952. error = TRUE;
  953. gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
  954. }
  955. else
  956. {
  957. llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
  958. }
  959. }
  960. if (mGLIndices)
  961. {
  962. glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
  963. if ((GLuint)buff != mGLIndices)
  964. {
  965. if (gDebugSession)
  966. {
  967. error = TRUE;
  968. gFailLog << "Invalid GL index buffer bound: " << buff <<  std::endl;
  969. }
  970. else
  971. {
  972. llerrs << "Invalid GL index buffer bound: " << buff << llendl;
  973. }
  974. }
  975. }
  976. }
  977. if (mResized)
  978. {
  979. if (gDebugGL)
  980. {
  981. GLint buff;
  982. glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
  983. if ((GLuint)buff != mGLBuffer)
  984. {
  985. if (gDebugSession)
  986. {
  987. error = TRUE;
  988. gFailLog << "Invalid GL vertex buffer bound: " << std::endl;
  989. }
  990. else
  991. {
  992. llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
  993. }
  994. }
  995. if (mGLIndices != 0)
  996. {
  997. glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
  998. if ((GLuint)buff != mGLIndices)
  999. {
  1000. if (gDebugSession)
  1001. {
  1002. error = TRUE;
  1003. gFailLog << "Invalid GL index buffer bound: "<< std::endl;
  1004. }
  1005. else
  1006. {
  1007. llerrs << "Invalid GL index buffer bound: " << buff << llendl;
  1008. }
  1009. }
  1010. }
  1011. }
  1012. if (mGLBuffer)
  1013. {
  1014. stop_glerror();
  1015. glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage);
  1016. stop_glerror();
  1017. }
  1018. if (mGLIndices)
  1019. {
  1020. stop_glerror();
  1021. glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage);
  1022. stop_glerror();
  1023. }
  1024. mEmpty = TRUE;
  1025. mResized = FALSE;
  1026. if (data_mask != 0)
  1027. {
  1028. if (gDebugSession)
  1029. {
  1030. error = TRUE;
  1031. gFailLog << "Buffer set for rendering before being filled after resize." << std::endl;
  1032. }
  1033. else
  1034. {
  1035. llerrs << "Buffer set for rendering before being filled after resize." << llendl;
  1036. }
  1037. }
  1038. }
  1039. if (error)
  1040. {
  1041. ll_fail("LLVertexBuffer::mapBuffer failed");
  1042. }
  1043. unmapBuffer();
  1044. }
  1045. else
  1046. {
  1047. if (mGLBuffer)
  1048. {
  1049. if (sEnableVBOs && sVBOActive)
  1050. {
  1051. glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
  1052. sBindCount++;
  1053. sVBOActive = FALSE;
  1054. setup = TRUE; // ... or a VBO is deactivated
  1055. }
  1056. if (sGLRenderBuffer != mGLBuffer)
  1057. {
  1058. setup = TRUE; // ... or a client memory pointer changed
  1059. }
  1060. }
  1061. if (sEnableVBOs && mGLIndices && sIBOActive)
  1062. {
  1063. /*if (sMapped)
  1064. {
  1065. llerrs << "VBO unbound while potentially mapped!" << llendl;
  1066. }*/
  1067. glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
  1068. sBindCount++;
  1069. sIBOActive = FALSE;
  1070. }
  1071. }
  1072. setupClientArrays(data_mask);
  1073. if (mGLIndices)
  1074. {
  1075. sGLRenderIndices = mGLIndices;
  1076. }
  1077. if (mGLBuffer)
  1078. {
  1079. sGLRenderBuffer = mGLBuffer;
  1080. if (data_mask && setup)
  1081. {
  1082. setupVertexBuffer(data_mask); // subclass specific setup (virtual function)
  1083. sSetCount++;
  1084. }
  1085. }
  1086. }
  1087. // virtual (default)
  1088. void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
  1089. {
  1090. LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
  1091. stop_glerror();
  1092. U8* base = useVBOs() ? NULL : mMappedData;
  1093. S32 stride = mStride;
  1094. if ((data_mask & mTypeMask) != data_mask)
  1095. {
  1096. llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
  1097. }
  1098. if (data_mask & MAP_NORMAL)
  1099. {
  1100. glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL]));
  1101. }
  1102. if (data_mask & MAP_TEXCOORD3)
  1103. {
  1104. glClientActiveTextureARB(GL_TEXTURE3_ARB);
  1105. glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD3]));
  1106. glClientActiveTextureARB(GL_TEXTURE0_ARB);
  1107. }
  1108. if (data_mask & MAP_TEXCOORD2)
  1109. {
  1110. glClientActiveTextureARB(GL_TEXTURE2_ARB);
  1111. glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
  1112. glClientActiveTextureARB(GL_TEXTURE0_ARB);
  1113. }
  1114. if (data_mask & MAP_TEXCOORD1)
  1115. {
  1116. glClientActiveTextureARB(GL_TEXTURE1_ARB);
  1117. glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD1]));
  1118. glClientActiveTextureARB(GL_TEXTURE0_ARB);
  1119. }
  1120. if (data_mask & MAP_BINORMAL)
  1121. {
  1122. glClientActiveTextureARB(GL_TEXTURE2_ARB);
  1123. glTexCoordPointer(3,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_BINORMAL]));
  1124. glClientActiveTextureARB(GL_TEXTURE0_ARB);
  1125. }
  1126. if (data_mask & MAP_TEXCOORD0)
  1127. {
  1128. glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD0]));
  1129. }
  1130. if (data_mask & MAP_COLOR)
  1131. {
  1132. glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR]));
  1133. }
  1134. if (data_mask & MAP_WEIGHT)
  1135. {
  1136. glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT]));
  1137. }
  1138. if (data_mask & MAP_CLOTHWEIGHT)
  1139. {
  1140. glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE,  stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
  1141. }
  1142. if (data_mask & MAP_VERTEX)
  1143. {
  1144. glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0));
  1145. }
  1146. llglassertok();
  1147. }
  1148. void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count)
  1149. {
  1150. // TODO: use GL_APPLE_flush_buffer_range here
  1151. /*if (useVBOs() && !mFilthy)
  1152. {
  1153. }*/
  1154. }