diff options
Diffstat (limited to 'indra')
43 files changed, 851 insertions, 468 deletions
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 27cdfcaa4e..a869c74189 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -28,8 +28,8 @@ #define LL_LLVERSIONVIEWER_H const S32 LL_VERSION_MAJOR = 3; -const S32 LL_VERSION_MINOR = 2; -const S32 LL_VERSION_PATCH = 9; +const S32 LL_VERSION_MINOR = 3; +const S32 LL_VERSION_PATCH = 0; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 0c6cf1dfae..761fc171c4 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2078,6 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mFaceMask = 0x0; mDetail = detail; mSculptLevel = -2; + mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims mIsMeshAssetLoaded = FALSE; mLODScaleBias.setVec(1,1,1); mHullPoints = NULL; @@ -3144,6 +3145,8 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, { F32 area = sculptGetSurfaceArea(); + mSurfaceArea = area; + const F32 SCULPT_MAX_AREA = 384.f; if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index afd1ec5eed..76cf9de613 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -963,6 +963,7 @@ public: S32 getNumFaces() const; S32 getNumVolumeFaces() const { return mVolumeFaces.size(); } F32 getDetail() const { return mDetail; } + F32 getSurfaceArea() const { return mSurfaceArea; } const LLVolumeParams& getParams() const { return mParams; } LLVolumeParams getCopyOfParams() const { return mParams; } const LLProfile& getProfile() const { return *mProfilep; } @@ -1065,6 +1066,7 @@ public: BOOL mUnique; F32 mDetail; S32 mSculptLevel; + F32 mSurfaceArea; //unscaled surface area BOOL mIsMeshAssetLoaded; LLVolumeParams mParams; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 03a9884c2b..b0ddacbb05 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -997,7 +997,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction) const glh::matrix4f& mat = gGL.getModelviewMatrix(); mat.mult_matrix_dir(dir); - mSpotDirection.set(direction); + mSpotDirection.set(dir.v); } } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 50b0c1a7dd..79d1beb33a 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -148,7 +148,7 @@ U32 wpo2(U32 i) return r;
}
-U8* LLVBOPool::allocate(U32& name, U32 size)
+volatile U8* LLVBOPool::allocate(U32& name, U32 size)
{
llassert(nhpo2(size) == size);
@@ -159,20 +159,25 @@ U8* LLVBOPool::allocate(U32& name, U32 size) mFreeList.resize(i+1);
}
- U8* ret = NULL;
+ volatile U8* ret = NULL;
if (mFreeList[i].empty())
{
//make a new buffer
glGenBuffersARB(1, &name);
glBindBufferARB(mType, name);
- glBufferDataARB(mType, size, 0, mUsage);
LLVertexBuffer::sAllocatedBytes += size;
- if (LLVertexBuffer::sDisableVBOMapping)
+ if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
+ glBufferDataARB(mType, size, 0, mUsage);
ret = (U8*) ll_aligned_malloc_16(size);
}
+ else
+ { //always use a true hint of static draw when allocating non-client-backed buffers
+ glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
+ }
+
glBindBufferARB(mType, 0);
}
else
@@ -188,7 +193,7 @@ U8* LLVBOPool::allocate(U32& name, U32 size) return ret;
}
-void LLVBOPool::release(U32 name, U8* buffer, U32 size)
+void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
{
llassert(nhpo2(size) == size);
@@ -202,8 +207,15 @@ void LLVBOPool::release(U32 name, U8* buffer, U32 size) sBytesPooled += size;
+ if (!LLVertexBuffer::sDisableVBOMapping && mUsage == GL_DYNAMIC_DRAW_ARB)
+ {
+ glDeleteBuffersARB(1, &rec.mGLName);
+ }
+ else
+ {
mFreeList[i].push_back(rec);
}
+}
void LLVBOPool::cleanup()
{
@@ -221,7 +233,7 @@ void LLVBOPool::cleanup() if (r.mClientData)
{
- ll_aligned_free_16(r.mClientData);
+ ll_aligned_free_16((void*) r.mClientData);
}
l.pop_front();
@@ -276,7 +288,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) if (LLGLSLShader::sNoFixedFunction)
{
for (U32 i = 0; i < TYPE_MAX; ++i)
- {
+ {
S32 loc = i;
U32 mask = 1 << i;
@@ -299,14 +311,14 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) }
else
{
-
- GLenum array[] =
- {
- GL_VERTEX_ARRAY,
- GL_NORMAL_ARRAY,
- GL_TEXTURE_COORD_ARRAY,
- GL_COLOR_ARRAY,
- };
+
+ GLenum array[] =
+ {
+ GL_VERTEX_ARRAY,
+ GL_NORMAL_ARRAY,
+ GL_TEXTURE_COORD_ARRAY,
+ GL_COLOR_ARRAY,
+ };
GLenum mask[] =
{
@@ -318,94 +330,94 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) - for (U32 i = 0; i < 4; ++i)
- {
- if (sLastMask & mask[i])
- { //was enabled
+ for (U32 i = 0; i < 4; ++i)
+ {
+ if (sLastMask & mask[i])
+ { //was enabled
if (!(data_mask & mask[i]))
- { //needs to be disabled
- glDisableClientState(array[i]);
- }
- else if (gDebugGL)
+ { //needs to be disabled
+ glDisableClientState(array[i]);
+ }
+ else if (gDebugGL)
{ //needs to be enabled, make sure it was (DEBUG)
if (!glIsEnabled(array[i]))
- {
+ {
+ if (gDebugSession)
+ {
+ error = TRUE;
+ gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
+ }
+ else
+ {
+ llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ }
+ }
+ }
+ }
+ else
+ { //was disabled
+ if (data_mask & mask[i])
+ { //needs to be enabled
+ glEnableClientState(array[i]);
+ }
+ else if (gDebugGL && glIsEnabled(array[i]))
+ { //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession)
{
error = TRUE;
- gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
+ gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
}
else
{
- llerrs << "Bad client state! " << array[i] << " disabled." << llendl;
+ llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
}
}
}
}
- else
- { //was disabled
- if (data_mask & mask[i])
- { //needs to be enabled
- glEnableClientState(array[i]);
- }
- else if (gDebugGL && glIsEnabled(array[i]))
- { //needs to be disabled, make sure it was (DEBUG TEMPORARY)
- if (gDebugSession)
- {
- error = TRUE;
- gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
- }
- else
- {
- llerrs << "Bad client state! " << array[i] << " enabled." << llendl;
- }
- }
- }
- }
-
- U32 map_tc[] =
- {
- MAP_TEXCOORD1,
- MAP_TEXCOORD2,
- MAP_TEXCOORD3
- };
+
+ U32 map_tc[] =
+ {
+ MAP_TEXCOORD1,
+ MAP_TEXCOORD2,
+ MAP_TEXCOORD3
+ };
- for (U32 i = 0; i < 3; i++)
- {
- if (sLastMask & map_tc[i])
+ for (U32 i = 0; i < 3; i++)
{
- if (!(data_mask & map_tc[i]))
+ if (sLastMask & map_tc[i])
+ {
+ if (!(data_mask & map_tc[i]))
{ //disable
+ glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ }
+ else if (data_mask & map_tc[i])
+ {
glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
}
- else if (data_mask & map_tc[i])
+
+ if (sLastMask & MAP_BINORMAL)
{
- glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ if (!(data_mask & MAP_BINORMAL))
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
}
- }
-
- if (sLastMask & MAP_BINORMAL)
- {
- if (!(data_mask & MAP_BINORMAL))
+ else if (data_mask & MAP_BINORMAL)
{
glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
}
- else if (data_mask & MAP_BINORMAL)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- }
-
+
sLastMask = data_mask;
}
}
@@ -441,8 +453,8 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con }
else
{
- glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
- glNormalPointer(GL_FLOAT, 0, norm[0].mV);
+ glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
+ glNormalPointer(GL_FLOAT, 0, norm[0].mV);
}
glDrawArrays(sGLMode[mode], 0, count);
@@ -529,14 +541,14 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of llerrs << "Bad texture index found in vertex data stream." << llendl;
}
}
+ }
}
}
-}
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
{
validateRange(start, end, count, indices_offset);
-
+ mMappable = FALSE;
gGL.syncMatrices();
llassert(mNumVerts >= 0);
@@ -551,15 +563,15 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi }
else
{
- if (mGLIndices != sGLRenderIndices)
- {
- llerrs << "Wrong index buffer bound." << llendl;
- }
+ if (mGLIndices != sGLRenderIndices)
+ {
+ llerrs << "Wrong index buffer bound." << llendl;
+ }
- if (mGLBuffer != sGLRenderBuffer)
- {
- llerrs << "Wrong vertex buffer bound." << llendl;
- }
+ if (mGLBuffer != sGLRenderBuffer)
+ {
+ llerrs << "Wrong vertex buffer bound." << llendl;
+ }
}
if (gDebugGL && !mGLArray && useVBOs())
@@ -591,7 +603,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-
+ mMappable = FALSE;
gGL.syncMatrices();
llassert(mNumIndices >= 0);
@@ -610,15 +622,15 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const }
else
{
- if (mGLIndices != sGLRenderIndices)
- {
- llerrs << "Wrong index buffer bound." << llendl;
- }
+ if (mGLIndices != sGLRenderIndices)
+ {
+ llerrs << "Wrong index buffer bound." << llendl;
+ }
- if (mGLBuffer != sGLRenderBuffer)
- {
- llerrs << "Wrong vertex buffer bound." << llendl;
- }
+ if (mGLBuffer != sGLRenderBuffer)
+ {
+ llerrs << "Wrong vertex buffer bound." << llendl;
+ }
}
if (mode >= LLRender::NUM_MODES)
@@ -637,7 +649,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
{
llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
-
+ mMappable = FALSE;
gGL.syncMatrices();
llassert(mNumVerts >= 0);
@@ -658,9 +670,9 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const {
BOOL uvb = useVBOs();
if (mGLBuffer != sGLRenderBuffer || uvb != sVBOActive)
- {
- llerrs << "Wrong vertex buffer bound." << llendl;
- }
+ {
+ llerrs << "Wrong vertex buffer bound." << llendl;
+ }
}
if (mode >= LLRender::NUM_MODES)
@@ -682,7 +694,7 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
if(!sPrivatePoolp)
- {
+ {
sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ;
}
@@ -788,9 +800,26 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : if (mUsage && mUsage != GL_STREAM_DRAW_ARB)
{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default
+ if (sDisableVBOMapping)
+ { //always use stream draw if VBO mapping is disabled
+ mUsage = GL_STREAM_DRAW_ARB;
+ }
+ else
+ {
mUsage = GL_DYNAMIC_DRAW_ARB;
}
+ }
+
+ if (mUsage == GL_DYNAMIC_DRAW_ARB && !sDisableVBOMapping)
+ {
+ mMappable = TRUE;
+ }
+ else
+ {
+ mMappable = FALSE;
+ }
+
//zero out offsets
for (U32 i = 0; i < TYPE_MAX; i++)
{
@@ -1001,7 +1030,7 @@ void LLVertexBuffer::createGLBuffer(U32 size) void LLVertexBuffer::createGLIndices(U32 size)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES);
-
+
if (mGLIndices)
{
destroyGLIndices();
@@ -1043,7 +1072,7 @@ void LLVertexBuffer::destroyGLBuffer() }
else
{
- FREE_MEM(sPrivatePoolp, mMappedData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedData) ;
mMappedData = NULL;
mEmpty = TRUE;
}
@@ -1064,7 +1093,7 @@ void LLVertexBuffer::destroyGLIndices() }
else
{
- FREE_MEM(sPrivatePoolp, mMappedIndexData) ;
+ FREE_MEM(sPrivatePoolp, (void*) mMappedIndexData) ;
mMappedIndexData = NULL;
mEmpty = TRUE;
}
@@ -1093,8 +1122,8 @@ void LLVertexBuffer::updateNumVerts(S32 nverts) createGLBuffer(needed_size);
}
- mNumVerts = nverts;
- }
+ mNumVerts = nverts;
+}
void LLVertexBuffer::updateNumIndices(S32 nindices)
{
@@ -1107,15 +1136,15 @@ void LLVertexBuffer::updateNumIndices(S32 nindices) if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2)
{
createGLIndices(needed_size);
- }
-
- mNumIndices = nindices;
}
+ mNumIndices = nindices;
+}
+
void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER);
-
+
stop_glerror();
if (nverts < 0 || nindices < 0 ||
@@ -1133,21 +1162,21 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) flush();
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
- {
+ {
#if GL_ARB_vertex_array_object
glGenVertexArrays(1, &mGLArray);
#endif
setupVertexArray();
}
}
- }
-
+}
+
static LLFastTimer::DeclareTimer FTM_SETUP_VERTEX_ARRAY("Setup VAO");
void LLVertexBuffer::setupVertexArray()
{
if (!mGLArray)
-{
+ {
return;
}
@@ -1173,7 +1202,7 @@ void LLVertexBuffer::setupVertexArray() 4, //TYPE_CLOTHWEIGHT,
1, //TYPE_TEXTURE_INDEX
};
-
+
U32 attrib_type[] =
{
GL_FLOAT, //TYPE_VERTEX,
@@ -1190,7 +1219,7 @@ void LLVertexBuffer::setupVertexArray() GL_FLOAT, //TYPE_CLOTHWEIGHT,
GL_FLOAT, //TYPE_TEXTURE_INDEX
};
-
+
U32 attrib_normalized[] =
{
GL_FALSE, //TYPE_VERTEX,
@@ -1217,21 +1246,21 @@ void LLVertexBuffer::setupVertexArray() {
glEnableVertexAttribArrayARB(i);
glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]);
- }
- else
- {
+ }
+ else
+ {
glDisableVertexAttribArrayARB(i);
- }
- }
+ }
+ }
//draw a dummy triangle to set index array pointer
//glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, NULL);
unbind();
- }
+}
void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices)
- {
+{
llassert(newnverts >= 0);
llassert(newnindices >= 0);
@@ -1239,9 +1268,9 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) updateNumVerts(newnverts);
updateNumIndices(newnindices);
-
+
if (useVBOs())
- {
+ {
flush();
if (mGLArray)
@@ -1283,8 +1312,11 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count) return true;
}
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER_RANGE("VBO Map Range");
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER("VBO Map");
+
// Map for data access
-U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
+volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)
{
bindGLBuffer(true);
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
@@ -1299,7 +1331,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (useVBOs())
{
- if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (count == -1)
{
@@ -1324,7 +1356,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (!mapped)
{
//not already mapped, map new region
- MappedRegion region(type, !sDisableVBOMapping && map_range ? -1 : index, count);
+ MappedRegion region(type, mMappable && map_range ? -1 : index, count);
mMappedVertexRegions.push_back(region);
}
}
@@ -1341,19 +1373,20 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran sMappedCount++;
stop_glerror();
- if(sDisableVBOMapping)
+ if(!mMappable)
{
map_range = false;
}
else
{
- U8* src = NULL;
+ volatile U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(FTM_VBO_MAP_BUFFER_RANGE);
S32 offset = mOffsets[type] + sTypeSize[type]*index;
S32 length = (sTypeSize[type]*count+0xF) & ~0xF;
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, offset, length,
@@ -1377,6 +1410,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran }
}
+ LLFastTimer t(FTM_VBO_MAP_BUFFER);
src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1404,7 +1438,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran llassert(src != NULL);
- mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src);
+ mMappedData = LL_NEXT_ALIGNED_ADDRESS<volatile U8>(src);
mAlignedOffset = mMappedData - src;
stop_glerror();
@@ -1417,7 +1451,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran //check the availability of memory
LLMemory::logMemoryInfo(TRUE) ;
- if(!sDisableVBOMapping)
+ if(mMappable)
{
//--------------------
//print out more debug info before crash
@@ -1449,7 +1483,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran map_range = false;
}
- if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
+ if (map_range && gGLManager.mHasMapBufferRange && mMappable)
{
return mMappedData;
}
@@ -1459,7 +1493,11 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran }
}
-U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
+
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX_RANGE("IBO Map Range");
+static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");
+
+volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
bindGLIndices(true);
@@ -1474,7 +1512,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (useVBOs())
{
- if (sDisableVBOMapping || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
+ if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange)
{
if (count == -1)
{
@@ -1496,7 +1534,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (!mapped)
{
//not already mapped, map new region
- MappedRegion region(TYPE_INDEX, !sDisableVBOMapping && map_range ? -1 : index, count);
+ MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count);
mMappedIndexRegions.push_back(region);
}
}
@@ -1525,19 +1563,20 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) }
}
- if(sDisableVBOMapping)
+ if(!mMappable)
{
map_range = false;
}
else
{
- U8* src = NULL;
+ volatile U8* src = NULL;
waitFence();
if (gGLManager.mHasMapBufferRange)
{
if (map_range)
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(FTM_VBO_MAP_INDEX_RANGE);
S32 offset = sizeof(U16)*index;
S32 length = sizeof(U16)*count;
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length,
@@ -1549,6 +1588,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) else
{
#ifdef GL_ARB_map_buffer_range
+ LLFastTimer t(FTM_VBO_MAP_INDEX);
src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, sizeof(U16)*mNumIndices,
GL_MAP_WRITE_BIT |
GL_MAP_FLUSH_EXPLICIT_BIT);
@@ -1570,6 +1610,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) }
else
{
+ LLFastTimer t(FTM_VBO_MAP_INDEX);
map_range = false;
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
}
@@ -1588,7 +1629,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) log_glerror();
LLMemory::logMemoryInfo(TRUE) ;
- if(!sDisableVBOMapping)
+ if(mMappable)
{
GLint buff;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
@@ -1610,7 +1651,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) map_range = false;
}
- if (map_range && gGLManager.mHasMapBufferRange && !sDisableVBOMapping)
+ if (map_range && gGLManager.mHasMapBufferRange && mMappable)
{
return mMappedIndexData;
}
@@ -1620,6 +1661,13 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) }
}
+static LLFastTimer::DeclareTimer FTM_VBO_UNMAP("VBO Unmap");
+static LLFastTimer::DeclareTimer FTM_VBO_FLUSH_RANGE("Flush VBO Range");
+
+
+static LLFastTimer::DeclareTimer FTM_IBO_UNMAP("IBO Unmap");
+static LLFastTimer::DeclareTimer FTM_IBO_FLUSH_RANGE("Flush IBO Range");
+
void LLVertexBuffer::unmapBuffer()
{
LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
@@ -1632,10 +1680,11 @@ void LLVertexBuffer::unmapBuffer() if (mMappedData && mVertexLocked)
{
+ LLFastTimer t(FTM_VBO_UNMAP);
bindGLBuffer(true);
updated_all = mIndexLocked; //both vertex and index buffers done updating
- if(sDisableVBOMapping)
+ if(!mMappable)
{
if (!mMappedVertexRegions.empty())
{
@@ -1645,7 +1694,7 @@ void LLVertexBuffer::unmapBuffer() const MappedRegion& region = mMappedVertexRegions[i];
S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0;
S32 length = sTypeSize[region.mType]*region.mCount;
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, mMappedData+offset);
+ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);
stop_glerror();
}
@@ -1654,7 +1703,7 @@ void LLVertexBuffer::unmapBuffer() else
{
stop_glerror();
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
+ glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (U8*) mMappedData);
stop_glerror();
}
}
@@ -1672,6 +1721,7 @@ void LLVertexBuffer::unmapBuffer() S32 length = sTypeSize[region.mType]*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
+ LLFastTimer t(FTM_VBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -1699,8 +1749,9 @@ void LLVertexBuffer::unmapBuffer() if (mMappedIndexData && mIndexLocked)
{
+ LLFastTimer t(FTM_IBO_UNMAP);
bindGLIndices();
- if(sDisableVBOMapping)
+ if(!mMappable)
{
if (!mMappedIndexRegions.empty())
{
@@ -1709,7 +1760,7 @@ void LLVertexBuffer::unmapBuffer() const MappedRegion& region = mMappedIndexRegions[i];
S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0;
S32 length = sizeof(U16)*region.mCount;
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, mMappedIndexData+offset);
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedIndexData+offset);
stop_glerror();
}
@@ -1718,7 +1769,7 @@ void LLVertexBuffer::unmapBuffer() else
{
stop_glerror();
- glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
+ glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (U8*) mMappedIndexData);
stop_glerror();
}
}
@@ -1735,6 +1786,7 @@ void LLVertexBuffer::unmapBuffer() S32 length = sizeof(U16)*region.mCount;
if (gGLManager.mHasMapBufferRange)
{
+ LLFastTimer t(FTM_IBO_FLUSH_RANGE);
#ifdef GL_ARB_map_buffer_range
glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
#endif
@@ -1764,9 +1816,9 @@ void LLVertexBuffer::unmapBuffer() if(updated_all)
{
- mEmpty = FALSE;
- }
+ mEmpty = FALSE;
}
+}
//----------------------------------------------------------------------------
@@ -1779,7 +1831,7 @@ template <class T,S32 type> struct VertexBufferStrider {
if (type == LLVertexBuffer::TYPE_INDEX)
{
- U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
+ volatile U8* ptr = vbo.mapIndexBuffer(index, count, map_range);
if (ptr == NULL)
{
@@ -1795,7 +1847,7 @@ template <class T,S32 type> struct VertexBufferStrider {
S32 stride = LLVertexBuffer::sTypeSize[type];
- U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
+ volatile U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range);
if (ptr == NULL)
{
@@ -1874,7 +1926,7 @@ bool LLVertexBuffer::bindGLArray() {
if (mGLArray && sGLRenderArray != mGLArray)
{
-{
+ {
LLFastTimer t(FTM_BIND_GL_ARRAY);
#if GL_ARB_vertex_array_object
glBindVertexArray(mGLArray);
@@ -1895,22 +1947,22 @@ bool LLVertexBuffer::bindGLArray() static LLFastTimer::DeclareTimer FTM_BIND_GL_BUFFER("Bind Buffer");
bool LLVertexBuffer::bindGLBuffer(bool force_bind)
- {
+{
bindGLArray();
bool ret = false;
if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))
- {
+ {
LLFastTimer t(FTM_BIND_GL_BUFFER);
- /*if (sMapped)
- {
- llerrs << "VBO bound while another VBO mapped!" << llendl;
- }*/
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
+ /*if (sMapped)
+ {
+ llerrs << "VBO bound while another VBO mapped!" << llendl;
+ }*/
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);
sGLRenderBuffer = mGLBuffer;
- sBindCount++;
- sVBOActive = TRUE;
+ sBindCount++;
+ sVBOActive = TRUE;
if (mGLArray)
{
@@ -1922,7 +1974,7 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind) }
return ret;
- }
+}
static LLFastTimer::DeclareTimer FTM_BIND_GL_INDICES("Bind Indices");
@@ -1932,23 +1984,23 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind) bool ret = false;
if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive))))
- {
+ {
LLFastTimer t(FTM_BIND_GL_INDICES);
- /*if (sMapped)
- {
- llerrs << "VBO bound while another VBO mapped!" << llendl;
- }*/
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
+ /*if (sMapped)
+ {
+ llerrs << "VBO bound while another VBO mapped!" << llendl;
+ }*/
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices);
sGLRenderIndices = mGLIndices;
- stop_glerror();
- sBindCount++;
- sIBOActive = TRUE;
+ stop_glerror();
+ sBindCount++;
+ sIBOActive = TRUE;
ret = true;
}
return ret;
- }
-
+}
+
void LLVertexBuffer::flush()
{
if (useVBOs())
@@ -1973,85 +2025,85 @@ void LLVertexBuffer::setBuffer(U32 data_mask) {
U32 required_mask = 0;
for (U32 i = 0; i < LLVertexBuffer::TYPE_TEXTURE_INDEX; ++i)
- {
- if (shader->getAttribLocation(i) > -1)
{
+ if (shader->getAttribLocation(i) > -1)
+ {
U32 required = 1 << i;
if ((data_mask & required) == 0)
- {
+ {
llwarns << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << llendl;
}
required_mask |= required;
}
- }
+ }
if ((data_mask & required_mask) != required_mask)
- {
+ {
llerrs << "Shader consumption mismatches data provision." << llendl;
}
- }
- }
+ }
+ }
if (useVBOs())
- {
+ {
if (mGLArray)
- {
+ {
bindGLArray();
setup = FALSE; //do NOT perform pointer setup if using VAO
- }
- else
- {
+ }
+ else
+ {
if (bindGLBuffer())
{
setup = TRUE;
- }
+ }
if (bindGLIndices())
{
setup = TRUE;
- }
}
+ }
BOOL error = FALSE;
if (gDebugGL && !mGLArray)
{
- GLint buff;
- glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
- if ((GLuint)buff != mGLBuffer)
+ GLint buff;
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
+ if ((GLuint)buff != mGLBuffer)
+ {
+ if (gDebugSession)
{
- if (gDebugSession)
- {
- error = TRUE;
+ error = TRUE;
gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
- }
- else
- {
- llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
- }
}
+ else
+ {
+ llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+ }
+ }
if (mGLIndices)
+ {
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+ if ((GLuint)buff != mGLIndices)
{
- glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
- if ((GLuint)buff != mGLIndices)
+ if (gDebugSession)
{
- if (gDebugSession)
- {
- error = TRUE;
+ error = TRUE;
gFailLog << "Invalid GL index buffer bound: " << buff << std::endl;
- }
- else
- {
- llerrs << "Invalid GL index buffer bound: " << buff << llendl;
- }
+ }
+ else
+ {
+ llerrs << "Invalid GL index buffer bound: " << buff << llendl;
}
}
}
+ }
-
- }
- else
- {
+
+ }
+ else
+ {
if (sGLRenderArray)
{
#if GL_ARB_vertex_array_object
@@ -2060,7 +2112,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) sGLRenderArray = 0;
sGLRenderIndices = 0;
sIBOActive = FALSE;
- }
+ }
if (mGLBuffer)
{
@@ -2081,10 +2133,10 @@ void LLVertexBuffer::setBuffer(U32 data_mask) {
if (sIBOActive)
{
- glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- sBindCount++;
- sIBOActive = FALSE;
- }
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
+ sBindCount++;
+ sIBOActive = FALSE;
+ }
sGLRenderIndices = mGLIndices;
}
@@ -2092,9 +2144,9 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (!mGLArray)
{
- setupClientArrays(data_mask);
+ setupClientArrays(data_mask);
}
-
+
if (mGLBuffer)
{
if (data_mask && setup)
@@ -2110,7 +2162,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) {
LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER);
stop_glerror();
- U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
+ volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
/*if ((data_mask & mTypeMask) != data_mask)
{
@@ -2190,7 +2242,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) S32 loc = TYPE_TEXTURE_INDEX;
void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
- }
+ }
if (data_mask & MAP_VERTEX)
{
S32 loc = TYPE_VERTEX;
@@ -2200,56 +2252,56 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) }
else
{
- if (data_mask & MAP_NORMAL)
- {
- glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
- }
- if (data_mask & MAP_TEXCOORD3)
- {
- glClientActiveTextureARB(GL_TEXTURE3_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD2)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD1)
- {
- glClientActiveTextureARB(GL_TEXTURE1_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_BINORMAL)
- {
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
- }
- if (data_mask & MAP_TEXCOORD0)
- {
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
- }
- if (data_mask & MAP_COLOR)
- {
- glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
- }
+ if (data_mask & MAP_NORMAL)
+ {
+ glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+ }
+ if (data_mask & MAP_TEXCOORD3)
+ {
+ glClientActiveTextureARB(GL_TEXTURE3_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD2)
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD1)
+ {
+ glClientActiveTextureARB(GL_TEXTURE1_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_BINORMAL)
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
+ if (data_mask & MAP_TEXCOORD0)
+ {
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+ }
+ if (data_mask & MAP_COLOR)
+ {
+ glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR]));
+ }
if (data_mask & MAP_VERTEX)
- {
+ {
glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
}
}
llglassertok();
- }
+}
LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
- {
+{
llassert(mType == LLVertexBuffer::TYPE_INDEX ||
mType < LLVertexBuffer::TYPE_TEXTURE_INDEX);
- }
+}
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 3e6f6a959a..e1cbfd3b61 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -60,10 +60,10 @@ public: U32 mType; //size MUST be a power of 2 - U8* allocate(U32& name, U32 size); + volatile U8* allocate(U32& name, U32 size); //size MUST be the size provided to allocate that returned the given name - void release(U32 name, U8* buffer, U32 size); + void release(U32 name, volatile U8* buffer, U32 size); //destroy all records in mFreeList void cleanup(); @@ -72,7 +72,7 @@ public: { public: U32 mGLName; - U8* mClientData; + volatile U8* mClientData; }; typedef std::list<Record> record_list_t; @@ -208,8 +208,8 @@ public: LLVertexBuffer(U32 typemask, S32 usage); // map for data access - U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range); - U8* mapIndexBuffer(S32 index, S32 count, bool map_range); + volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range); + volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range); // set for rendering virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 @@ -244,16 +244,17 @@ public: S32 getNumVerts() const { return mNumVerts; } S32 getNumIndices() const { return mNumIndices; } - U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; } - U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; } + volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; } + volatile U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; } U32 getTypeMask() const { return mTypeMask; } bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); } S32 getSize() const; S32 getIndicesSize() const { return mIndicesSize; } - U8* getMappedData() const { return mMappedData; } - U8* getMappedIndices() const { return mMappedIndexData; } + volatile U8* getMappedData() const { return mMappedData; } + volatile U8* getMappedIndices() const { return mMappedIndexData; } S32 getOffset(S32 type) const { return mOffsets[type]; } S32 getUsage() const { return mUsage; } + BOOL isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? TRUE : FALSE; } void draw(U32 mode, U32 count, U32 indices_offset) const; void drawArrays(U32 mode, U32 offset, U32 count) const; @@ -278,12 +279,13 @@ protected: U32 mGLIndices; // GL IBO handle U32 mGLArray; // GL VAO handle - U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) - U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) + volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) + volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory BOOL mFinal; // if TRUE, buffer can not be mapped again BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. + mutable BOOL mMappable; // if TRUE, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData) S32 mOffsets[TYPE_MAX]; std::vector<MappedRegion> mMappedVertexRegions; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ea00a0204d..0e26013152 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9079,6 +9079,28 @@ <key>Value</key> <integer>1</integer> </map> + <key>RenderAutoMuteByteLimit</key> + <map> + <key>Comment</key> + <string>Maximum bytes of attachments before an avatar is automatically visually muted (0 for no limit).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>RenderAutoMuteSurfaceAreaLimit</key> + <map> + <key>Comment</key> + <string>Maximum surface area of attachments before an avatar is automatically visually muted (0 for no limit).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderUseShaderLOD</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl index 0170ad4b55..40b0cf47ac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl @@ -61,17 +61,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa vec3 lv = lp.xyz-v; //get distance - float d = length(lv); + float d = dot(lv,lv); float da = 0.0; if (d > 0.0 && la > 0.0 && fa > 0.0) { //normalize light vector - lv *= 1.0/d; + lv = normalize(lv); //distance attenuation - float dist2 = d*d/(la*la); + float dist2 = d/la; da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); // spotlight coefficient. @@ -79,7 +79,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa da *= spot*spot; // GL_SPOT_EXPONENT=2 //angular attenuation - da *= calcDirectionalLight(n, lv); + da *= max(dot(n, lv), 0.0); } return da; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 93b1a114db..8c96d55342 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -70,17 +70,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa vec3 lv = lp.xyz-v; //get distance - float d = length(lv); + float d = dot(lv,lv); float da = 0.0; if (d > 0.0 && la > 0.0 && fa > 0.0) { //normalize light vector - lv *= 1.0/d; + lv = normalize(lv); //distance attenuation - float dist2 = d*d/(la*la); + float dist2 = d/la; da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); // spotlight coefficient. @@ -88,7 +88,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa da *= spot*spot; // GL_SPOT_EXPONENT=2 //angular attenuation - da *= calcDirectionalLight(n, lv); + da *= max(dot(n, lv), 0.0); } return da; @@ -123,7 +123,6 @@ void main() col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z); vary_pointlight_col = col.rgb*diffuse_color.rgb; - col.rgb = vec3(0,0,0); // Add windlight lights diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index d7b90978ba..c0edddc40a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -65,17 +65,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa vec3 lv = lp.xyz-v; //get distance - float d = length(lv); + float d = dot(lv,lv); float da = 0.0; if (d > 0.0 && la > 0.0 && fa > 0.0) { //normalize light vector - lv *= 1.0/d; + lv = normalize(lv); //distance attenuation - float dist2 = d*d/(la*la); + float dist2 = d/la; da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); // spotlight coefficient. @@ -83,7 +83,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa da *= spot*spot; // GL_SPOT_EXPONENT=2 //angular attenuation - da *= calcDirectionalLight(n, lv); + da *= max(dot(n, lv), 0.0); } return da; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl index 5a3955ef00..83815b1786 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -63,21 +63,21 @@ uniform vec3 light_diffuse[8]; float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) { - //get light vector +//get light vector vec3 lv = lp.xyz-v; //get distance - float d = length(lv); + float d = dot(lv,lv); float da = 0.0; if (d > 0.0 && la > 0.0 && fa > 0.0) { //normalize light vector - lv *= 1.0/d; + lv = normalize(lv); //distance attenuation - float dist2 = d*d/(la*la); + float dist2 = d/la; da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); // spotlight coefficient. @@ -85,7 +85,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa da *= spot*spot; // GL_SPOT_EXPONENT=2 //angular attenuation - da *= calcDirectionalLight(n, lv); + da *= max(dot(n, lv), 0.0); } return da; diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index 9540ddd2e8..1660f9687e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -69,17 +69,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa vec3 lv = lp.xyz-v; //get distance - float d = length(lv); + float d = dot(lv,lv); float da = 0.0; if (d > 0.0 && la > 0.0 && fa > 0.0) { //normalize light vector - lv *= 1.0/d; + lv = normalize(lv); //distance attenuation - float dist2 = d*d/(la*la); + float dist2 = d/la; da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); // spotlight coefficient. @@ -87,7 +87,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa da *= spot*spot; // GL_SPOT_EXPONENT=2 //angular attenuation - da *= calcDirectionalLight(n, lv); + da *= max(dot(n, lv), 0.0); } return da; diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl index 9c7a332417..84c27edb26 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -66,17 +66,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa vec3 lv = lp.xyz-v; //get distance - float d = length(lv); + float d = dot(lv,lv); float da = 0.0; if (d > 0.0 && la > 0.0 && fa > 0.0) { //normalize light vector - lv *= 1.0/d; + lv = normalize(lv); //distance attenuation - float dist2 = d*d/(la*la); + float dist2 = d/la; da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); // spotlight coefficient. @@ -84,7 +84,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa da *= spot*spot; // GL_SPOT_EXPONENT=2 //angular attenuation - da *= calcDirectionalLight(n, lv); + da *= max(dot(n, lv), 0.0); } return da; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 54ad3cd187..ab9b5ff436 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3314,6 +3314,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * } llinfos << "Received cached texture response for " << num_results << " textures." << llendl; + gAgentAvatarp->outputRezTiming("Fetched agent wearables textures from cache. Will now load them"); gAgentAvatarp->updateMeshTextures(); diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 13b62cb019..09305a5b4d 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -185,6 +185,7 @@ void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) { if (avatar) { + avatar->outputRezTiming("Sending wearables request"); sendAgentWearablesRequest(); } } @@ -949,6 +950,11 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs if (mInitialWearablesUpdateReceived) return; + if (isAgentAvatarValid()) + { + gAgentAvatarp->outputRezTiming("Received initial wearables update"); + } + // notify subscribers that wearables started loading. See EXT-7777 // *TODO: find more proper place to not be called from deprecated method. // Seems such place is found: LLInitialWearablesFetch::processContents() @@ -1619,6 +1625,11 @@ void LLAgentWearables::queryWearableCache() //VWR-22113: gAgent.getRegion() can return null if invalid, seen here on logout if(gAgent.getRegion()) { + if (isAgentAvatarValid()) + { + gAgentAvatarp->outputRezTiming("Fetching textures from cache"); + } + llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); gAgentQueryManager.mNumPendingQueries++; diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 4097ff707c..8cba54347e 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -87,6 +87,10 @@ public: LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) : LLInventoryFetchDescendentsObserver(cof_id) { + if (isAgentAvatarValid()) + { + gAgentAvatarp->outputRezTiming("Initial wearables fetch started"); + } } LLInitialWearablesFetch::~LLInitialWearablesFetch() @@ -101,6 +105,10 @@ void LLInitialWearablesFetch::done() // idle tick instead. gInventory.removeObserver(this); doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this)); + if (isAgentAvatarValid()) + { + gAgentAvatarp->outputRezTiming("Initial wearables fetch done"); + } } void LLInitialWearablesFetch::add(InitialWearableData &data) diff --git a/indra/newview/llagentwearablesfetch.h b/indra/newview/llagentwearablesfetch.h index 7dafab4a33..bedc445c0e 100644 --- a/indra/newview/llagentwearablesfetch.h +++ b/indra/newview/llagentwearablesfetch.h @@ -40,6 +40,8 @@ //-------------------------------------------------------------------- class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver { + LOG_CLASS(LLInitialWearablesFetch); + public: LLInitialWearablesFetch(const LLUUID& cof_id); ~LLInitialWearablesFetch(); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 663257042e..33f5373d7e 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -268,6 +268,8 @@ struct LLFoundData class LLWearableHoldingPattern { + LOG_CLASS(LLWearableHoldingPattern); + public: LLWearableHoldingPattern(); ~LLWearableHoldingPattern(); @@ -436,6 +438,11 @@ void LLWearableHoldingPattern::checkMissingWearables() void LLWearableHoldingPattern::onAllComplete() { + if (isAgentAvatarValid()) + { + gAgentAvatarp->outputRezTiming("Agent wearables fetch complete"); + } + if (!isMostRecent()) { llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl; @@ -2363,6 +2370,8 @@ void LLAppearanceMgr::autopopulateOutfits() // Handler for anything that's deferred until avatar de-clouds. void LLAppearanceMgr::onFirstFullyVisible() { + gAgentAvatarp->outputRezTiming("Avatar fully loaded"); + gAgentAvatarp->reportAvatarRezTime(); gAgentAvatarp->debugAvatarVisible(); // The auto-populate is failing at the point of generating outfits diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index debac9dcbf..21b21c152a 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1077,6 +1077,7 @@ BOOL LLDrawable::isVisible() const LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) : LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) { + mBridge = this; mDrawable = root; root->setSpatialBridge(this); @@ -1105,6 +1106,15 @@ LLSpatialBridge::~LLSpatialBridge() { group->mSpatialPartition->remove(this, group); } + + //delete octree here so listeners will still be able to access bridge specific state + destroyTree(); +} + +void LLSpatialBridge::destroyTree() +{ + delete mOctree; + mOctree = NULL; } void LLSpatialBridge::updateSpatialExtents() diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 55b314fbb1..b002c11af5 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1285,7 +1285,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face->setGeomIndex(0); face->setIndicesIndex(0); - if (buffer.isNull() || buffer->getTypeMask() != data_mask) + if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) { //make a new buffer if (sShaderLevel > 0) { @@ -1319,7 +1319,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* LLMatrix3 mat_normal(mat3); //let getGeometryVolume know if alpha should override shiny - if (face->getFaceColor().mV[3] < 1.f) + U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); + + if (type == LLDrawPool::POOL_ALPHA) { face->setPoolType(LLDrawPool::POOL_ALPHA); } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 6dbeae6677..cd33a19a2a 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -693,6 +693,49 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of tex_coord.mV[1] = t; } +// Transform the texture coordinates for this face. +static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVector4Logical& mask, const LLVector4a& rot0, const LLVector4a& rot1, const LLVector4a& offset, const LLVector4a& scale) +{ + //tex coord is two coords, <s0, t0, s1, t1> + LLVector4a st; + + // Texture transforms are done about the center of the face. + st.setAdd(tex_coord, trans); + + // Handle rotation + LLVector4a rot_st; + + // <s0 * cosAng, s0*-sinAng, s1*cosAng, s1*-sinAng> + LLVector4a s0; + s0.splat(st, 0); + LLVector4a s1; + s1.splat(st, 2); + LLVector4a ss; + ss.setSelectWithMask(mask, s1, s0); + + LLVector4a a; + a.setMul(rot0, ss); + + // <t0*sinAng, t0*cosAng, t1*sinAng, t1*cosAng> + LLVector4a t0; + t0.splat(st, 1); + LLVector4a t1; + t1.splat(st, 3); + LLVector4a tt; + tt.setSelectWithMask(mask, t1, t0); + + LLVector4a b; + b.setMul(rot1, tt); + + st.setAdd(a,b); + + // Then scale + st.mul(scale); + + // Then offset + tex_coord.setAdd(st, offset); +} + bool less_than_max_mag(const LLVector4a& vec) { @@ -1060,6 +1103,16 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal"); static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail"); +static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos"); +static LLFastTimer::DeclareTimer FTM_FACE_TEXTURE_INDEX_STORE("TexIdx"); +static LLFastTimer::DeclareTimer FTM_FACE_POSITION_PAD("Pad"); +static LLFastTimer::DeclareTimer FTM_FACE_TEX_DEFAULT("Default"); +static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK("Quick"); +static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_NO_XFORM("No Xform"); +static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_XFORM("Xform"); + +static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_PLANAR("Quick Planar"); BOOL LLFace::getGeometryVolume(const LLVolume& volume, const S32 &f, @@ -1078,7 +1131,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, updateRebuildFlags(); } - bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; + + //don't use map range (generates many redundant unmap calls) + bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; if (mVertexBuffer.notNull()) { @@ -1104,16 +1159,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } LLStrider<LLVector3> vert; - LLVector4a* vertices = NULL; LLStrider<LLVector2> tex_coords; LLStrider<LLVector2> tex_coords2; - LLVector4a* normals = NULL; LLStrider<LLVector3> norm; LLStrider<LLColor4U> colors; - LLVector4a* binormals = NULL; LLStrider<LLVector3> binorm; LLStrider<U16> indicesp; - LLVector4a* weights = NULL; LLStrider<LLVector4> wght; BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME); @@ -1202,7 +1253,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLFastTimer t(FTM_FACE_GEOM_INDEX); mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range); - __m128i* dst = (__m128i*) indicesp.get(); + volatile __m128i* dst = (__m128i*) indicesp.get(); __m128i* src = (__m128i*) vf.mIndices; __m128i offset = _mm_set1_epi16(index_offset); @@ -1211,12 +1262,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, for (S32 i = 0; i < end; i++) { __m128i res = _mm_add_epi16(src[i], offset); - _mm_storeu_si128(dst+i, res); + _mm_storeu_si128((__m128i*) dst++, res); } - for (S32 i = end*8; i < num_indices; ++i) { - indicesp[i] = vf.mIndices[i]+index_offset; + LLFastTimer t(FTM_FACE_GEOM_INDEX_TAIL); + U16* idx = (U16*) dst; + + for (S32 i = end*8; i < num_indices; ++i) + { + *idx++ = vf.mIndices[i]+index_offset; + } } if (map_range) @@ -1373,19 +1429,48 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (texgen != LLTextureEntry::TEX_GEN_PLANAR) { + LLFastTimer t(FTM_FACE_TEX_QUICK); if (!do_tex_mat) { if (!do_xform) { + LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM); LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); } else { - for (S32 i = 0; i < num_vertices; i++) + LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM); + F32* dst = (F32*) tex_coords.get(); + LLVector4a* src = (LLVector4a*) vf.mTexCoords; + + LLVector4a trans; + trans.splat(-0.5f); + + LLVector4a rot0; + rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang); + + LLVector4a rot1; + rot1.set(sin_ang, cos_ang, sin_ang, cos_ang); + + LLVector4a scale; + scale.set(ms, mt, ms, mt); + + LLVector4a offset; + offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f); + + LLVector4Logical mask; + mask.clear(); + mask.setElement<2>(); + mask.setElement<3>(); + + U32 count = num_vertices/2 + num_vertices%2; + + for (S32 i = 0; i < count; i++) { - LLVector2 tc(vf.mTexCoords[i]); - xform(tc, cos_ang, sin_ang, os, ot, ms, mt); - *tex_coords++ = tc; + LLVector4a res = *src++; + xform4a(res, trans, mask, rot0, rot1, offset, scale); + res.store4a(dst); + dst += 4; } } } @@ -1407,6 +1492,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } else { //no bump, no atlas, tex gen planar + LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR); if (do_tex_mat) { for (S32 i = 0; i < num_vertices; i++) @@ -1451,6 +1537,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } else { //either bump mapped or in atlas, just do the whole expensive loop + LLFastTimer t(FTM_FACE_TEX_DEFAULT); mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range); std::vector<LLVector2> bump_tc; @@ -1642,44 +1729,55 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, llassert(num_vertices > 0); mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); - vertices = (LLVector4a*) vert.get(); - + + LLMatrix4a mat_vert; mat_vert.loadu(mat_vert_in); LLVector4a* src = vf.mPositions; - LLVector4a* dst = vertices; + volatile F32* dst = (volatile F32*) vert.get(); - LLVector4a* end = dst+num_vertices; - do - { - mat_vert.affineTransform(*src++, *dst++); - } - while(dst < end); + volatile F32* end = dst+num_vertices*4; + LLVector4a res; - F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); + LLVector4a texIdx; + F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); llassert(index <= LLGLSLShader::sIndexedTextureChannels-1); - F32 *index_dst = (F32*) vertices; - F32 *index_end = (F32*) end; - index_dst += 3; - index_end += 3; - do + LLVector4Logical mask; + mask.clear(); + mask.setElement<3>(); + + texIdx.set(0,0,0,index); + { - *index_dst = index; - index_dst += 4; + LLFastTimer t(FTM_FACE_POSITION_STORE); + LLVector4a tmp; + + do + { + mat_vert.affineTransform(*src++, res); + tmp.setSelectWithMask(mask, texIdx, res); + tmp.store4a((F32*) dst); + dst += 4; + } + while(dst < end); } - while (index_dst < index_end); - - S32 aligned_pad_vertices = mGeomCount - num_vertices; - LLVector4a* last_vec = end - 1; - while (aligned_pad_vertices > 0) + { - --aligned_pad_vertices; - *dst++ = *last_vec; + LLFastTimer t(FTM_FACE_POSITION_PAD); + S32 aligned_pad_vertices = mGeomCount - num_vertices; + res.set(res[0], res[1], res[2], 0.f); + + while (aligned_pad_vertices > 0) + { + --aligned_pad_vertices; + res.store4a((F32*) dst); + dst += 4; + } } - + if (map_range) { mVertexBuffer->flush(); @@ -1690,14 +1788,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLFastTimer t(FTM_FACE_GEOM_NORMAL); mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); - normals = (LLVector4a*) norm.get(); + F32* normals = (F32*) norm.get(); for (S32 i = 0; i < num_vertices; i++) { LLVector4a normal; mat_normal.rotate(vf.mNormals[i], normal); normal.normalize3fast(); - normals[i] = normal; + normal.store4a(normals); + normals += 4; } if (map_range) @@ -1710,14 +1809,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLFastTimer t(FTM_FACE_GEOM_BINORMAL); mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); - binormals = (LLVector4a*) binorm.get(); + F32* binormals = (F32*) binorm.get(); for (S32 i = 0; i < num_vertices; i++) { LLVector4a binormal; mat_normal.rotate(vf.mBinormals[i], binormal); binormal.normalize3fast(); - binormals[i] = binormal; + binormal.store4a(binormals); + binormals += 4; } if (map_range) @@ -1730,8 +1830,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLFastTimer t(FTM_FACE_GEOM_WEIGHTS); mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range); - weights = (LLVector4a*) wght.get(); - LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); + F32* weights = (F32*) wght.get(); + LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); if (map_range) { mVertexBuffer->flush(); @@ -1750,7 +1850,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, src.loadua((F32*) vec); - LLVector4a* dst = (LLVector4a*) colors.get(); + F32* dst = (F32*) colors.get(); S32 num_vecs = num_vertices/4; if (num_vertices%4 > 0) { @@ -1759,7 +1859,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, for (S32 i = 0; i < num_vecs; i++) { - dst[i] = src; + src.store4a(dst); + dst += 4; } if (map_range) @@ -1789,7 +1890,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, src.loadua((F32*) vec); - LLVector4a* dst = (LLVector4a*) emissive.get(); + F32* dst = (F32*) emissive.get(); S32 num_vecs = num_vertices/4; if (num_vertices%4 > 0) { @@ -1798,7 +1899,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, for (S32 i = 0; i < num_vecs; i++) { - dst[i] = src; + src.store4a(dst); + dst += 4; } if (map_range) @@ -1821,6 +1923,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mTexExtents[1][1] *= et ; } + mLastVertexBuffer = mVertexBuffer; mLastGeomCount = mGeomCount; mLastGeomIndex = mGeomIndex; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 64bdcccd9f..9122e5a8f5 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3969,7 +3969,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices(); if (num_indices > 2) { - glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f); + glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, (U8*) mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f); } tri_count += num_indices/3; stop_gloderror(); @@ -4083,14 +4083,14 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim { buff->allocateBuffer(sizes[i*2+1], sizes[i*2], true); buff->setBuffer(type_mask); - glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, buff->getIndicesPointer()); + glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, (U8*) buff->getIndicesPointer()); stop_gloderror(); } else { //this face was eliminated, create a dummy triangle (one vertex, 3 indices, all 0) buff->allocateBuffer(1, 3, true); - memset(buff->getMappedData(), 0, buff->getSize()); - memset(buff->getIndicesPointer(), 0, buff->getIndicesSize()); + memset((U8*) buff->getMappedData(), 0, buff->getSize()); + memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize()); } buff->validateRange(0, buff->getNumVerts()-1, buff->getNumIndices(), 0); @@ -4880,8 +4880,8 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget ) LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0); buff->allocateBuffer(1, 3, true); - memset( buff->getMappedData(), 0, buff->getSize() ); - memset( buff->getIndicesPointer(), 0, buff->getIndicesSize() ); + memset( (U8*) buff->getMappedData(), 0, buff->getSize() ); + memset( (U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize() ); buff->validateRange( 0, buff->getNumVerts()-1, buff->getNumIndices(), 0 ); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index c0065a94e6..cebe93f042 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -73,7 +73,7 @@ #include "llwearablelist.h" // Marketplace outbox current disabled -#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 1 +#define ENABLE_MERCHANT_OUTBOX_CONTEXT_MENU 0 #define ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU 0 #define BLOCK_WORN_ITEMS_IN_OUTBOX 1 diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index c64479f589..b02bf79a28 100644..100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -88,6 +88,9 @@ const S32 MAX_MESH_VERSION = 999; U32 LLMeshRepository::sBytesReceived = 0; U32 LLMeshRepository::sHTTPRequestCount = 0; U32 LLMeshRepository::sHTTPRetryCount = 0; +U32 LLMeshRepository::sLODProcessing = 0; +U32 LLMeshRepository::sLODPending = 0; + U32 LLMeshRepository::sCacheBytesRead = 0; U32 LLMeshRepository::sCacheBytesWritten = 0; U32 LLMeshRepository::sPeakKbps = 0; @@ -205,6 +208,12 @@ public: LLMeshHeaderResponder(const LLVolumeParams& mesh_params) : mMeshParams(mesh_params) { + LLMeshRepoThread::sActiveHeaderRequests++; + } + + ~LLMeshHeaderResponder() + { + LLMeshRepoThread::sActiveHeaderRequests--; } virtual void completedRaw(U32 status, const std::string& reason, @@ -224,6 +233,12 @@ public: LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes) : mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes) { + LLMeshRepoThread::sActiveLODRequests++; + } + + ~LLMeshLODResponder() + { + LLMeshRepoThread::sActiveLODRequests--; } virtual void completedRaw(U32 status, const std::string& reason, @@ -497,6 +512,7 @@ void LLMeshRepoThread::run() mMutex->lock(); LODRequest req = mLODReqQ.front(); mLODReqQ.pop(); + LLMeshRepository::sLODProcessing--; mMutex->unlock(); if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit { @@ -607,6 +623,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { LLMutexLock lock(mMutex); mLODReqQ.push(req); + LLMeshRepository::sLODProcessing++; } } else @@ -714,7 +731,6 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) new LLMeshSkinInfoResponder(mesh_id, offset, size)); if(ret) { - ++sActiveLODRequests; LLMeshRepository::sHTTPRequestCount++; } } @@ -792,7 +808,6 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) new LLMeshDecompositionResponder(mesh_id, offset, size)); if(ret) { - ++sActiveLODRequests; LLMeshRepository::sHTTPRequestCount++; } } @@ -870,7 +885,6 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) if(ret) { - ++sActiveLODRequests; LLMeshRepository::sHTTPRequestCount++; } } @@ -925,7 +939,6 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c retval = mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params)); if(retval) { - ++sActiveHeaderRequests; LLMeshRepository::sHTTPRequestCount++; } count++; @@ -995,7 +1008,6 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, if(retval) { - ++sActiveLODRequests; LLMeshRepository::sHTTPRequestCount++; } count++; @@ -1070,6 +1082,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat { LODRequest req(mesh_params, iter->second[i]); mLODReqQ.push(req); + LLMeshRepository::sLODProcessing++; } } mPendingLOD.erase(iter); @@ -1753,7 +1766,6 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, const LLIOPipe::buffer_ptr_t& buffer) { - LLMeshRepoThread::sActiveLODRequests--; S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1970,7 +1982,6 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { - LLMeshRepoThread::sActiveHeaderRequests--; if (status < 200 || status > 400) { //llwarns @@ -2188,6 +2199,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para //first request for this mesh mLoadingMeshes[detail][mesh_params].insert(vobj->getID()); mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); + LLMeshRepository::sLODPending++; } } @@ -2400,6 +2412,7 @@ void LLMeshRepository::notifyLoadedMeshes() LLMeshRepoThread::LODRequest& request = mPendingRequests.front(); mThread->loadMeshLOD(request.mMeshParams, request.mLOD); mPendingRequests.erase(mPendingRequests.begin()); + LLMeshRepository::sLODPending--; push_count--; } } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 1b7954d4bd..4139b9725b 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -441,6 +441,8 @@ public: static U32 sBytesReceived; static U32 sHTTPRequestCount; static U32 sHTTPRetryCount; + static U32 sLODPending; + static U32 sLODProcessing; static U32 sCacheBytesRead; static U32 sCacheBytesWritten; static U32 sPeakKbps; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 5d0d1ef9a3..6111255a66 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5556,38 +5556,37 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) //helper function for pushing relevant vertices from drawable to GL void pushWireframe(LLDrawable* drawable) { - if (drawable->isState(LLDrawable::RIGGED)) - { //render straight from rigged volume if this is a rigged attachment - LLVOVolume* vobj = drawable->getVOVolume(); - if (vobj) - { - vobj->updateRiggedVolume(); - LLRiggedVolume* rigged_volume = vobj->getRiggedVolume(); - if (rigged_volume) - { - LLVertexBuffer::unbind(); - gGL.pushMatrix(); - gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); - for (S32 i = 0; i < rigged_volume->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = rigged_volume->getVolumeFace(i); - LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices); - } - gGL.popMatrix(); - } - } - } - else + LLVOVolume* vobj = drawable->getVOVolume(); + if (vobj) { - for (S32 i = 0; i < drawable->getNumFaces(); ++i) + LLVertexBuffer::unbind(); + gGL.pushMatrix(); + gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); + + LLVolume* volume = NULL; + + if (drawable->isState(LLDrawable::RIGGED)) + { + vobj->updateRiggedVolume(); + volume = vobj->getRiggedVolume(); + } + else + { + volume = vobj->getVolume(); + } + + if (volume) { - LLFace* face = drawable->getFace(i); - if (face->verify()) + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { - pushVerts(face, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); + const LLVolumeFace& face = volume->getVolumeFace(i); + LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices); } } + + gGL.popMatrix(); } + } void LLSelectNode::renderOneWireframe(const LLColor4& color) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 7d8f7b6df0..746320f887 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -265,7 +265,7 @@ static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); void LLSpatialGroup::buildOcclusion()
{
- if (mOcclusionVerts.isNull())
+ //if (mOcclusionVerts.isNull())
{
mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,
LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
@@ -727,7 +727,9 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) if (vertex_count > 0 && index_count > 0)
{ //create vertex buffer containing volume geometry for this node
group->mBuilt = 1.f;
- if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
+ if (group->mVertexBuffer.isNull() ||
+ !group->mVertexBuffer->isWriteable() ||
+ (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
{
group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
@@ -1186,6 +1188,8 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mState(0),
+ mGeometryBytes(0),
+ mSurfaceArea(0.f),
mBuilt(0.f),
mOctreeNode(node),
mSpatialPartition(part),
@@ -1411,6 +1415,17 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) }
}
+ //clean up avatar attachment stats
+ LLSpatialBridge* bridge = mSpatialPartition->asBridge();
+ if (bridge)
+ {
+ if (bridge->mAvatar.notNull())
+ {
+ bridge->mAvatar->mAttachmentGeometryBytes -= mGeometryBytes;
+ bridge->mAvatar->mAttachmentSurfaceArea -= mSurfaceArea;
+ }
+ }
+
clearDrawMap();
mVertexBuffer = NULL;
mBufferMap.clear();
@@ -1766,7 +1781,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //==============================================
LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage)
-: mRenderByGroup(render_by_group)
+: mRenderByGroup(render_by_group), mBridge(NULL)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
mOcclusionEnabled = TRUE;
@@ -3776,7 +3791,7 @@ void renderRaycast(LLDrawable* drawablep) for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
-
+
gGL.pushMatrix();
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix);
@@ -3810,7 +3825,7 @@ void renderRaycast(LLDrawable* drawablep) gGL.syncMatrices();
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
-
+
if (!volume->isUnique())
{
F32 t = 1.f;
@@ -3822,7 +3837,7 @@ void renderRaycast(LLDrawable* drawablep) LLRenderOctreeRaycast render(starta, dir, &t);
- render.traverse(face.mOctree);
+ render.traverse(face.mOctree);
}
gGL.popMatrix();
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 899547ae4d..6c14ecf452 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -405,6 +405,9 @@ public: bridge_list_t mBridgeList; buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers + U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node + F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node + F32 mBuilt; OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; @@ -474,8 +477,8 @@ public: BOOL isVisible(const LLVector3& v); bool isHUDPartition() ; - virtual LLSpatialBridge* asBridge() { return NULL; } - virtual BOOL isBridge() { return asBridge() != NULL; } + LLSpatialBridge* asBridge() { return mBridge; } + BOOL isBridge() { return asBridge() != NULL; } void renderPhysicsShapes(); void renderDebug(); @@ -487,6 +490,9 @@ public: public: LLSpatialGroup::OctreeNode* mOctree; + LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this + // use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe + // to call asBridge() from the destructor BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane U32 mBufferUsage; @@ -511,8 +517,9 @@ public: LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); - virtual BOOL isSpatialBridge() const { return TRUE; } + void destroyTree(); + virtual BOOL isSpatialBridge() const { return TRUE; } virtual void updateSpatialExtents(); virtual void updateBinRadius(); virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE); @@ -523,11 +530,12 @@ public: virtual void shiftPos(const LLVector4a& vec); virtual void cleanupReferences(); virtual LLSpatialPartition* asPartition() { return this; } - virtual LLSpatialBridge* asBridge() { return this; } - + virtual LLCamera transformCamera(LLCamera& camera); LLDrawable* mDrawable; + LLPointer<LLVOAvatar> mAvatar; + }; class LLCullResult diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h index 85dadb213c..4f43547dae 100644 --- a/indra/newview/lltexlayer.h +++ b/indra/newview/lltexlayer.h @@ -261,6 +261,8 @@ private: //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLTexLayerSetBuffer : public LLViewerDynamicTexture { + LOG_CLASS(LLTexLayerSetBuffer); + public: LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height); virtual ~LLTexLayerSetBuffer(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 67f6150dbe..99540ccce9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -947,6 +947,10 @@ U32 info_display_from_string(std::string info_display) { return LLPipeline::RENDER_DEBUG_COMPOSITION; } + else if ("attachment bytes" == info_display) + { + return LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES; + } else if ("glow" == info_display) { return LLPipeline::RENDER_DEBUG_GLOW; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b8772971aa..37fb77a10a 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5520,11 +5520,12 @@ void LLViewerObject::dirtyMesh() { if (mDrawable) { - LLSpatialGroup* group = mDrawable->getSpatialGroup(); + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); + /*LLSpatialGroup* group = mDrawable->getSpatialGroup(); if (group) { group->dirtyMesh(); - } + }*/ } } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 487f849ada..04b687b42f 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -615,7 +615,9 @@ public: addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount, LLMeshRepository::sHTTPRetryCount)); - + ypos += y_inc; + + addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing)); ypos += y_inc; addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f))); @@ -1997,7 +1999,7 @@ void LLViewerWindow::shutdownViews() gMorphView->setVisible(FALSE); } llinfos << "Global views cleaned." << llendl ; - + // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open // will crump with LL_ERRS. LLModalDialog::shutdownModals(); @@ -2010,17 +2012,17 @@ void LLViewerWindow::shutdownViews() delete LLNavigationBar::getInstance(); } llinfos << "LLNavigationBar destroyed." << llendl ; - + // destroy menus after instantiating navbar above, as it needs // access to gMenuHolder cleanup_menus(); llinfos << "menus destroyed." << llendl ; - + // Delete all child views. delete mRootView; mRootView = NULL; llinfos << "RootView deleted." << llendl ; - + // Automatically deleted as children of mRootView. Fix the globals. gStatusBar = NULL; gIMMgr = NULL; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 68637a7ed9..bc7f5a9744 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -651,6 +651,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, LLViewerObject(id, pcode, regionp), mIsDummy(FALSE), mSpecialRenderMode(0), + mAttachmentGeometryBytes(0), + mAttachmentSurfaceArea(0.f), mTurning(FALSE), mPelvisToFoot(0.f), mLastSkeletonSerialNum( 0 ), @@ -3363,6 +3365,16 @@ void LLVOAvatar::slamPosition() mRoot.updateWorldMatrixChildren(); } +bool LLVOAvatar::isVisuallyMuted() +{ + static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit"); + static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); + + return LLMuteList::getInstance()->isMuted(getID()) || + (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || + (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f); +} + //------------------------------------------------------------------------ // updateCharacter() // called on both your avatar and other avatars @@ -3429,8 +3441,9 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) size.setSub(ext[1],ext[0]); F32 mag = size.getLength3().getF32()*0.5f; + F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); - if (LLMuteList::getInstance()->isMuted(getID())) + if (isVisuallyMuted()) { // muted avatars update at 16 hz mUpdatePeriod = 16; } @@ -8333,6 +8346,11 @@ void LLVOAvatar::idleUpdateRenderCost() static std::set<LLUUID> all_textures; + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES)) + { //set debug text to attachment geometry bytes here so render cost will override + setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea)); + } + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) { return; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 59796370ae..dd0317f555 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -78,6 +78,8 @@ class LLVOAvatar : public LLCharacter, public boost::signals2::trackable { + LOG_CLASS(LLVOAvatar); + public: friend class LLVOAvatarSelf; protected: @@ -380,6 +382,8 @@ private: public: U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); + bool isVisuallyMuted(); + U32 renderRigid(); U32 renderSkinned(EAvatarRenderPass pass); F32 getLastSkinTime() { return mLastSkinTime; } @@ -391,6 +395,9 @@ public: static void restoreGL(); BOOL mIsDummy; // for special views S32 mSpecialRenderMode; // special lighting + U32 mAttachmentGeometryBytes; //number of bytes in attached geometry + F32 mAttachmentSurfaceArea; //estimated surface area of attachments + private: bool shouldAlphaMask(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 581912f844..f1df67494f 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1574,7 +1574,7 @@ void LLVOAvatarSelf::invalidateAll() { invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE); } - mDebugSelfLoadTimer.reset(); + //mDebugSelfLoadTimer.reset(); } //----------------------------------------------------------------------------- @@ -1896,11 +1896,13 @@ BOOL LLVOAvatarSelf::getIsCloud() gAgentWearables.getWearableCount(LLWearableType::WT_EYES) == 0 || gAgentWearables.getWearableCount(LLWearableType::WT_SKIN) == 0) { + lldebugs << "No body parts" << llendl; return TRUE; } if (!isTextureDefined(TEX_HAIR, 0)) { + lldebugs << "No hair texture" << llendl; return TRUE; } @@ -1909,12 +1911,14 @@ BOOL LLVOAvatarSelf::getIsCloud() if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) && (!isTextureDefined(TEX_LOWER_BAKED, 0))) { + lldebugs << "Lower textures not baked" << llendl; return TRUE; } if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) && (!isTextureDefined(TEX_UPPER_BAKED, 0))) { + lldebugs << "Upper textures not baked" << llendl; return TRUE; } @@ -1931,10 +1935,12 @@ BOOL LLVOAvatarSelf::getIsCloud() const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 ); if (!baked_img || !baked_img->hasGLTexture()) { + lldebugs << "Texture at index " << i << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl; return TRUE; } } + lldebugs << "Avatar de-clouded" << llendl; } return FALSE; } @@ -2258,6 +2264,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) } } +// FIXME: This is never called. Something may be broken. void LLVOAvatarSelf::outputRezDiagnostics() const { if(!gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) @@ -2315,6 +2322,18 @@ void LLVOAvatarSelf::outputRezDiagnostics() const } } +void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const +{ + LL_DEBUGS("Avatar Rez") + << llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32()) + << llendl; +} + +void LLVOAvatarSelf::reportAvatarRezTime() const +{ + // TODO: report mDebugSelfLoadTimer.getElapsedTimeF32() somehow. +} + //----------------------------------------------------------------------------- // setCachedBakedTexture() // A baked texture id was received from a cache query, make it active diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 74ff47a3e4..54dbe81993 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -41,6 +41,7 @@ struct LocalTextureData; class LLVOAvatarSelf : public LLVOAvatar { + LOG_CLASS(LLVOAvatarSelf); /******************************************************************************** ** ** @@ -358,6 +359,8 @@ public: void debugWearablesLoaded() { mDebugTimeWearablesLoaded = mDebugSelfLoadTimer.getElapsedTimeF32(); } void debugAvatarVisible() { mDebugTimeAvatarVisible = mDebugSelfLoadTimer.getElapsedTimeF32(); } void outputRezDiagnostics() const; + void outputRezTiming(const std::string& msg) const; + void reportAvatarRezTime() const; void debugBakedTextureUpload(LLVOAvatarDefines::EBakedTextureIndex index, BOOL finished); static void debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index c3a2e6a712..bf6158eeaf 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -65,7 +65,7 @@ public: return; } - U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; + volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; //assume tex coords 2 and 3 are present U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 20f8674655..7492a06784 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4097,6 +4097,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); + LLVOAvatar* pAvatarVO = NULL; + + LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + if (bridge) + { + if (bridge->mAvatar.isNull()) + { + LLViewerObject* vobj = bridge->mDrawable->getVObj(); + if (vobj) + { + bridge->mAvatar = vobj->getAvatar(); + } + } + + pAvatarVO = bridge->mAvatar; + } + + if (pAvatarVO) + { + pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes; + pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea; + } + + group->mGeometryBytes = 0; + group->mSurfaceArea = 0; + group->clearDrawMap(); mFaceList.clear(); @@ -4133,12 +4159,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOVolume* vobj = drawablep->getVOVolume(); + if (!vobj) + { + continue; + } + if (vobj->isMesh() && (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled())) { continue; } + LLVolume* volume = vobj->getVolume(); + if (volume) + { + const LLVector3& scale = vobj->getScale(); + group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); + } + llassert_always(vobj); vobj->updateTextureVirtualSize(true); vobj->preRebuild(); @@ -4183,7 +4221,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //Determine if we've received skininfo that contains an //alternate bind matrix - if it does then apply the translational component //to the joints of the avatar. - LLVOAvatar* pAvatarVO = vobj->getAvatar(); bool pelvisGotSet = false; if ( pAvatarVO ) @@ -4253,13 +4290,16 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (type == LLDrawPool::POOL_ALPHA) { - if (te->getFullbright()) + if (te->getColor().mV[3] > 0.f) { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); - } - else - { - pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + } } } else if (te->getShiny()) @@ -4392,8 +4432,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { - drawablep->setState(LLDrawable::HAS_ALPHA); - alpha_faces.push_back(facep); + if (te->getColor().mV[3] > 0.f) + { + drawablep->setState(LLDrawable::HAS_ALPHA); + alpha_faces.push_back(facep); + } } } else @@ -4510,6 +4553,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } mFaceList.clear(); + + if (pAvatarVO) + { + pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes; + pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea; + } } static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry"); @@ -4806,17 +4855,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: //create/delete/resize vertex buffer if needed LLVertexBuffer* buffer = NULL; - LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter); + + { //try to find a buffer to reuse + LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter); - if (found_iter != group->mBufferMap[mask].end()) - { - if ((U32) buffer_index < found_iter->second.size()) + if (found_iter != group->mBufferMap[mask].end()) { - buffer = found_iter->second[buffer_index]; + if ((U32) buffer_index < found_iter->second.size()) + { + buffer = found_iter->second[buffer_index]; + } } } - if (!buffer) + if (!buffer || !buffer->isWriteable()) { //create new buffer if needed buffer = createVertexBuffer(mask, buffer_usage); buffer->allocateBuffer(geom_count, index_count, TRUE); @@ -4835,6 +4887,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } } + group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); + + buffer_map[mask][*face_iter].push_back(buffer); //add face geometry diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 7df50ec815..315616e8a5 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -167,7 +167,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) indices_per_quad * num_quads); LLVertexBuffer* buff = face->getVertexBuffer(); - if (!buff) + if (!buff || !buff->isWriteable()) { buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index f1c5499d84..afd902201b 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -774,7 +774,7 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) LLStrider<LLColor4U> colorsp; LLStrider<LLVector2> texcoordsp; - if (mStarsVerts.isNull()) + if (mStarsVerts.isNull() || !mStarsVerts->isWriteable()) { mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index a929d7a6dd..1f777032e6 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1217,10 +1217,12 @@ void LLPipeline::restoreGL() BOOL LLPipeline::canUseVertexShaders() { + static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable"; + if (sDisableShaders || !gGLManager.mHasVertexShader || !gGLManager.mHasFragmentShader || - !LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") || + !LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) || (assertInitialized() && mVertexShadersLoaded != 1) ) { return FALSE; @@ -3765,6 +3767,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO"); // Initialize lots of GL state to "safe" values + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadIdentity(); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -5297,7 +5300,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light_state->setConstantAttenuation(0.f); if (sRenderDeferred) { - light_state->setLinearAttenuation(light_radius*1.5f); + F32 size = light_radius*1.5f; + light_state->setLinearAttenuation(size*size); light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f); } else @@ -5319,7 +5323,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light_state->setSpotCutoff(90.f); light_state->setSpotExponent(2.f); - light_state->setSpecular(LLColor4::black); + const LLColor4 specular(0.f, 0.f, 0.f, 0.f); + light_state->setSpecular(specular); } else // omnidirectional (point) light { @@ -9425,7 +9430,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID()); + bool muted = avatar->isVisuallyMuted(); pushRenderTypeMask(); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 2815d736e4..9c78048c46 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -432,34 +432,35 @@ public: enum LLRenderDebugMask { - RENDER_DEBUG_COMPOSITION = 0x0000001, - RENDER_DEBUG_VERIFY = 0x0000002, - RENDER_DEBUG_BBOXES = 0x0000004, - RENDER_DEBUG_OCTREE = 0x0000008, - RENDER_DEBUG_WIND_VECTORS = 0x0000010, - RENDER_DEBUG_OCCLUSION = 0x0000020, - RENDER_DEBUG_POINTS = 0x0000040, - RENDER_DEBUG_TEXTURE_PRIORITY = 0x0000080, - RENDER_DEBUG_TEXTURE_AREA = 0x0000100, - RENDER_DEBUG_FACE_AREA = 0x0000200, - RENDER_DEBUG_PARTICLES = 0x0000400, - RENDER_DEBUG_GLOW = 0x0000800, - RENDER_DEBUG_TEXTURE_ANIM = 0x0001000, - RENDER_DEBUG_LIGHTS = 0x0002000, - RENDER_DEBUG_BATCH_SIZE = 0x0004000, - RENDER_DEBUG_ALPHA_BINS = 0x0008000, - RENDER_DEBUG_RAYCAST = 0x0010000, - RENDER_DEBUG_SHAME = 0x0020000, - RENDER_DEBUG_SHADOW_FRUSTA = 0x0040000, - RENDER_DEBUG_SCULPTED = 0x0080000, - RENDER_DEBUG_AVATAR_VOLUME = 0x0100000, - RENDER_DEBUG_BUILD_QUEUE = 0x0200000, - RENDER_DEBUG_AGENT_TARGET = 0x0400000, - RENDER_DEBUG_UPDATE_TYPE = 0x0800000, - RENDER_DEBUG_PHYSICS_SHAPES = 0x1000000, - RENDER_DEBUG_NORMALS = 0x2000000, - RENDER_DEBUG_LOD_INFO = 0x4000000, - RENDER_DEBUG_RENDER_COMPLEXITY = 0x8000000 + RENDER_DEBUG_COMPOSITION = 0x00000001, + RENDER_DEBUG_VERIFY = 0x00000002, + RENDER_DEBUG_BBOXES = 0x00000004, + RENDER_DEBUG_OCTREE = 0x00000008, + RENDER_DEBUG_WIND_VECTORS = 0x00000010, + RENDER_DEBUG_OCCLUSION = 0x00000020, + RENDER_DEBUG_POINTS = 0x00000040, + RENDER_DEBUG_TEXTURE_PRIORITY = 0x00000080, + RENDER_DEBUG_TEXTURE_AREA = 0x00000100, + RENDER_DEBUG_FACE_AREA = 0x00000200, + RENDER_DEBUG_PARTICLES = 0x00000400, + RENDER_DEBUG_GLOW = 0x00000800, + RENDER_DEBUG_TEXTURE_ANIM = 0x00001000, + RENDER_DEBUG_LIGHTS = 0x00002000, + RENDER_DEBUG_BATCH_SIZE = 0x00004000, + RENDER_DEBUG_ALPHA_BINS = 0x00008000, + RENDER_DEBUG_RAYCAST = 0x00010000, + RENDER_DEBUG_SHAME = 0x00020000, + RENDER_DEBUG_SHADOW_FRUSTA = 0x00040000, + RENDER_DEBUG_SCULPTED = 0x00080000, + RENDER_DEBUG_AVATAR_VOLUME = 0x00100000, + RENDER_DEBUG_BUILD_QUEUE = 0x00200000, + RENDER_DEBUG_AGENT_TARGET = 0x00400000, + RENDER_DEBUG_UPDATE_TYPE = 0x00800000, + RENDER_DEBUG_PHYSICS_SHAPES = 0x01000000, + RENDER_DEBUG_NORMALS = 0x02000000, + RENDER_DEBUG_LOD_INFO = 0x04000000, + RENDER_DEBUG_RENDER_COMPLEXITY = 0x08000000, + RENDER_DEBUG_ATTACHMENT_BYTES = 0x10000000, }; public: diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 33a756fdd5..d8f9453b09 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -153,13 +153,6 @@ function="BuyCurrency" /> </menu_item_call> <menu_item_call - label="Merchant Outbox..." - name="MerchantOutbox"> - <menu_item_call.on_click - function="Floater.ToggleOrBringToFront" - parameter="outbox" /> - </menu_item_call> - <menu_item_call label="Account dashboard..." name="Manage My Account"> <menu_item_call.on_click @@ -2457,6 +2450,16 @@ function="Advanced.ToggleInfoDisplay" parameter="rendercomplexity" /> </menu_item_check> + <menu_item_check + label="Attachment Bytes" + name="attachment bytes"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="attachment bytes" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="attachment bytes" /> + </menu_item_check> <menu_item_check label="Sculpt" name="Sculpt"> |