From b101bb00013452c6d569cf85a79ae5bc3e8ea9db Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 17 Jul 2012 23:38:34 -0500 Subject: [PATCH 001/103] MAINT-646: Faster traversal of render batch lists. https://bitbucket.org/davep/viewer-development/changeset/38b7779af5f9 --- indra/newview/lldrawpool.cpp | 2 +- indra/newview/lldrawpoolalpha.cpp | 4 +- indra/newview/lldrawpoolavatar.cpp | 68 +++++++++----- indra/newview/lldrawpoolbump.cpp | 12 +-- indra/newview/llspatialpartition.cpp | 135 +++++++++++++++++---------- indra/newview/llspatialpartition.h | 68 +++++++++----- indra/newview/pipeline.cpp | 60 ++++++------ indra/newview/pipeline.h | 8 +- 8 files changed, 214 insertions(+), 143 deletions(-) diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 968ed740a..69a3cf419 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -446,7 +446,7 @@ void LLRenderPass::renderTexture(U32 type, U32 mask) void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) { - for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) + for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i) { LLDrawInfo* pparams = *i; if (pparams) diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 500f8b67a..865e89f89 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -355,7 +355,7 @@ void LLDrawPoolAlpha::render(S32 pass) void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) { - for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) + for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && @@ -392,7 +392,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) BOOL use_shaders = gPipeline.canUseVertexShaders(); - for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) + for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; llassert(group); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index a37f117c4..3e818faa4 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1203,15 +1203,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (pass >= 7 && pass < 9) { - LLGLEnable blend(GL_BLEND); - - gGL.setColorMask(true, true); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA, - LLRender::BF_ZERO, - LLRender::BF_ONE_MINUS_SOURCE_ALPHA); - - if (pass == 7) { renderRiggedAlpha(avatarp); @@ -1227,20 +1218,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (pass == 9) { - LLGLEnable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.flush(); - - LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(-1.0f, -1.0f); - gGL.setSceneBlendType(LLRender::BT_ADD); - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - gGL.setColorMask(false, true); - renderRiggedGlow(avatarp); - gGL.setColorMask(true, false); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + return; } @@ -1640,17 +1619,56 @@ void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar) void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) { - renderRigged(avatar, RIGGED_ALPHA); + if (!mRiggedFace[RIGGED_ALPHA].empty()) + { + LLGLEnable blend(GL_BLEND); + + gGL.setColorMask(true, true); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA, + LLRender::BF_ZERO, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + + renderRigged(avatar, RIGGED_ALPHA); + } } void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) { - renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); + if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty()) + { + LLGLEnable blend(GL_BLEND); + + gGL.setColorMask(true, true); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA, + LLRender::BF_ZERO, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + + renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); + } } void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) { - renderRigged(avatar, RIGGED_GLOW, true); + if (!mRiggedFace[RIGGED_GLOW].empty()) + { + LLGLEnable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.flush(); + + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -1.0f); + gGL.setSceneBlendType(LLRender::BT_ADD); + + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.setColorMask(false, true); + + renderRigged(avatar, RIGGED_GLOW, true); + + gGL.setColorMask(true, false); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 65ab71abc..60af91ac8 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -848,12 +848,12 @@ void LLDrawPoolBump::renderDeferred(S32 pass) LLFastTimer ftm(FTM_RENDER_BUMP); U32 type = LLRenderPass::PASS_BUMP; - LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type); - LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type); + LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; - for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i) + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo& params = **i; @@ -1449,10 +1449,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI void LLDrawPoolBump::renderBump(U32 type, U32 mask) { - LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type); - LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type); + LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); + LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i) + for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo& params = **i; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 2d476dfbb..55e3b758f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -4476,29 +4476,64 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) } LLCullResult::LLCullResult() -{ +{ + mVisibleGroupsAllocated = 0; + mAlphaGroupsAllocated = 0; + mOcclusionGroupsAllocated = 0; + mDrawableGroupsAllocated = 0; + mVisibleListAllocated = 0; + mVisibleBridgeAllocated = 0; + + mVisibleGroups = NULL; + mVisibleGroupsEnd = NULL; + mAlphaGroups = NULL; + mAlphaGroupsEnd = NULL; + mOcclusionGroups = NULL; + mOcclusionGroupsEnd = NULL; + mDrawableGroups = NULL; + mDrawableGroupsEnd = NULL; + mVisibleList = NULL; + mVisibleListEnd = NULL; + mVisibleBridge = NULL; + mVisibleBridgeEnd = NULL; + + for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) + { + mRenderMap[i] = NULL; + mRenderMapEnd[i] = NULL; + mRenderMapAllocated[i] = 0; + } + clear(); } +void LLCullResult::pushBack(void**& head, U32& count, void* val) +{ + count++; + head = (void**) realloc((void*) head, sizeof(void*) * count); + head[count-1] = val; +} + void LLCullResult::clear() { mVisibleGroupsSize = 0; - mVisibleGroupsEnd = mVisibleGroups.begin(); + mVisibleGroupsEnd = mVisibleGroups; mAlphaGroupsSize = 0; - mAlphaGroupsEnd = mAlphaGroups.begin(); + mAlphaGroupsEnd = mAlphaGroups; mOcclusionGroupsSize = 0; - mOcclusionGroupsEnd = mOcclusionGroups.begin(); + mOcclusionGroupsEnd = mOcclusionGroups; mDrawableGroupsSize = 0; - mDrawableGroupsEnd = mDrawableGroups.begin(); + mDrawableGroupsEnd = mDrawableGroups; mVisibleListSize = 0; - mVisibleListEnd = mVisibleList.begin(); + mVisibleListEnd = mVisibleList; mVisibleBridgeSize = 0; - mVisibleBridgeEnd = mVisibleBridge.begin(); + mVisibleBridgeEnd = mVisibleBridge; + for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) { @@ -4507,176 +4542,176 @@ void LLCullResult::clear() mRenderMap[i][j] = 0; } mRenderMapSize[i] = 0; - mRenderMapEnd[i] = mRenderMap[i].begin(); + mRenderMapEnd[i] = mRenderMap[i]; } } -LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups() +LLCullResult::sg_iterator LLCullResult::beginVisibleGroups() { - return mVisibleGroups.begin(); + return mVisibleGroups; } -LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups() +LLCullResult::sg_iterator LLCullResult::endVisibleGroups() { return mVisibleGroupsEnd; } -LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() +LLCullResult::sg_iterator LLCullResult::beginAlphaGroups() { - return mAlphaGroups.begin(); + return mAlphaGroups; } -LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups() +LLCullResult::sg_iterator LLCullResult::endAlphaGroups() { return mAlphaGroupsEnd; } -LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() +LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups() { - return mOcclusionGroups.begin(); + return mOcclusionGroups; } -LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups() +LLCullResult::sg_iterator LLCullResult::endOcclusionGroups() { return mOcclusionGroupsEnd; } -LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() +LLCullResult::sg_iterator LLCullResult::beginDrawableGroups() { - return mDrawableGroups.begin(); + return mDrawableGroups; } -LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups() +LLCullResult::sg_iterator LLCullResult::endDrawableGroups() { return mDrawableGroupsEnd; } -LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() +LLCullResult::drawable_iterator LLCullResult::beginVisibleList() { - return mVisibleList.begin(); + return mVisibleList; } -LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList() +LLCullResult::drawable_iterator LLCullResult::endVisibleList() { return mVisibleListEnd; } -LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() +LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge() { - return mVisibleBridge.begin(); + return mVisibleBridge; } -LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge() +LLCullResult::bridge_iterator LLCullResult::endVisibleBridge() { return mVisibleBridgeEnd; } -LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type) { - return mRenderMap[type].begin(); + return mRenderMap[type]; } -LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type) { return mRenderMapEnd[type]; } void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) { - if (mVisibleGroupsSize < mVisibleGroups.size()) + if (mVisibleGroupsSize < mVisibleGroupsAllocated) { mVisibleGroups[mVisibleGroupsSize] = group; } else { - mVisibleGroups.push_back(group); + pushBack((void**&) mVisibleGroups, mVisibleGroupsAllocated, (void*) group); } ++mVisibleGroupsSize; - mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize; + mVisibleGroupsEnd = mVisibleGroups+mVisibleGroupsSize; } void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) { - if (mAlphaGroupsSize < mAlphaGroups.size()) + if (mAlphaGroupsSize < mAlphaGroupsAllocated) { mAlphaGroups[mAlphaGroupsSize] = group; } else { - mAlphaGroups.push_back(group); + pushBack((void**&) mAlphaGroups, mAlphaGroupsAllocated, (void*) group); } ++mAlphaGroupsSize; - mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize; + mAlphaGroupsEnd = mAlphaGroups+mAlphaGroupsSize; } void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) { - if (mOcclusionGroupsSize < mOcclusionGroups.size()) + if (mOcclusionGroupsSize < mOcclusionGroupsAllocated) { mOcclusionGroups[mOcclusionGroupsSize] = group; } else { - mOcclusionGroups.push_back(group); + pushBack((void**&) mOcclusionGroups, mOcclusionGroupsAllocated, (void*) group); } ++mOcclusionGroupsSize; - mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize; + mOcclusionGroupsEnd = mOcclusionGroups+mOcclusionGroupsSize; } void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) { - if (mDrawableGroupsSize < mDrawableGroups.size()) + if (mDrawableGroupsSize < mDrawableGroupsAllocated) { mDrawableGroups[mDrawableGroupsSize] = group; } else { - mDrawableGroups.push_back(group); + pushBack((void**&) mDrawableGroups, mDrawableGroupsAllocated, (void*) group); } ++mDrawableGroupsSize; - mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize; + mDrawableGroupsEnd = mDrawableGroups+mDrawableGroupsSize; } void LLCullResult::pushDrawable(LLDrawable* drawable) { - if (mVisibleListSize < mVisibleList.size()) + if (mVisibleListSize < mVisibleListAllocated) { mVisibleList[mVisibleListSize] = drawable; } else { - mVisibleList.push_back(drawable); + pushBack((void**&) mVisibleList, mVisibleListAllocated, (void*) drawable); } ++mVisibleListSize; - mVisibleListEnd = mVisibleList.begin()+mVisibleListSize; + mVisibleListEnd = mVisibleList+mVisibleListSize; } void LLCullResult::pushBridge(LLSpatialBridge* bridge) { - if (mVisibleBridgeSize < mVisibleBridge.size()) + if (mVisibleBridgeSize < mVisibleBridgeAllocated) { mVisibleBridge[mVisibleBridgeSize] = bridge; } else { - mVisibleBridge.push_back(bridge); + pushBack((void**&) mVisibleBridge, mVisibleBridgeAllocated, (void*) bridge); } ++mVisibleBridgeSize; - mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize; + mVisibleBridgeEnd = mVisibleBridge+mVisibleBridgeSize; } void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) { - if (mRenderMapSize[type] < mRenderMap[type].size()) + if (mRenderMapSize[type] < mRenderMapAllocated[type]) { mRenderMap[type][mRenderMapSize[type]] = draw_info; } else { - mRenderMap[type].push_back(draw_info); + pushBack((void**&) mRenderMap[type], mRenderMapAllocated[type], (void*) draw_info); } ++mRenderMapSize[type]; - mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type]; + mRenderMapEnd[type] = mRenderMap[type] + mRenderMapSize[type]; } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 95ba1c036..d86221ddc 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -522,34 +522,39 @@ class LLCullResult public: LLCullResult(); - typedef std::vector sg_list_t; - typedef std::vector drawable_list_t; - typedef std::vector bridge_list_t; - typedef std::vector drawinfo_list_t; + typedef LLSpatialGroup** sg_list_t; + typedef LLDrawable** drawable_list_t; + typedef LLSpatialBridge** bridge_list_t; + typedef LLDrawInfo** drawinfo_list_t; + + typedef LLSpatialGroup** sg_iterator; + typedef LLSpatialBridge** bridge_iterator; + typedef LLDrawInfo** drawinfo_iterator; + typedef LLDrawable** drawable_iterator; void clear(); - sg_list_t::iterator beginVisibleGroups(); - sg_list_t::iterator endVisibleGroups(); + sg_iterator beginVisibleGroups(); + sg_iterator endVisibleGroups(); - sg_list_t::iterator beginAlphaGroups(); - sg_list_t::iterator endAlphaGroups(); + sg_iterator beginAlphaGroups(); + sg_iterator endAlphaGroups(); bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } - sg_list_t::iterator beginOcclusionGroups(); - sg_list_t::iterator endOcclusionGroups(); + sg_iterator beginOcclusionGroups(); + sg_iterator endOcclusionGroups(); - sg_list_t::iterator beginDrawableGroups(); - sg_list_t::iterator endDrawableGroups(); + sg_iterator beginDrawableGroups(); + sg_iterator endDrawableGroups(); - drawable_list_t::iterator beginVisibleList(); - drawable_list_t::iterator endVisibleList(); + drawable_iterator beginVisibleList(); + drawable_iterator endVisibleList(); - bridge_list_t::iterator beginVisibleBridge(); - bridge_list_t::iterator endVisibleBridge(); + bridge_iterator beginVisibleBridge(); + bridge_iterator endVisibleBridge(); - drawinfo_list_t::iterator beginRenderMap(U32 type); - drawinfo_list_t::iterator endRenderMap(U32 type); + drawinfo_iterator beginRenderMap(U32 type); + drawinfo_iterator endRenderMap(U32 type); void pushVisibleGroup(LLSpatialGroup* group); void pushAlphaGroup(LLSpatialGroup* group); @@ -569,28 +574,41 @@ public: void assertDrawMapsEmpty(); private: + + void pushBack(void** &head, U32& count, void* val); + U32 mVisibleGroupsSize; U32 mAlphaGroupsSize; U32 mOcclusionGroupsSize; U32 mDrawableGroupsSize; U32 mVisibleListSize; U32 mVisibleBridgeSize; + + U32 mVisibleGroupsAllocated; + U32 mAlphaGroupsAllocated; + U32 mOcclusionGroupsAllocated; + U32 mDrawableGroupsAllocated; + U32 mVisibleListAllocated; + U32 mVisibleBridgeAllocated; + U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES]; sg_list_t mVisibleGroups; - sg_list_t::iterator mVisibleGroupsEnd; + sg_iterator mVisibleGroupsEnd; sg_list_t mAlphaGroups; - sg_list_t::iterator mAlphaGroupsEnd; + sg_iterator mAlphaGroupsEnd; sg_list_t mOcclusionGroups; - sg_list_t::iterator mOcclusionGroupsEnd; + sg_iterator mOcclusionGroupsEnd; sg_list_t mDrawableGroups; - sg_list_t::iterator mDrawableGroupsEnd; + sg_iterator mDrawableGroupsEnd; drawable_list_t mVisibleList; - drawable_list_t::iterator mVisibleListEnd; + drawable_iterator mVisibleListEnd; bridge_list_t mVisibleBridge; - bridge_list_t::iterator mVisibleBridgeEnd; + bridge_iterator mVisibleBridgeEnd; drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; - drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; + U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES]; + drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; + }; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 27632dcfc..f6cdbba74 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1815,19 +1815,19 @@ void LLPipeline::checkReferences(LLFace* face) #if 0 if (sCull) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, face); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, face); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, face); @@ -1847,19 +1847,19 @@ void LLPipeline::checkReferences(LLDrawable* drawable) #if 0 if (sCull) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, drawable); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, drawable); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, drawable); @@ -1898,19 +1898,19 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info) #if 0 if (sCull) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, draw_info); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, draw_info); } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; check_references(group, draw_info); @@ -1924,7 +1924,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group) #if 0 if (sCull) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { if (group == *iter) { @@ -1932,7 +1932,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group) } } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) { if (group == *iter) { @@ -1940,7 +1940,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group) } } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { if (group == *iter) { @@ -2282,7 +2282,7 @@ void LLPipeline::doOcclusion(LLCamera& camera) } mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) { LLSpatialGroup* group = *iter; group->doOcclusion(&camera); @@ -2816,7 +2816,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) //LLVertexBuffer::unbind(); grabReferences(result); - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); @@ -2842,9 +2842,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { LLSpatialGroup* last_group = NULL; - for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { - LLCullResult::bridge_list_t::iterator cur_iter = i; + LLCullResult::bridge_iterator cur_iter = i; LLSpatialBridge* bridge = *cur_iter; LLSpatialGroup* group = bridge->getSpatialGroup(); @@ -2874,7 +2874,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); @@ -2896,7 +2896,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { LLFastTimer ftm(FTM_STATESORT_DRAWABLE); - for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); + for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) { LLDrawable *drawablep = *iter; @@ -3045,11 +3045,11 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } -void forAllDrawables(LLCullResult::sg_list_t::iterator begin, - LLCullResult::sg_list_t::iterator end, +void forAllDrawables(LLCullResult::sg_iterator begin, + LLCullResult::sg_iterator end, void (*func)(LLDrawable*)) { - for (LLCullResult::sg_list_t::iterator i = begin; i != end; ++i) + for (LLCullResult::sg_iterator i = begin; i != end; ++i) { for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j) { @@ -3219,7 +3219,7 @@ void LLPipeline::postSort(LLCamera& camera) llpushcallstacks ; //rebuild drawable geometry - for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) + for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) { LLSpatialGroup* group = *i; if (!sUseOcclusion || @@ -3237,7 +3237,7 @@ void LLPipeline::postSort(LLCamera& camera) //build render map - for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; @@ -4179,7 +4179,7 @@ void LLPipeline::renderPhysicsDisplay() } } - for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) @@ -4238,7 +4238,7 @@ void LLPipeline::renderDebug() } } - for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) @@ -9328,7 +9328,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) { - for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) + for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; if (!group->isDead() && @@ -9593,22 +9593,22 @@ BOOL LLPipeline::hasRenderBatches(const U32 type) const return sCull->getRenderMapSize(type) > 0; } -LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type) { return sCull->beginRenderMap(type); } -LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type) +LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type) { return sCull->endRenderMap(type); } -LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups() +LLCullResult::sg_iterator LLPipeline::beginAlphaGroups() { return sCull->beginAlphaGroups(); } -LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() +LLCullResult::sg_iterator LLPipeline::endAlphaGroups() { return sCull->endAlphaGroups(); } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 4ad8a5e19..3a89ca0a0 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -296,10 +296,10 @@ public: void setLight(LLDrawable *drawablep, BOOL is_light); BOOL hasRenderBatches(const U32 type) const; - LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type); - LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type); - LLCullResult::sg_list_t::iterator beginAlphaGroups(); - LLCullResult::sg_list_t::iterator endAlphaGroups(); + LLCullResult::drawinfo_iterator beginRenderMap(U32 type); + LLCullResult::drawinfo_iterator endRenderMap(U32 type); + LLCullResult::sg_iterator beginAlphaGroups(); + LLCullResult::sg_iterator endAlphaGroups(); void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); From cc5ffafd7c5696d084761cdb99c013aacaee5dee Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 17 Jul 2012 23:54:10 -0500 Subject: [PATCH 002/103] MAINT-646: Add a lookup map for joints to remove hotspot in LLJoint::findJoint https://bitbucket.org/davep/viewer-development/changeset/15b05dc53770 --- indra/llcharacter/llcharacter.cpp | 5 ----- indra/llcharacter/llmotioncontroller.cpp | 1 + indra/newview/llvoavatar.cpp | 17 ++++++++++++++++- indra/newview/llvoavatar.h | 4 ++++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 85291530c..d62eb8da1 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -194,19 +194,14 @@ void LLCharacter::requestStopMotion( LLMotion* motion) //----------------------------------------------------------------------------- // updateMotions() //----------------------------------------------------------------------------- -static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation"); -static LLFastTimer::DeclareTimer FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim"); - void LLCharacter::updateMotions(e_update_t update_type) { if (update_type == HIDDEN_UPDATE) { - LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION); mMotionController.updateMotionsMinimal(); } else { - LLFastTimer t(FTM_UPDATE_ANIMATION); // unpause if the number of outstanding pause requests has dropped to the initial one if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1) { diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index 3b7dbec33..f0c95560e 100644 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -837,6 +837,7 @@ void LLMotionController::updateMotions(bool force_update) } updateLoadingMotions(); + return; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 5c4d540ea..d7a6628f2 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1179,6 +1179,7 @@ LLVOAvatar::~LLVOAvatar() lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl; mRoot.removeAllChildren(); + mJointMap.clear(); deleteAndClearArray(mSkeleton); deleteAndClearArray(mCollisionVolumes); @@ -2340,6 +2341,7 @@ void LLVOAvatar::buildCharacter() // remove all of mRoot's children //------------------------------------------------------------------------- mRoot.removeAllChildren(); + mJointMap.clear(); mIsBuilt = FALSE; //------------------------------------------------------------------------- @@ -5887,7 +5889,20 @@ const LLUUID& LLVOAvatar::getID() const // RN: avatar joints are multi-rooted to include screen-based attachments LLJoint *LLVOAvatar::getJoint( const std::string &name ) { - LLJoint* jointp = mRoot.findJoint(name); + joint_map_t::iterator iter = mJointMap.find(name); + + LLJoint* jointp = NULL; + + if (iter == mJointMap.end() || iter->second == NULL) + { //search for joint and cache found joint in lookup table + jointp = mRoot.findJoint(name); + mJointMap[name] = jointp; + } + else + { //return cached pointer + jointp = iter->second; + } + return jointp; } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index e0d4b3bf5..81529a2f3 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -376,6 +376,10 @@ public: LLVector3 mHeadOffset; // current head position LLViewerJoint mRoot; + + typedef std::map joint_map_t; + joint_map_t mJointMap; + protected: static BOOL parseSkeletonFile(const std::string& filename); void buildCharacter(); From a56ad597d414b9604ae1bad32ab883adc55f8e78 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 00:54:52 -0500 Subject: [PATCH 003/103] MAINT-646: Factor std::set out of lloctree https://bitbucket.org/davep/viewer-development/changeset/52b6c9168974 --- indra/llmath/lloctree.h | 131 +++++++++++++++++++-------- indra/llmath/llvolume.cpp | 6 +- indra/llmath/llvolumeoctree.cpp | 6 +- indra/llmath/llvolumeoctree.h | 7 +- indra/newview/lldrawable.cpp | 26 +++++- indra/newview/lldrawable.h | 6 +- indra/newview/llface.cpp | 22 +++-- indra/newview/llspatialpartition.cpp | 48 +++++----- indra/newview/llspatialpartition.h | 5 + indra/newview/llvograss.cpp | 2 +- indra/newview/llvopartgroup.cpp | 2 +- indra/newview/llvovolume.cpp | 29 ++++-- indra/newview/pipeline.cpp | 14 +-- 13 files changed, 208 insertions(+), 96 deletions(-) diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index c8a0875f5..9a5918849 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -89,9 +89,9 @@ public: typedef LLOctreeTraveler oct_traveler; typedef LLTreeTraveler tree_traveler; - typedef typename std::set > element_list; - typedef typename element_list::iterator element_iter; - typedef typename element_list::const_iterator const_element_iter; + typedef LLPointer* element_list; + typedef LLPointer* element_iter; + typedef const LLPointer* const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; typedef typename std::vector* > child_list; typedef LLTreeNode BaseType; @@ -115,6 +115,9 @@ public: : mParent((oct_node*)parent), mOctant(octant) { + mData = NULL; + mDataEnd = NULL; + mCenter = center; mSize = size; @@ -133,6 +136,16 @@ public: { BaseType::destroyListeners(); + for (U32 i = 0; i < mElementCount; ++i) + { + mData[i]->setBinIndex(-1); + mData[i] = NULL; + } + + free(mData); + mData = NULL; + mDataEnd = NULL; + for (U32 i = 0; i < getChildCount(); i++) { delete getChild(i); @@ -232,9 +245,14 @@ public: virtual bool isLeaf() const { return mChild.empty(); } U32 getElementCount() const { return mElementCount; } + bool isEmpty() const { return mElementCount == 0; } element_list& getData() { return mData; } const element_list& getData() const { return mData; } - + element_iter getDataBegin() { return mData; } + element_iter getDataEnd() { return mDataEnd; } + const_element_iter getDataBegin() const { return mData; } + const_element_iter getDataEnd() const { return mDataEnd; } + U32 getChildCount() const { return mChildCount; } oct_node* getChild(U32 index) { return mChild[index]; } const oct_node* getChild(U32 index) const { return mChild[index]; } @@ -299,7 +317,7 @@ public: virtual bool insert(T* data) { - if (data == NULL) + if (data == NULL || data->getBinIndex() != -1) { OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl; return false; @@ -309,22 +327,19 @@ public: //is it here? if (isInside(data->getPositionGroup())) { - if (((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius())) || + if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) || (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here -#if LL_OCTREE_PARANOIA_CHECK - //if this is a redundant insertion, error out (should never happen) - if (mData.find(data) != mData.end()) - { - llwarns << "Redundant octree insertion detected. " << data << llendl; - return false; - } -#endif + mElementCount++; + mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); - mData.insert(data); + //avoid unref on uninitialized memory + memset(mData+mElementCount-1, 0, sizeof(LLPointer)); + + mData[mElementCount-1] = data; + mDataEnd = mData + mElementCount; + data->setBinIndex(mElementCount-1); BaseType::insert(data); - - mElementCount = mData.size(); return true; } else @@ -358,10 +373,16 @@ public: if( lt == 0x7 ) { - mData.insert(data); - BaseType::insert(data); + mElementCount++; + mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); - mElementCount = mData.size(); + //avoid unref on uninitialized memory + memset(mData+mElementCount-1, 0, sizeof(LLPointer)); + + mData[mElementCount-1] = data; + mDataEnd = mData + mElementCount; + data->setBinIndex(mElementCount-1); + BaseType::insert(data); return true; } @@ -410,23 +431,59 @@ public: return false; } + void _remove(T* data, S32 i) + { //precondition -- mElementCount > 0, idx is in range [0, mElementCount) + + mElementCount--; + data->setBinIndex(-1); + + if (mElementCount > 0) + { + if (mElementCount != i) + { + mData[i] = mData[mElementCount]; //might unref data, do not access data after this point + mData[i]->setBinIndex(i); + } + + mData[mElementCount] = NULL; //needed for unref + mData = (element_list) realloc(mData, sizeof(LLPointer)*mElementCount); + mDataEnd = mData+mElementCount; + } + else + { + mData[0] = NULL; //needed for unref + free(mData); + mData = NULL; + mDataEnd = NULL; + } + + notifyRemoval(data); + checkAlive(); + } + bool remove(T* data) { - if (mData.find(data) != mData.end()) - { //we have data - mData.erase(data); - mElementCount = mData.size(); - this->notifyRemoval(data); - checkAlive(); - return true; + S32 i = data->getBinIndex(); + + if (i >= 0 && i < (S32)mElementCount) + { + if (mData[i] == data) + { //found it + _remove(data, i); + llassert(data->getBinIndex() == -1); + return true; + } } - else if (isInside(data)) + + if (isInside(data)) { oct_node* dest = getNodeAt(data); if (dest != this) { - return dest->remove(data); + bool ret = dest->remove(data); + llassert(data->getBinIndex() == -1); + return ret; } } @@ -445,19 +502,20 @@ public: //node is now root llwarns << "!!! OCTREE REMOVING FACE BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl; node->removeByAddress(data); + llassert(data->getBinIndex() == -1); return true; } void removeByAddress(T* data) { - if (mData.find(data) != mData.end()) + for (U32 i = 0; i < mElementCount; ++i) { - mData.erase(data); - mElementCount = mData.size(); - this->notifyRemoval(data); - llwarns << "FOUND!" << llendl; - checkAlive(); - return; + if (mData[i] == data) + { //we have data + _remove(data, i); + llwarns << "FOUND!" << llendl; + return; + } } for (U32 i = 0; i < getChildCount(); i++) @@ -624,6 +682,7 @@ protected: U32 mChildCount; element_list mData; + element_iter mDataEnd; U32 mElementCount; }; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8b47a92ea..99094ce23 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -324,16 +324,16 @@ public: LLVector4a& min = node->mExtents[0]; LLVector4a& max = node->mExtents[1]; - if (!branch->getData().empty()) + if (!branch->isEmpty()) { //node has data, find AABB that binds data set - const LLVolumeTriangle* tri = *(branch->getData().begin()); + const LLVolumeTriangle* tri = *(branch->getDataBegin()); //initialize min/max to first available vertex min = *(tri->mV[0]); max = *(tri->mV[0]); for (LLOctreeNode::const_element_iter iter = - branch->getData().begin(); iter != branch->getData().end(); ++iter) + branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { //for each triangle in node //stretch by triangles in node diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index d5bd5a78d..cf9aeece8 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -131,7 +131,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode* node) { for (LLOctreeNode::const_element_iter iter = - node->getData().begin(); iter != node->getData().end(); ++iter) + node->getDataBegin(); iter != node->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -236,8 +236,8 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) } //children fit, check data - for (LLOctreeNode::const_element_iter iter = branch->getData().begin(); - iter != branch->getData().end(); ++iter) + for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); + iter != branch->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 688d91dc4..c25e37f1a 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -39,7 +39,7 @@ class LLVolumeTriangle : public LLRefCount public: LLVolumeTriangle() { - + mBinIndex = -1; } LLVolumeTriangle(const LLVolumeTriangle& rhs) @@ -64,9 +64,14 @@ public: U16 mIndex[3]; F32 mRadius; + mutable S32 mBinIndex; + virtual const LLVector4a& getPositionGroup() const; virtual const F32& getBinRadius() const; + + S32 getBinIndex() const { return mBinIndex; } + void setBinIndex(S32 idx) const { mBinIndex = idx; } }; class LLVolumeOctreeListener : public LLOctreeListener diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index b9df32f06..89e26ccb1 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -113,6 +113,7 @@ void LLDrawable::init() mGeneration = -1; mBinRadius = 1.f; + mBinIndex = -1; mSpatialBridge = NULL; } @@ -963,6 +964,12 @@ void LLDrawable::updateUVMinMax() { } +LLSpatialGroup* LLDrawable::getSpatialGroup() const +{ + llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); + return mSpatialGroupp; +} + void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { /*if (mSpatialGroupp && (groupp != mSpatialGroupp)) @@ -985,6 +992,8 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) } mSpatialGroupp = groupp; + + llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); } LLSpatialPartition* LLDrawable::getSpatialPartition() @@ -1107,6 +1116,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat mDrawable = root; root->setSpatialBridge(this); + mBinIndex = -1; + mRenderType = mDrawable->mRenderType; mDrawableType = mDrawable->mRenderType; @@ -1500,7 +1511,13 @@ void LLSpatialBridge::cleanupReferences() LLDrawable::cleanupReferences(); if (mDrawable) { - mDrawable->setSpatialGroup(NULL); + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->mOctreeNode->remove(mDrawable); + mDrawable->setSpatialGroup(NULL); + } + if (mDrawable->getVObj()) { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); @@ -1511,7 +1528,12 @@ void LLSpatialBridge::cleanupReferences() LLDrawable* drawable = child->mDrawable; if (drawable) { - drawable->setSpatialGroup(NULL); + LLSpatialGroup* group = drawable->getSpatialGroup(); + if (group) + { + group->mOctreeNode->remove(drawable); + drawable->setSpatialGroup(NULL); + } } } } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 6f07c82be..bd2d23c5f 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -115,6 +115,9 @@ public: F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } F32 getBinRadius() const { return mBinRadius; } + S32 getBinIndex() const { return mBinIndex; } + void setBinIndex(S32 index) const { mBinIndex = index; } + void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -200,7 +203,7 @@ public: S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators... void setSpatialGroup(LLSpatialGroup *groupp); - LLSpatialGroup *getSpatialGroup() const { return mSpatialGroupp; } + LLSpatialGroup *getSpatialGroup() const; LLSpatialPartition* getSpatialPartition(); // Statics @@ -321,6 +324,7 @@ private: mutable U32 mVisible; F32 mRadius; F32 mBinRadius; + mutable S32 mBinIndex; S32 mGeneration; LLVector3 mCurrentScale; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index e52bb5959..38e41c6b4 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1209,19 +1209,25 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) { - llwarns << "Index buffer overflow!" << llendl; - llwarns << "Indices Count: " << mIndicesCount - << " VF Num Indices: " << num_indices - << " Indices Index: " << mIndicesIndex - << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl; - llwarns << " Face Index: " << f - << " Pool Type: " << mPoolType << llendl; + if (gDebugGL) + { + llwarns << "Index buffer overflow!" << llendl; + llwarns << "Indices Count: " << mIndicesCount + << " VF Num Indices: " << num_indices + << " Indices Index: " << mIndicesIndex + << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl; + llwarns << " Face Index: " << f + << " Pool Type: " << mPoolType << llendl; + } return FALSE; } if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts()) { - llwarns << "Vertex buffer overflow!" << llendl; + if (gDebugGL) + { + llwarns << "Vertex buffer overflow!" << llendl; + } return FALSE; } } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 55e3b758f..784a0e69c 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -424,7 +424,7 @@ void LLSpatialGroup::validate() validateDrawMap(); - for (element_iter i = getData().begin(); i != getData().end(); ++i) + for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { LLDrawable* drawable = *i; sg_assert(drawable->getSpatialGroup() == this); @@ -640,7 +640,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma { const OctreeNode* node = mOctreeNode; - if (node->getData().empty()) + if (node->isEmpty()) { //don't do anything if there are no objects if (empty && mOctreeNode->getParent()) { //only root is allowed to be empty @@ -657,14 +657,14 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma clearState(OBJECT_DIRTY); //initialize bounding box to first element - OctreeNode::const_element_iter i = node->getData().begin(); + OctreeNode::const_element_iter i = node->getDataBegin(); LLDrawable* drawablep = *i; const LLVector4a* minMax = drawablep->getSpatialExtents(); newMin = minMax[0]; newMax = minMax[1]; - for (++i; i != node->getData().end(); ++i) + for (++i; i != node->getDataEnd(); ++i) { drawablep = *i; minMax = drawablep->getSpatialExtents(); @@ -1124,7 +1124,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) llerrs << "Spatial group dirty on distance update." << llendl; } #endif - if (!getData().empty() /*&& !LLSpatialPartition::sFreezeState*/) + if (!isEmpty() /*&& !LLSpatialPartition::sFreezeState*/) { mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : (F32) mOctreeNode->getSize().getLength3().getF32(); @@ -1276,7 +1276,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); setState(DEAD); - for (element_iter i = getData().begin(); i != getData().end(); ++i) + for (element_iter i = getDataBegin(); i != getDataEnd(); ++i) { LLDrawable* drawable = *i; if (drawable->getSpatialGroup() == this) @@ -1363,7 +1363,7 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) } - for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) + for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i) { LLDrawable* drawable = *i; for (S32 j = 0; j < drawable->getNumFaces(); j++) @@ -1720,12 +1720,14 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - drawablep->setSpatialGroup(NULL); - if (!curp->removeObject(drawablep)) { OCT_ERRS << "Failed to remove drawable from octree!" << llendl; } + else + { + drawablep->setSpatialGroup(NULL); + } assert_octree_valid(mOctree); @@ -1996,7 +1998,7 @@ public: virtual void processGroup(LLSpatialGroup* group) { - llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty()) + llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty()) if (mRes < 2) { @@ -2063,7 +2065,7 @@ public: { LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { LLDrawable* drawable = *i; @@ -2187,7 +2189,7 @@ public: LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); group->destroyGL(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawable = *i; if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) @@ -2500,7 +2502,7 @@ void renderOctree(LLSpatialGroup* group) gGL.flush(); glLineWidth(1.f); gGL.flush(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawable = *i; if (!group->mSpatialPartition->isBridge()) @@ -2546,7 +2548,7 @@ void renderOctree(LLSpatialGroup* group) } else { - if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty() + if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty() && group->mSpatialPartition->mRenderByGroup) { col.setVec(0.8f, 0.4f, 0.1f, 0.1f); @@ -2614,7 +2616,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && - !group->getData().empty(); + !group->isEmpty(); if (render_objects) { @@ -3356,7 +3358,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) void renderPhysicsShapes(LLSpatialGroup* group) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawable = *i; LLVOVolume* volume = drawable->getVOVolume(); @@ -3601,7 +3603,7 @@ public: LLVector3 center, size; - if (branch->getData().empty()) + if (branch->isEmpty()) { gGL.diffuseColor3f(1.f,0.2f,0.f); center.set(branch->getCenter().getF32ptr()); @@ -3637,8 +3639,8 @@ public: } gGL.begin(LLRender::TRIANGLES); - for (LLOctreeNode::const_element_iter iter = branch->getData().begin(); - iter != branch->getData().end(); + for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); + iter != branch->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -3875,7 +3877,7 @@ public: if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) { - if (!group->getData().empty()) + if (!group->isEmpty()) { gGL.diffuseColor3f(0,0,1); drawBoxOutline(group->mObjectBounds[0], @@ -3883,7 +3885,7 @@ public: } } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { LLDrawable* drawable = *i; @@ -4068,7 +4070,7 @@ public: return; } - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { LLDrawable* drawable = *i; @@ -4291,7 +4293,7 @@ public: virtual void visit(const LLSpatialGroup::OctreeNode* branch) { - for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) { check(*i); } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index d86221ddc..890a52f0d 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -330,8 +330,13 @@ public: void dirtyGeom() { setState(GEOM_DIRTY); } void dirtyMesh() { setState(MESH_DIRTY); } + + //octree wrappers to make code more readable element_list& getData() { return mOctreeNode->getData(); } + element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } + element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } + bool isEmpty() const { return mOctreeNode->isEmpty(); } void drawObjectBox(LLColor4 col); diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 5a58ae770..6434dd619 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -645,7 +645,7 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count mFaceList.clear(); LLViewerCamera* camera = LLViewerCamera::getInstance(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawablep = *i; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 434c8ca64..3dee80cce 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -582,7 +582,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co mFaceList.clear(); LLViewerCamera* camera = LLViewerCamera::getInstance(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawablep = *i; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d8b34bd30..4431a9a33 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2390,7 +2390,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const produces_light = 1; } - for (S32 i = 0; i < num_faces; ++i) + for (S32 i = 0; i < (S32)num_faces; ++i) { const LLFace* face = drawablep->getFace(i); if (!face) continue; @@ -3481,7 +3481,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST); //get all the faces into a list - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; @@ -3887,7 +3887,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (!LLPipeline::sDelayVBUpdate) { //drawables have been rebuilt, clear rebuild status - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; drawablep->clearState(LLDrawable::REBUILD_ALL); @@ -3927,7 +3927,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) std::set mapped_buffers; - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; @@ -3951,8 +3951,14 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) if (buff) { llassert(!face->isState(LLFace::RIGGED)); - face->getGeometryVolume(*volume, face->getTEOffset(), - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); + + if (!face->getGeometryVolume(*volume, face->getTEOffset(), + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) + { //something's gone wrong with the vertex buffer accounting, rebuild this group + group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); + } + if (buff->isLocked()) { @@ -3993,7 +3999,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ; warningsCount = 1; } - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; for (S32 i = 0; i < drawablep->getNumFaces(); ++i) @@ -4294,8 +4300,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: llassert(!facep->isState(LLFace::RIGGED)); - facep->getGeometryVolume(*volume, te_idx, - vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true); + if (!facep->getGeometryVolume(*volume, te_idx, + vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true)) + { + llwarns << "Failed to get geometry for face!" << llendl; + } if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) { @@ -4464,7 +4473,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun //for each drawable - for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) + for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { LLDrawable* drawablep = *drawable_iter; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f6cdbba74..9235a7b2a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1174,7 +1174,7 @@ public: { LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty()) + if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) { for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) { @@ -1781,7 +1781,7 @@ void LLPipeline::clearReferences() void check_references(LLSpatialGroup* group, LLDrawable* drawable) { - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { if (drawable == *i) { @@ -1803,7 +1803,7 @@ void check_references(LLDrawable* drawable, LLFace* face) void check_references(LLSpatialGroup* group, LLFace* face) { - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawable = *i; check_references(drawable, face); @@ -2179,7 +2179,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) { - if (group->getData().empty()) + if (group->isEmpty()) { return; } @@ -2827,7 +2827,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) else { group->setVisible(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { markVisible(*i, camera); } @@ -2915,7 +2915,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); if (!sSkipUpdate && group->changeLOD()) { - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { LLDrawable* drawablep = *i; stateSort(drawablep, camera); @@ -3051,7 +3051,7 @@ void forAllDrawables(LLCullResult::sg_iterator begin, { for (LLCullResult::sg_iterator i = begin; i != end; ++i) { - for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j) + for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j) { func(*j); } From bf3e605d3b47cd715bb76c7789b825b3b164bf80 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 01:03:54 -0500 Subject: [PATCH 004/103] MAINT-646: Factor std::vector out of lloctree https://bitbucket.org/davep/viewer-development/changeset/efcec3eb374f --- indra/llmath/lloctree.h | 17 ++++++++++------- indra/llmath/llvolume.cpp | 2 +- indra/newview/llvovolume.cpp | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 9a5918849..07ca00913 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -37,7 +37,6 @@ #include "v3math.h" #include "llvector4a.h" #include -#include #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG #define OCT_ERRS LL_ERRS("OctreeErrors") @@ -93,7 +92,8 @@ public: typedef LLPointer* element_iter; typedef const LLPointer* const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; - typedef typename std::vector* > child_list; + typedef LLOctreeNode** child_list; + typedef LLOctreeNode** child_iter; typedef LLTreeNode BaseType; typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; @@ -242,7 +242,7 @@ public: } void accept(oct_traveler* visitor) { visitor->visit(this); } - virtual bool isLeaf() const { return mChild.empty(); } + virtual bool isLeaf() const { return mChildCount == 0; } U32 getElementCount() const { return mElementCount; } bool isEmpty() const { return mElementCount == 0; } @@ -527,8 +527,8 @@ public: void clearChildren() { - mChild.clear(); mChildCount = 0; + U32* foo = (U32*) mChildMap; foo[0] = foo[1] = 0xFFFFFFFF; } @@ -590,7 +590,7 @@ public: mChildMap[child->getOctant()] = mChildCount; - mChild.push_back(child); + mChild[mChildCount] = child; ++mChildCount; child->setParent(this); @@ -619,9 +619,12 @@ public: mChild[index]->destroy(); delete mChild[index]; } - mChild.erase(mChild.begin() + index); + --mChildCount; + mChild[index] = mChild[mChildCount]; + + //rebuild child map U32* foo = (U32*) mChildMap; foo[0] = foo[1] = 0xFFFFFFFF; @@ -677,7 +680,7 @@ protected: oct_node* mParent; U8 mOctant; - child_list mChild; + LLOctreeNode* mChild[8]; U8 mChildMap[8]; U32 mChildCount; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 99094ce23..54a88a570 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -348,7 +348,7 @@ public: max.setMax(max, *tri->mV[2]); } } - else if (!branch->getChildren().empty()) + else if (!branch->isLeaf()) { //no data, but child nodes exist LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 4431a9a33..ba9b6c994 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -430,8 +430,8 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { LLViewerObject::idleUpdate(agent, world, time); - static LLFastTimer::DeclareTimer ftm("Volume Idle"); - LLFastTimer t(ftm); + //static LLFastTimer::DeclareTimer ftm("Volume Idle"); + //LLFastTimer t(ftm); if (mDead || mDrawable.isNull()) { From 9c58d42a3c204821221d4be80ffbc1ac57cb0248 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 02:40:41 -0500 Subject: [PATCH 005/103] MAINT-646: Don't spend so much time fetching avatar physics params. https://bitbucket.org/davep/viewer-development/changeset/b895285ab0de --- indra/newview/llphysicsmotion.cpp | 117 ++++++++++++++++++++---------- indra/newview/llphysicsmotion.h | 37 ++++------ 2 files changed, 95 insertions(+), 59 deletions(-) diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index fbcd93912..1df29b37e 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -2,31 +2,25 @@ * @file llphysicsmotion.cpp * @brief Implementation of LLPhysicsMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2011, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -74,6 +68,19 @@ inline F64 llsgn(const F64 a) class LLPhysicsMotion { public: + typedef enum + { + SMOOTHING = 0, + MASS, + GRAVITY, + SPRING, + GAIN, + DAMPING, + DRAG, + MAX_EFFECT, + NUM_PARAMS + } eParamName; + /* param_driver_name: The param that controls the params that are being affected by the physics. joint_name: The joint that the body part is attached to. The joint is @@ -107,8 +114,12 @@ public: mVelocity_local(0) { mJointState = new LLJointState; - } + for (U32 i = 0; i < NUM_PARAMS; ++i) + { + mParamCache[i] = NULL; + } + } void getString(std::ostringstream &oss); BOOL initialize(); @@ -124,19 +135,46 @@ public: void reset(); protected: - F32 getParamValue(const std::string& controller_key) - { - const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key); + + F32 getParamValue(eParamName param) + { + static std::string controller_key[] = + { + "Smoothing", + "Mass", + "Gravity", + "Spring", + "Gain", + "Damping", + "Drag", + "MaxEffect" + }; + + if (!mParamCache[param]) + { + const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key[param]); if (entry == mParamControllers.end()) { - return sDefaultController[controller_key]; + return sDefaultController[controller_key[param]]; } const std::string& param_name = (*entry).second.c_str(); - return mCharacter->getVisualParamWeight(param_name.c_str()); - } + mParamCache[param] = mCharacter->getVisualParam(param_name.c_str()); + } + + if (mParamCache[param]) + { + return mParamCache[param]->getWeight(); + } + else + { + return sDefaultController[controller_key[param]]; + } + } + + void setParamValue(LLViewerVisualParam *param, const F32 new_value_local, - F32 behavior_maxeffect); + F32 behavior_maxeffect); F32 toLocal(const LLVector3 &world); F32 calculateVelocity_local(); @@ -164,6 +202,8 @@ private: F32 mLastTime; + LLVisualParam* mParamCache[NUM_PARAMS]; + static default_controller_map_t sDefaultController; }; @@ -268,7 +308,7 @@ void LLPhysicsMotion::getString(std::ostringstream &oss) oss << " Controllers:" << std::endl; for(controller_map_t::const_iterator it = mParamControllers.begin(); it!= mParamControllers.end(); ++it) { - oss << " mParamControllers[\"" << it->first << "\"] = \"" << it->second << "\" =" << getParamValue(it->first) << std::endl; + oss << " mParamControllers[\"" << it->first << "\"] = \"" << it->second << "\" =" << mCharacter->getVisualParamWeight(it->first.c_str()) << std::endl; } } @@ -574,15 +614,16 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) LLJoint *joint = mJointState->getJoint(); - const F32 behavior_mass = getParamValue("Mass"); - const F32 behavior_gravity = getParamValue("Gravity"); - const F32 behavior_spring = getParamValue("Spring"); - const F32 behavior_gain = getParamValue("Gain"); - const F32 behavior_damping = getParamValue("Damping"); - const F32 behavior_drag = getParamValue("Drag"); - const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts. + const F32 behavior_mass = getParamValue(MASS); + const F32 behavior_gravity = getParamValue(GRAVITY); + const F32 behavior_spring = getParamValue(SPRING); + const F32 behavior_gain = getParamValue(GAIN); + const F32 behavior_damping = getParamValue(DAMPING); + const F32 behavior_drag = getParamValue(DRAG); + F32 behavior_maxeffect = getParamValue(MAX_EFFECT); + + const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts. - F32 behavior_maxeffect = getParamValue("MaxEffect"); if (physics_test) behavior_maxeffect = 1.0f; diff --git a/indra/newview/llphysicsmotion.h b/indra/newview/llphysicsmotion.h index 7e6bddd17..7412c9d88 100644 --- a/indra/newview/llphysicsmotion.h +++ b/indra/newview/llphysicsmotion.h @@ -2,31 +2,25 @@ * @file llphysicsmotion.h * @brief Implementation of LLPhysicsMotion class. * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2011, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -113,6 +107,7 @@ public: virtual void onDeactivate(); LLCharacter* getCharacter() { return mCharacter; } + protected: void addMotion(LLPhysicsMotion *motion); private: From d57d0ceb0df1a549a3e97aa33030146d9b9da72c Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 03:04:12 -0500 Subject: [PATCH 006/103] MAINT-646: Vectorize LLPolyMesh https://bitbucket.org/davep/viewer-development/changeset/668dcacd6e76 --- indra/newview/lldriverparam.cpp | 26 ++- indra/newview/lldriverparam.h | 10 +- indra/newview/llpolymesh.cpp | 349 +++++++++++++++------------- indra/newview/llpolymesh.h | 52 ++--- indra/newview/llpolymorph.cpp | 294 ++++++++++++----------- indra/newview/llpolymorph.h | 18 +- indra/newview/lltexlayerparams.h | 20 +- indra/newview/llviewervisualparam.h | 8 +- 8 files changed, 424 insertions(+), 353 deletions(-) diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp index 93c437d2d..a1cba861c 100644 --- a/indra/newview/lldriverparam.cpp +++ b/indra/newview/lldriverparam.cpp @@ -155,6 +155,7 @@ LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) : mAvatarp(avatarp), mWearablep(NULL) { + mDefaultVec.clear(); } LLDriverParam::LLDriverParam(LLWearable *wearablep) : @@ -162,6 +163,7 @@ LLDriverParam::LLDriverParam(LLWearable *wearablep) : mAvatarp(NULL), mWearablep(wearablep) { + mDefaultVec.clear(); } LLDriverParam::~LLDriverParam() @@ -341,18 +343,19 @@ F32 LLDriverParam::getTotalDistortion() return sum; } -const LLVector3 &LLDriverParam::getAvgDistortion() +const LLVector4a &LLDriverParam::getAvgDistortion() { // It's not actually correct to take the average of averages, but it good enough here. - LLVector3 sum; + LLVector4a sum; + sum.clear(); S32 count = 0; for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ ) { LLDrivenEntry* driven = &(*iter); - sum += driven->mParam->getAvgDistortion(); + sum.add(driven->mParam->getAvgDistortion()); count++; } - sum /= (F32)count; + sum.mul( 1.f/(F32)count); mDefaultVec = sum; return mDefaultVec; @@ -375,21 +378,22 @@ F32 LLDriverParam::getMaxDistortion() } -LLVector3 LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) +LLVector4a LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { - LLVector3 sum; + LLVector4a sum; + sum.clear(); for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ ) { LLDrivenEntry* driven = &(*iter); - sum += driven->mParam->getVertexDistortion( index, poly_mesh ); + sum.add(driven->mParam->getVertexDistortion( index, poly_mesh )); } return sum; } -const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { mCurrentDistortionParam = NULL; - const LLVector3* v = NULL; + const LLVector4a* v = NULL; for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ ) { LLDrivenEntry* driven = &(*iter); @@ -404,7 +408,7 @@ const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly return v; }; -const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { llassert( mCurrentDistortionParam ); if( !mCurrentDistortionParam ) @@ -432,7 +436,7 @@ const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_ } // We're already in the middle of a param's distortions, so get the next one. - const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh ); + const LLVector4a* v = driven->mParam->getNextDistortion( index, poly_mesh ); if( (!v) && (iter != mDriven.end()) ) { // This param is finished, so start the next param. It might not have any diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h index fb1b44458..7a4d711d4 100644 --- a/indra/newview/lldriverparam.h +++ b/indra/newview/lldriverparam.h @@ -105,18 +105,18 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion(); - /*virtual*/ const LLVector3& getAvgDistortion(); + /*virtual*/ const LLVector4a& getAvgDistortion(); /*virtual*/ F32 getMaxDistortion(); - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); protected: F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight); void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake); - LLVector3 mDefaultVec; // temp holder + LLVector4a mDefaultVec; // temp holder typedef std::vector entry_list_t; entry_list_t mDriven; LLViewerVisualParam* mCurrentDistortionParam; diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index 491cf43f3..d7b342b25 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -229,16 +229,20 @@ U32 LLPolyMeshSharedData::getNumKB() BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices ) { U32 i; - mBaseCoords = new LLVector3[ numVertices ]; - mBaseNormals = new LLVector3[ numVertices ]; - mBaseBinormals = new LLVector3[ numVertices ]; + mBaseCoords = new LLVector4a[ numVertices ]; + mBaseNormals = new LLVector4a[ numVertices ]; + mBaseBinormals = new LLVector4a[ numVertices ]; mTexCoords = new LLVector2[ numVertices ]; mDetailTexCoords = new LLVector2[ numVertices ]; mWeights = new F32[ numVertices ]; for (i = 0; i < numVertices; i++) { + mBaseCoords[i].clear(); + mBaseNormals[i].clear(); + mBaseBinormals[i].clear(); + mTexCoords[i].clear(); mWeights[i] = 0.f; - } + } mNumVertices = numVertices; return TRUE; } @@ -408,40 +412,48 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName ) allocateVertexData( numVertices ); - //---------------------------------------------------------------- - // Coords - //---------------------------------------------------------------- - numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp); - llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices); - if (numRead != numVertices) + for (U16 i = 0; i < numVertices; ++i) { - llerrs << "can't read Coordinates from " << fileName << llendl; - return FALSE; - } + //---------------------------------------------------------------- + // Coords + //---------------------------------------------------------------- + numRead = fread(&mBaseCoords[i], sizeof(float), 3, fp); + llendianswizzle(&mBaseCoords[i], sizeof(float), 3); + if (numRead != 3) + { + llerrs << "can't read Coordinates from " << fileName << llendl; + return FALSE; + } + } - //---------------------------------------------------------------- - // Normals - //---------------------------------------------------------------- - numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp); - llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices); - if (numRead != numVertices) - { - llerrs << " can't read Normals from " << fileName << llendl; - return FALSE; - } + for (U16 i = 0; i < numVertices; ++i) + { + //---------------------------------------------------------------- + // Normals + //---------------------------------------------------------------- + numRead = fread(&mBaseNormals[i], sizeof(float), 3, fp); + llendianswizzle(&mBaseNormals[i], sizeof(float), 3); + if (numRead != 3) + { + llerrs << " can't read Normals from " << fileName << llendl; + return FALSE; + } + } - //---------------------------------------------------------------- - // Binormals - //---------------------------------------------------------------- - numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp); - llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices); - if (numRead != numVertices) - { - llerrs << " can't read Binormals from " << fileName << llendl; - return FALSE; + for (U16 i = 0; i < numVertices; ++i) + { + //---------------------------------------------------------------- + // Binormals + //---------------------------------------------------------------- + numRead = fread(&mBaseBinormals[i], sizeof(float), 3, fp); + llendianswizzle(&mBaseBinormals[i], sizeof(float), 3); + if (numRead != 3) + { + llerrs << " can't read Binormals from " << fileName << llendl; + return FALSE; + } } - //---------------------------------------------------------------- // TexCoords //---------------------------------------------------------------- @@ -767,21 +779,28 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_ { // Allocate memory without initializing every vector // NOTE: This makes asusmptions about the size of LLVector[234] - int nverts = mSharedData->mNumVertices; - int nfloats = nverts * (2*4 + 3*3 + 2 + 4); + S32 nverts = mSharedData->mNumVertices; + //make sure it's an even number of verts for alignment + nverts += nverts%2; + S32 nfloats = nverts * ( + 4 + //coords + 4 + //normals + 4 + //weights + 2 + //coords + 4 + //scaled normals + 4 + //binormals + 4); //scaled binormals + //use 16 byte aligned vertex data to make LLPolyMesh SSE friendly mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4); - int offset = 0; - mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts; - mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts; - mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts; - mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; - - // these members don't need to be 16-byte aligned, but the first one might be - // read during an aligned memcpy of mTexCoords - mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + S32 offset = 0; + mCoords = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mNormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mClothingWeights = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; + mScaledNormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mBinormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; + mScaledBinormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts; initializeForMorph(); } } @@ -966,38 +985,47 @@ BOOL LLPolyMesh::saveLLM(LLFILE *fp) //---------------------------------------------------------------- // Coords //---------------------------------------------------------------- - LLVector3* coords = mSharedData->mBaseCoords; - - llendianswizzle(coords, sizeof(float), 3*numVertices); - if (fwrite(coords, 3*sizeof(float), numVertices, fp) != numVertices) + for (U16 i = 0; i < numVertices; ++i) { - llwarns << "Short write" << llendl; + LLVector4a& coords = mSharedData->mBaseCoords[i]; + + llendianswizzle(coords.getF32ptr(), sizeof(float), 3); + if (fwrite(coords.getF32ptr(), 3*sizeof(float), 1, fp) != 1) + { + llwarns << "Short write" << llendl; + } + llendianswizzle(coords.getF32ptr(), sizeof(float), 3); } - llendianswizzle(coords, sizeof(float), 3*numVertices); //---------------------------------------------------------------- // Normals //---------------------------------------------------------------- - LLVector3* normals = mSharedData->mBaseNormals; - - llendianswizzle(normals, sizeof(float), 3*numVertices); - if (fwrite(normals, 3*sizeof(float), numVertices, fp) != numVertices) + for (U16 i = 0; i < numVertices; ++i) { - llwarns << "Short write" << llendl; + LLVector4a& normals = mSharedData->mBaseNormals[i]; + + llendianswizzle(normals.getF32ptr(), sizeof(float), 3); + if (fwrite(normals.getF32ptr(), 3*sizeof(float), 1, fp) != 1) + { + llwarns << "Short write" << llendl; + } + llendianswizzle(normals.getF32ptr(), sizeof(float), 3); } - llendianswizzle(normals, sizeof(float), 3*numVertices); //---------------------------------------------------------------- // Binormals //---------------------------------------------------------------- - LLVector3* binormals = mSharedData->mBaseBinormals; - - llendianswizzle(binormals, sizeof(float), 3*numVertices); - if (fwrite(binormals, 3*sizeof(float), numVertices, fp) != numVertices) + for (U16 i = 0; i < numVertices; ++i) { - llwarns << "Short write" << llendl; + LLVector4a& binormals = mSharedData->mBaseBinormals[i]; + + llendianswizzle(binormals.getF32ptr(), sizeof(float), 3); + if (fwrite(binormals.getF32ptr(), 3*sizeof(float), 1, fp) != 1) + { + llwarns << "Short write" << llendl; + } + llendianswizzle(binormals.getF32ptr(), sizeof(float), 3); } - llendianswizzle(binormals, sizeof(float), 3*numVertices); //---------------------------------------------------------------- // TexCoords @@ -1224,24 +1252,24 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp) int nfaces = mSharedData->mNumFaces; int i; - LLVector4* coords = getWritableCoords(); + LLVector4a* coords = getWritableCoords(); for ( i=0; imBaseCoords, mCoords, sizeof(LLVector3) * mSharedData->mNumVertices); - memcpy(mSharedData->mBaseNormals, mNormals, sizeof(LLVector3) * mSharedData->mNumVertices); - memcpy(mSharedData->mBaseBinormals, mBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); - memcpy(mSharedData->mTexCoords, mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mSharedData->mBaseCoords, (F32*) mCoords, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mSharedData->mBaseNormals, (F32*) mNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mSharedData->mBaseBinormals, (F32*) mBinormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mSharedData->mTexCoords, (F32*) mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2)); // Update all avatars by applying the delta @@ -1479,27 +1496,29 @@ BOOL LLPolyMesh::setSharedFromCurrent() LLPolyMesh* mesh = avatarp->getMesh(mSharedData); if (mesh) { - LLVector4 *mesh_coords = mesh->getWritableCoords(); - LLVector4 *mesh_normals = mesh->getWritableNormals(); - LLVector3 *mesh_binormals = mesh->getWritableBinormals(); - LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords(); - LLVector3 *mesh_scaled_normals = mesh->getScaledNormals(); - LLVector3 *mesh_scaled_binormals = mesh->getScaledBinormals(); + LLVector4a *mesh_coords = mesh->getWritableCoords(); + LLVector4a *mesh_normals = mesh->getWritableNormals(); + LLVector4a *mesh_binormals = mesh->getWritableBinormals(); + LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords(); + LLVector4a *mesh_scaled_normals = mesh->getScaledNormals(); + LLVector4a *mesh_scaled_binormals = mesh->getScaledBinormals(); for( vert_index = 0; vert_index < nverts; vert_index++) { - mesh_coords[vert_index] -= delta_coords[vert_index]; + mesh_coords[vert_index].sub(delta_coords[vert_index]); mesh_tex_coords[vert_index] -= delta_tex_coords[vert_index]; - mesh_scaled_normals[vert_index] -= LLVector3(delta_normals[vert_index]); - LLVector3 normalized_normal = mesh_scaled_normals[vert_index]; - normalized_normal.normVec(); - mesh_normals[vert_index] = LLVector4(normalized_normal); + mesh_scaled_normals[vert_index].sub(delta_normals[vert_index]); + LLVector4a normalized_normal = mesh_scaled_normals[vert_index]; + normalized_normal.normalize3(); + mesh_normals[vert_index] = normalized_normal; - mesh_scaled_binormals[vert_index] -= delta_binormals[vert_index]; - LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal; - LLVector3 normalized_binormal = normalized_normal % tangent; - normalized_binormal.normVec(); + mesh_scaled_binormals[vert_index].sub(delta_binormals[vert_index]); + LLVector4a tangent; + tangent.setCross3(mesh_scaled_binormals[vert_index], normalized_normal); + LLVector4a normalized_binormal; + normalized_binormal.setCross3(normalized_normal, tangent); + normalized_binormal.normalize3(); mesh_binormals[vert_index] = normalized_binormal; } @@ -1598,7 +1617,7 @@ void LLPolyMesh::dumpDiagInfo(void*) //----------------------------------------------------------------------------- // getWritableCoords() //----------------------------------------------------------------------------- -LLVector4 *LLPolyMesh::getWritableCoords() +LLVector4a *LLPolyMesh::getWritableCoords() { return mCoords; } @@ -1606,7 +1625,7 @@ LLVector4 *LLPolyMesh::getWritableCoords() //----------------------------------------------------------------------------- // getWritableNormals() //----------------------------------------------------------------------------- -LLVector4 *LLPolyMesh::getWritableNormals() +LLVector4a *LLPolyMesh::getWritableNormals() { return mNormals; } @@ -1614,7 +1633,7 @@ LLVector4 *LLPolyMesh::getWritableNormals() //----------------------------------------------------------------------------- // getWritableBinormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableBinormals() +LLVector4a *LLPolyMesh::getWritableBinormals() { return mBinormals; } @@ -1623,7 +1642,7 @@ LLVector3 *LLPolyMesh::getWritableBinormals() //----------------------------------------------------------------------------- // getWritableClothingWeights() //----------------------------------------------------------------------------- -LLVector4 *LLPolyMesh::getWritableClothingWeights() +LLVector4a *LLPolyMesh::getWritableClothingWeights() { return mClothingWeights; } @@ -1639,7 +1658,7 @@ LLVector2 *LLPolyMesh::getWritableTexCoords() //----------------------------------------------------------------------------- // getScaledNormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getScaledNormals() +LLVector4a *LLPolyMesh::getScaledNormals() { return mScaledNormals; } @@ -1647,7 +1666,7 @@ LLVector3 *LLPolyMesh::getScaledNormals() //----------------------------------------------------------------------------- // getScaledBinormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getScaledBinormals() +LLVector4a *LLPolyMesh::getScaledBinormals() { return mScaledBinormals; } @@ -1661,19 +1680,20 @@ void LLPolyMesh::initializeForMorph() if (!mSharedData) return; + LLVector4a::memcpyNonAliased16((F32*) mCoords, (F32*) mSharedData->mBaseCoords, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices); + LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2)); + for (U32 i = 0; i < (U32)mSharedData->mNumVertices; ++i) { - mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]); - mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]); + mClothingWeights[i].clear(); } - - memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices); } + //----------------------------------------------------------------------------- // getMorphList() //----------------------------------------------------------------------------- @@ -1818,8 +1838,8 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node) //----------------------------------------------------------------------------- LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp) { - mAvatar = avatarp; - mDefaultVec.setVec(0.001f, 0.001f, 0.001f); + mAvatar = avatarp; + mDefaultVec.splat(0.001f); } //----------------------------------------------------------------------------- @@ -1947,36 +1967,49 @@ LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data, const LLVector3 &direction, const std::string &name) { - LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); - cloned_morph_data->mName = name; - for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) - { - cloned_morph_data->mCoords[v] = direction; - cloned_morph_data->mNormals[v] = LLVector3(0,0,0); - cloned_morph_data->mBinormals[v] = LLVector3(0,0,0); - } - return cloned_morph_data; + LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); + cloned_morph_data->mName = name; + LLVector4a dir; + dir.load3(direction.mV); + + for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) + { + cloned_morph_data->mCoords[v] = dir; + cloned_morph_data->mNormals[v].clear(); + cloned_morph_data->mBinormals[v].clear(); + } + return cloned_morph_data; } LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data, F32 scale, const std::string &name) { - LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); - cloned_morph_data->mName = name; - for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) - { - cloned_morph_data->mCoords[v] = src_data->mCoords[v]*scale; - cloned_morph_data->mNormals[v] = src_data->mNormals[v]*scale; - cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]*scale; - if (cloned_morph_data->mCoords[v][1] < 0) - { - cloned_morph_data->mCoords[v][1] *= -1; - cloned_morph_data->mNormals[v][1] *= -1; - cloned_morph_data->mBinormals[v][1] *= -1; - } - } - return cloned_morph_data; + LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data); + cloned_morph_data->mName = name; + + LLVector4a sc; + sc.splat(scale); + + LLVector4a nsc; + nsc.set(scale, -scale, scale, scale); + + for (U32 v=0; v < cloned_morph_data->mNumIndices; v++) + { + if (cloned_morph_data->mCoords[v][1] < 0) + { + cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc); + cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc); + cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc); + } + else + { + cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc); + cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc); + cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc); + } + } + return cloned_morph_data; } // End diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h index 4b7927564..d09909309 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/newview/llpolymesh.h @@ -73,9 +73,9 @@ private: // vertex data S32 mNumVertices; - LLVector3 *mBaseCoords; - LLVector3 *mBaseNormals; - LLVector3 *mBaseBinormals; + LLVector4a *mBaseCoords; + LLVector4a *mBaseNormals; + LLVector4a *mBaseBinormals; LLVector2 *mTexCoords; LLVector2 *mDetailTexCoords; F32 *mWeights; @@ -235,41 +235,41 @@ public: } // Get coords - const LLVector4 *getCoords() const{ + const LLVector4a *getCoords() const{ return mCoords; } // non const version - LLVector4 *getWritableCoords(); + LLVector4a *getWritableCoords(); // Get normals - const LLVector4 *getNormals() const{ + const LLVector4a *getNormals() const{ return mNormals; } // Get normals - const LLVector3 *getBinormals() const{ + const LLVector4a *getBinormals() const{ return mBinormals; } // Get base mesh normals - const LLVector3 *getBaseNormals() const{ + const LLVector4a *getBaseNormals() const{ llassert(mSharedData); return mSharedData->mBaseNormals; } // Get base mesh normals - const LLVector3 *getBaseBinormals() const{ + const LLVector4a *getBaseBinormals() const{ llassert(mSharedData); return mSharedData->mBaseBinormals; } // intermediate morphed normals and output normals - LLVector4 *getWritableNormals(); - LLVector3 *getScaledNormals(); + LLVector4a *getWritableNormals(); + LLVector4a *getScaledNormals(); - LLVector3 *getWritableBinormals(); - LLVector3 *getScaledBinormals(); + LLVector4a *getWritableBinormals(); + LLVector4a *getScaledBinormals(); // Get texCoords const LLVector2 *getTexCoords() const { @@ -293,9 +293,9 @@ public: F32 *getWritableWeights() const; - LLVector4 *getWritableClothingWeights(); + LLVector4a *getWritableClothingWeights(); - const LLVector4 *getClothingWeights() + const LLVector4a *getClothingWeights() { return mClothingWeights; } @@ -363,17 +363,17 @@ protected: // Single array of floats for allocation / deletion F32 *mVertexData; // deformed vertices (resulting from application of morph targets) - LLVector4 *mCoords; + LLVector4a *mCoords; // deformed normals (resulting from application of morph targets) - LLVector3 *mScaledNormals; + LLVector4a *mScaledNormals; // output normals (after normalization) - LLVector4 *mNormals; + LLVector4a *mNormals; // deformed binormals (resulting from application of morph targets) - LLVector3 *mScaledBinormals; + LLVector4a *mScaledBinormals; // output binormals (after normalization) - LLVector3 *mBinormals; + LLVector4a *mBinormals; // weight values that mark verts as clothing/skin - LLVector4 *mClothingWeights; + LLVector4a *mClothingWeights; // output texture coordinates LLVector2 *mTexCoords; @@ -441,17 +441,17 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 0.1f; } - /*virtual*/ const LLVector3& getAvgDistortion() { return mDefaultVec; } + /*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; } /*virtual*/ F32 getMaxDistortion() { return 0.1f; } - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector3(0.001f, 0.001f, 0.001f);} - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);} + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;}; + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;}; protected: typedef std::map joint_vec_map_t; joint_vec_map_t mJointScales; joint_vec_map_t mJointOffsets; - LLVector3 mDefaultVec; + LLVector4a mDefaultVec; // Backlink only; don't make this an LLPointer. LLVOAvatar *mAvatar; }; diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index 73a0b525c..b43837e89 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -49,7 +49,7 @@ LLPolyMorphData::LLPolyMorphData(const std::string& morph_name) mNumIndices = 0; mCurrentIndex = 0; mTotalDistortion = 0.f; - mAvgDistortion.zeroVec(); + mAvgDistortion.clear(); mMaxDistortion = 0.f; mVertexIndices = NULL; mCoords = NULL; @@ -74,9 +74,9 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : { const S32 numVertices = mNumIndices; - mCoords = new LLVector3[numVertices]; - mNormals = new LLVector3[numVertices]; - mBinormals = new LLVector3[numVertices]; + mCoords = new LLVector4a[numVertices]; + mNormals = new LLVector4a[numVertices]; + mBinormals = new LLVector4a[numVertices]; mTexCoords = new LLVector2[numVertices]; mVertexIndices = new U32[numVertices]; @@ -90,6 +90,7 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : } } + //----------------------------------------------------------------------------- // ~LLPolyMorphData() //----------------------------------------------------------------------------- @@ -121,16 +122,16 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) //------------------------------------------------------------------------- // allocate vertices //------------------------------------------------------------------------- - mCoords = new LLVector3[numVertices]; - mNormals = new LLVector3[numVertices]; - mBinormals = new LLVector3[numVertices]; + mCoords = new LLVector4a[numVertices]; + mNormals = new LLVector4a[numVertices]; + mBinormals = new LLVector4a[numVertices]; mTexCoords = new LLVector2[numVertices]; // Actually, we are allocating more space than we need for the skiplist mVertexIndices = new U32[numVertices]; mNumIndices = 0; mTotalDistortion = 0.f; mMaxDistortion = 0.f; - mAvgDistortion.zeroVec(); + mAvgDistortion.clear(); mMesh = mesh; //------------------------------------------------------------------------- @@ -152,36 +153,36 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) } - numRead = fread(&mCoords[v].mV, sizeof(F32), 3, fp); - llendianswizzle(&mCoords[v].mV, sizeof(F32), 3); + numRead = fread(&mCoords[v], sizeof(F32), 3, fp); + llendianswizzle(&mCoords[v], sizeof(F32), 3); if (numRead != 3) { llwarns << "Can't read morph target vertex coordinates" << llendl; return FALSE; } - F32 magnitude = mCoords[v].magVec(); + F32 magnitude = mCoords[v].getLength3().getF32(); mTotalDistortion += magnitude; - mAvgDistortion.mV[VX] += fabs(mCoords[v].mV[VX]); - mAvgDistortion.mV[VY] += fabs(mCoords[v].mV[VY]); - mAvgDistortion.mV[VZ] += fabs(mCoords[v].mV[VZ]); + LLVector4a t; + t.setAbs(mCoords[v]); + mAvgDistortion.add(t); if (magnitude > mMaxDistortion) { mMaxDistortion = magnitude; } - numRead = fread(&mNormals[v].mV, sizeof(F32), 3, fp); - llendianswizzle(&mNormals[v].mV, sizeof(F32), 3); + numRead = fread(&mNormals[v], sizeof(F32), 3, fp); + llendianswizzle(&mNormals[v], sizeof(F32), 3); if (numRead != 3) { llwarns << "Can't read morph target normal" << llendl; return FALSE; } - numRead = fread(&mBinormals[v].mV, sizeof(F32), 3, fp); - llendianswizzle(&mBinormals[v].mV, sizeof(F32), 3); + numRead = fread(&mBinormals[v], sizeof(F32), 3, fp); + llendianswizzle(&mBinormals[v], sizeof(F32), 3); if (numRead != 3) { llwarns << "Can't read morph target binormal" << llendl; @@ -200,8 +201,8 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) mNumIndices++; } - mAvgDistortion = mAvgDistortion * (1.f/(F32)mNumIndices); - mAvgDistortion.normVec(); + mAvgDistortion.mul(1.f/(F32)mNumIndices); + mAvgDistortion.normalize3fast(); return TRUE; } @@ -235,26 +236,26 @@ BOOL LLPolyMorphData::saveLLM(LLFILE *fp) } llendianswizzle(&mVertexIndices[v], sizeof(U32), 1); - llendianswizzle(&mCoords[v].mV, sizeof(F32), 3); - if (fwrite(&mCoords[v].mV, sizeof(F32), 3, fp) != 3) + llendianswizzle(mCoords[v].getF32ptr(), sizeof(F32), 3); + if (fwrite(mCoords[v].getF32ptr(), sizeof(F32), 3, fp) != 3) { llwarns << "Short write" << llendl; } - llendianswizzle(&mCoords[v].mV, sizeof(F32), 3); + llendianswizzle(mCoords[v].getF32ptr(), sizeof(F32), 3); - llendianswizzle(&mNormals[v].mV, sizeof(F32), 3); - if (fwrite(&mNormals[v].mV, sizeof(F32), 3, fp) != 3) + llendianswizzle(mNormals[v].getF32ptr(), sizeof(F32), 3); + if (fwrite(mNormals[v].getF32ptr(), sizeof(F32), 3, fp) != 3) { llwarns << "Short write" << llendl; } - llendianswizzle(&mNormals[v].mV, sizeof(F32), 3); + llendianswizzle(mNormals[v].getF32ptr(), sizeof(F32), 3); - llendianswizzle(&mBinormals[v].mV, sizeof(F32), 3); - if (fwrite(&mBinormals[v].mV, sizeof(F32), 3, fp) != 3) + llendianswizzle(mBinormals[v].getF32ptr(), sizeof(F32), 3); + if (fwrite(mBinormals[v].getF32ptr(), sizeof(F32), 3, fp) != 3) { llwarns << "Short write" << llendl; } - llendianswizzle(&mBinormals[v].mV, sizeof(F32), 3); + llendianswizzle(mBinormals[v].getF32ptr(), sizeof(F32), 3); llendianswizzle(&mTexCoords[v].mV, sizeof(F32), 2); if (fwrite(&mTexCoords[v].mV, sizeof(F32), 2, fp) != 2) @@ -277,17 +278,17 @@ BOOL LLPolyMorphData::saveOBJ(LLFILE *fp) LLPolyMesh mesh(mMesh, NULL); - LLVector4 *coords = mesh.getWritableCoords(); - LLVector4 *normals = mesh.getWritableNormals(); + LLVector4a *coords = mesh.getWritableCoords(); + LLVector4a *normals = mesh.getWritableNormals(); LLVector2 *tex_coords = mesh.getWritableTexCoords(); for(U32 vert_index_morph = 0; vert_index_morph < mNumIndices; vert_index_morph++) { S32 vert_index_mesh = mVertexIndices[vert_index_morph]; - coords[vert_index_mesh] += LLVector4(mCoords[vert_index_morph]); - normals[vert_index_mesh] += LLVector4(mNormals[vert_index_morph]); - normals[vert_index_mesh].normVec(); + coords[vert_index_mesh].add(mCoords[vert_index_morph]); + normals[vert_index_mesh].add(mNormals[vert_index_morph]); + normals[vert_index_mesh].normalize3(); tex_coords[vert_index_mesh] += mTexCoords[vert_index_morph]; } @@ -302,9 +303,9 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) if (!morph) return FALSE; - LLVector4 *morph_coords = morph->getWritableCoords(); - LLVector4 *morph_normals = morph->getWritableNormals(); - LLVector3 *morph_binormals = morph->getWritableBinormals(); + LLVector4a *morph_coords = morph->getWritableCoords(); + LLVector4a *morph_normals = morph->getWritableNormals(); + LLVector4a *morph_binormals = morph->getWritableBinormals(); LLVector2 *morph_tex_coords = morph->getWritableTexCoords(); // We now have the morph loaded as a mesh. We have to subtract the @@ -313,19 +314,19 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) LLPolyMesh delta(mMesh, NULL); U32 nverts = delta.getNumVertices(); - LLVector4 *delta_coords = delta.getWritableCoords(); - LLVector4 *delta_normals = delta.getWritableNormals(); - LLVector3 *delta_binormals = delta.getWritableBinormals(); + LLVector4a *delta_coords = delta.getWritableCoords(); + LLVector4a *delta_normals = delta.getWritableNormals(); + LLVector4a *delta_binormals = delta.getWritableBinormals(); LLVector2 *delta_tex_coords = delta.getWritableTexCoords(); U32 num_significant = 0; U32 vert_index; for( vert_index = 0; vert_index < nverts; vert_index++) { - delta_coords[vert_index] = morph_coords[vert_index] - delta_coords[vert_index]; - delta_normals[vert_index] = morph_normals[vert_index] - delta_normals[vert_index]; - delta_binormals[vert_index] = morph_binormals[vert_index] - delta_binormals[vert_index]; - delta_tex_coords[vert_index] = morph_tex_coords[vert_index] - delta_tex_coords[vert_index]; + delta_coords[vert_index].setSub( morph_coords[vert_index], delta_coords[vert_index]); + delta_normals[vert_index].setSub( morph_normals[vert_index], delta_normals[vert_index]); + delta_binormals[vert_index].setSub( morph_binormals[vert_index], delta_binormals[vert_index]); + delta_tex_coords[vert_index] = morph_tex_coords[vert_index] - delta_tex_coords[vert_index]; // For the normals and binormals, we really want the deltas // to be perpendicular to the mesh (bi)normals in the plane @@ -333,10 +334,10 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) // that the morph (bi)normals form the hypotenuses of right // triangles. Right now, we just compute the difference vector. - if (delta_coords[vert_index].length() > SIGNIFICANT_DELTA - || delta_normals[vert_index].length() > SIGNIFICANT_DELTA - || delta_binormals[vert_index].length() > SIGNIFICANT_DELTA - || delta_tex_coords[vert_index].length() > SIGNIFICANT_DELTA) + if (delta_coords[vert_index].getLength3().getF32() > SIGNIFICANT_DELTA + || delta_normals[vert_index].getLength3().getF32() > SIGNIFICANT_DELTA + || delta_binormals[vert_index].getLength3().getF32() > SIGNIFICANT_DELTA + || delta_tex_coords[vert_index].length() > SIGNIFICANT_DELTA) { num_significant++; } @@ -353,39 +354,39 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) if (num_significant == 0) nindices = 1; - LLVector3* new_coords = new LLVector3[nindices]; - LLVector3* new_normals = new LLVector3[nindices]; - LLVector3* new_binormals = new LLVector3[nindices]; + LLVector4a* new_coords = new LLVector4a[nindices]; + LLVector4a* new_normals = new LLVector4a[nindices]; + LLVector4a* new_binormals = new LLVector4a[nindices]; LLVector2* new_tex_coords = new LLVector2[nindices]; U32* new_vertex_indices = new U32[nindices]; // We'll set the distortion directly mTotalDistortion = 0.f; mMaxDistortion = 0.f; - mAvgDistortion.zeroVec(); + mAvgDistortion.clear(); U32 morph_index = 0; for( vert_index = 0; vert_index < nverts; vert_index++) { - if (delta_coords[vert_index].length() > SIGNIFICANT_DELTA - || delta_normals[vert_index].length() > SIGNIFICANT_DELTA - || delta_binormals[vert_index].length() > SIGNIFICANT_DELTA - || delta_tex_coords[vert_index].length() > SIGNIFICANT_DELTA + if (delta_coords[vert_index].getLength3().getF32() > SIGNIFICANT_DELTA + || delta_normals[vert_index].getLength3().getF32() > SIGNIFICANT_DELTA + || delta_binormals[vert_index].getLength3().getF32() > SIGNIFICANT_DELTA + || delta_tex_coords[vert_index].length() > SIGNIFICANT_DELTA || num_significant == 0) { new_vertex_indices[morph_index] = vert_index; - new_coords[morph_index] = LLVector3(delta_coords[vert_index]); - new_normals[morph_index] = LLVector3(delta_normals[vert_index]); + new_coords[morph_index] = delta_coords[vert_index]; + new_normals[morph_index] = delta_normals[vert_index]; new_binormals[morph_index] = delta_binormals[vert_index]; new_tex_coords[morph_index] = delta_tex_coords[vert_index]; - F32 magnitude = new_coords[morph_index].magVec(); + F32 magnitude = new_coords[morph_index].getLength3().getF32(); mTotalDistortion += magnitude; - mAvgDistortion.mV[VX] += fabs(new_coords[morph_index].mV[VX]); - mAvgDistortion.mV[VY] += fabs(new_coords[morph_index].mV[VY]); - mAvgDistortion.mV[VZ] += fabs(new_coords[morph_index].mV[VZ]); + LLVector4a t; + t.setAbs(new_coords[morph_index]); + mAvgDistortion.add(t); if (magnitude > mMaxDistortion) { @@ -397,8 +398,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) } } - mAvgDistortion = mAvgDistortion * (1.f/(F32)nindices); - mAvgDistortion.normVec(); + mAvgDistortion.mul(1.f/(F32)nindices); + mAvgDistortion.normalize3(); //------------------------------------------------------------------------- // compute the change in the morph @@ -412,9 +413,9 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) { vert_index = mVertexIndices[morph_index]; - delta_coords[vert_index] -= LLVector4(mCoords[morph_index]); - delta_normals[vert_index] -= LLVector4(mNormals[morph_index]); - delta_binormals[vert_index] -= mBinormals[morph_index]; + delta_coords[vert_index].sub( mCoords[morph_index]); + delta_normals[vert_index].sub( mNormals[morph_index]); + delta_binormals[vert_index].sub(mBinormals[morph_index]); delta_tex_coords[vert_index] -= mTexCoords[morph_index]; } @@ -451,27 +452,35 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph) continue; }*/ - LLVector4 *mesh_coords = mesh->getWritableCoords(); - LLVector4 *mesh_normals = mesh->getWritableNormals(); - LLVector3 *mesh_binormals = mesh->getWritableBinormals(); - LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords(); - LLVector3 *mesh_scaled_normals = mesh->getScaledNormals(); - LLVector3 *mesh_scaled_binormals = mesh->getScaledBinormals(); + LLVector4a *mesh_coords = mesh->getWritableCoords(); + LLVector4a *mesh_normals = mesh->getWritableNormals(); + LLVector4a *mesh_binormals = mesh->getWritableBinormals(); + LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords(); + LLVector4a *mesh_scaled_normals = mesh->getScaledNormals(); + LLVector4a *mesh_scaled_binormals = mesh->getScaledBinormals(); for( vert_index = 0; vert_index < nverts; vert_index++) { - mesh_coords[vert_index] += delta_coords[vert_index] * weight; + delta_coords[vert_index].mul(weight); + mesh_coords[vert_index].add(delta_coords[vert_index]); + mesh_tex_coords[vert_index] += delta_tex_coords[vert_index] * weight; - mesh_scaled_normals[vert_index] += LLVector3(delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR); - LLVector3 normalized_normal = mesh_scaled_normals[vert_index]; - normalized_normal.normVec(); - mesh_normals[vert_index] = LLVector4(normalized_normal); + delta_normals[vert_index].mul(weight * NORMAL_SOFTEN_FACTOR); + mesh_scaled_normals[vert_index].add(delta_normals[vert_index]); + + LLVector4a normalized_normal = mesh_scaled_normals[vert_index]; + normalized_normal.normalize3(); + mesh_normals[vert_index] = normalized_normal; - mesh_scaled_binormals[vert_index] += delta_binormals[vert_index] * weight * NORMAL_SOFTEN_FACTOR; - LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal; - LLVector3 normalized_binormal = normalized_normal % tangent; - normalized_binormal.normVec(); + delta_binormals[vert_index].mul(weight * NORMAL_SOFTEN_FACTOR); + mesh_scaled_binormals[vert_index].add(delta_binormals[vert_index]); + + LLVector4a tangent; + tangent.setCross3(mesh_scaled_binormals[vert_index], normalized_normal); + LLVector4a normalized_binormal; + normalized_binormal.setCross3(normalized_normal, tangent); + normalized_binormal.normalize3(); mesh_binormals[vert_index] = normalized_binormal; } @@ -658,9 +667,9 @@ BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node) //----------------------------------------------------------------------------- // getVertexDistortion() //----------------------------------------------------------------------------- -LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh) +LLVector4a LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh) { - if (!mMorphData || mMesh != mesh) return LLVector3::zero; + if (!mMorphData || mMesh != mesh) return LLVector4a::getZero(); for(U32 index = 0; index < mMorphData->mNumIndices; index++) { @@ -670,17 +679,17 @@ LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh } } - return LLVector3::zero; + return LLVector4a::getZero(); } //----------------------------------------------------------------------------- // getFirstDistortion() //----------------------------------------------------------------------------- -const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { - if (!mMorphData) return &LLVector3::zero; + if (!mMorphData) return &LLVector4a::getZero(); - LLVector3* resultVec; + LLVector4a* resultVec; mMorphData->mCurrentIndex = 0; if (mMorphData->mNumIndices) { @@ -702,11 +711,11 @@ const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh ** //----------------------------------------------------------------------------- // getNextDistortion() //----------------------------------------------------------------------------- -const LLVector3 *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) +const LLVector4a *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { - if (!mMorphData) return &LLVector3::zero; + if (!mMorphData) return &LLVector4a::getZero(); - LLVector3* resultVec; + LLVector4a* resultVec; mMorphData->mCurrentIndex++; if (mMorphData->mCurrentIndex < mMorphData->mNumIndices) { @@ -742,7 +751,7 @@ F32 LLPolyMorphTarget::getTotalDistortion() //----------------------------------------------------------------------------- // getAvgDistortion() //----------------------------------------------------------------------------- -const LLVector3& LLPolyMorphTarget::getAvgDistortion() +const LLVector4a& LLPolyMorphTarget::getAvgDistortion() { if (mMorphData) { @@ -750,7 +759,7 @@ const LLVector3& LLPolyMorphTarget::getAvgDistortion() } else { - return LLVector3::zero; + return LLVector4a::getZero(); } } @@ -799,15 +808,15 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) if (delta_weight != 0.f) { llassert(!mMesh->isLOD()); - LLVector4 *coords = mMesh->getWritableCoords(); + LLVector4a *coords = mMesh->getWritableCoords(); - LLVector3 *scaled_normals = mMesh->getScaledNormals(); - LLVector4 *normals = mMesh->getWritableNormals(); + LLVector4a *scaled_normals = mMesh->getScaledNormals(); + LLVector4a *normals = mMesh->getWritableNormals(); - LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); - LLVector3 *binormals = mMesh->getWritableBinormals(); + LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); + LLVector4a *binormals = mMesh->getWritableBinormals(); - LLVector4 *clothing_weights = mMesh->getWritableClothingWeights(); + LLVector4a *clothing_weights = mMesh->getWritableClothingWeights(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL; @@ -822,31 +831,38 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) maskWeight = maskWeightArray[vert_index_morph]; } - coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight); + + LLVector4a pos = mMorphData->mCoords[vert_index_morph]; + pos.mul(delta_weight*maskWeight); + coords[vert_index_mesh].add(pos); if (getInfo()->mIsClothingMorph && clothing_weights) { - LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; - LLVector4* clothing_weight = &clothing_weights[vert_index_mesh]; - clothing_weight->mV[VX] += clothing_offset.mV[VX]; - clothing_weight->mV[VY] += clothing_offset.mV[VY]; - clothing_weight->mV[VZ] += clothing_offset.mV[VZ]; - clothing_weight->mV[VW] = maskWeight; + LLVector4a clothing_offset = mMorphData->mCoords[vert_index_morph]; + clothing_offset.mul(delta_weight * maskWeight); + LLVector4a* clothing_weight = &clothing_weights[vert_index_mesh]; + clothing_weight->add(clothing_offset); + clothing_weight->getF32ptr()[VW] = maskWeight; } // calculate new normals based on half angles - scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; - LLVector3 normalized_normal = scaled_normals[vert_index_mesh]; - normalized_normal.normVec(); - normals[vert_index_mesh] = LLVector4(normalized_normal); + LLVector4a norm = mMorphData->mNormals[vert_index_morph]; + norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); + scaled_normals[vert_index_mesh].add(norm); + norm = scaled_normals[vert_index_mesh]; + norm.normalize3fast(); + normals[vert_index_mesh] = norm; // calculate new binormals - scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; - LLVector3 tangent = scaled_binormals[vert_index_mesh] % normalized_normal; - LLVector3 normalized_binormal = normalized_normal % tangent; - normalized_binormal.normVec(); - binormals[vert_index_mesh] = normalized_binormal; - + LLVector4a binorm = mMorphData->mBinormals[vert_index_morph]; + binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); + scaled_binormals[vert_index_mesh].add(binorm); + LLVector4a tangent; + tangent.setCross3(scaled_binormals[vert_index_mesh], norm); + LLVector4a& normalized_binormal = binormals[vert_index_mesh]; + normalized_binormal.setCross3(norm, tangent); + normalized_binormal.normalize3fast(); + tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight; } @@ -873,7 +889,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) //----------------------------------------------------------------------------- void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert) { - LLVector4 *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL; + LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL; if (!mVertMask) { @@ -887,29 +903,47 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3 if (maskWeights) { - LLVector4 *coords = mMesh->getWritableCoords(); - LLVector3 *scaled_normals = mMesh->getScaledNormals(); - LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); + LLVector4a *coords = mMesh->getWritableCoords(); + LLVector4a *scaled_normals = mMesh->getScaledNormals(); + LLVector4a *scaled_binormals = mMesh->getScaledBinormals(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); + LLVector4Logical clothing_mask; + clothing_mask.clear(); + clothing_mask.setElement<0>(); + clothing_mask.setElement<1>(); + clothing_mask.setElement<2>(); + + for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++) { F32 lastMaskWeight = mLastWeight * maskWeights[vert]; S32 out_vert = mMorphData->mVertexIndices[vert]; // remove effect of existing masked morph - coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight; - scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; - scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; + LLVector4a t; + t = mMorphData->mCoords[vert]; + t.mul(lastMaskWeight); + coords[out_vert].sub(t); + + t = mMorphData->mNormals[vert]; + t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); + scaled_normals[out_vert].sub(t); + + t = mMorphData->mBinormals[vert]; + t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR); + scaled_binormals[out_vert].sub(t); + tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight; if (clothing_weights) { - LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight; - LLVector4* clothing_weight = &clothing_weights[out_vert]; - clothing_weight->mV[VX] -= clothing_offset.mV[VX]; - clothing_weight->mV[VY] -= clothing_offset.mV[VY]; - clothing_weight->mV[VZ] -= clothing_offset.mV[VZ]; + LLVector4a clothing_offset = mMorphData->mCoords[vert]; + clothing_offset.mul(lastMaskWeight); + LLVector4a* clothing_weight = &clothing_weights[out_vert]; + LLVector4a t; + t.setSub(*clothing_weight, clothing_offset); + clothing_weight->setSelectWithMask(clothing_mask, t, *clothing_weight); } } } @@ -945,7 +979,7 @@ LLPolyVertexMask::~LLPolyVertexMask() //----------------------------------------------------------------------------- // generateMask() //----------------------------------------------------------------------------- -void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights) +void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights) { // RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/) // BOOL debugImg = FALSE; @@ -989,7 +1023,7 @@ void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, if (clothing_weights) { - clothing_weights[vertIndex].mV[VW] = mWeights[index]; + clothing_weights[vertIndex].getF32ptr()[VW] = mWeights[index]; } } mWeightsGenerated = TRUE; diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h index be7019fdf..dac698437 100644 --- a/indra/newview/llpolymorph.h +++ b/indra/newview/llpolymorph.h @@ -68,14 +68,14 @@ public: U32 mNumIndices; U32* mVertexIndices; U32 mCurrentIndex; - LLVector3* mCoords; - LLVector3* mNormals; - LLVector3* mBinormals; + LLVector4a* mCoords; + LLVector4a* mNormals; + LLVector4a* mBinormals; LLVector2* mTexCoords; F32 mTotalDistortion; // vertex distortion summed over entire morph F32 mMaxDistortion; // maximum single vertex distortion in a given morph - LLVector3 mAvgDistortion; // average vertex distortion, to infer directionality of the morph + LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph LLPolyMeshSharedData* mMesh; }; @@ -88,7 +88,7 @@ public: LLPolyVertexMask(LLPolyMorphData* morph_data); ~LLPolyVertexMask(); - void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights); + void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights); F32* getMorphMaskWeights(); @@ -167,11 +167,11 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion(); - /*virtual*/ const LLVector3& getAvgDistortion(); + /*virtual*/ const LLVector4a& getAvgDistortion(); /*virtual*/ F32 getMaxDistortion(); - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh); + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh); + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh); void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert); void addPendingMorphMask() { mNumMorphMasksPending++; } diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h index 74c22b0cd..2c0da60b4 100644 --- a/indra/newview/lltexlayerparams.h +++ b/indra/newview/lltexlayerparams.h @@ -76,11 +76,11 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 1.f; } - /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; } + /*virtual*/ const LLVector4a& getAvgDistortion() { return mAvgDistortionVec; } /*virtual*/ F32 getMaxDistortion() { return 3.f; } - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);} - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector4a(1.f, 1.f, 1.f);} + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; // New functions BOOL render( S32 x, S32 y, S32 width, S32 height ); @@ -94,7 +94,7 @@ private: LLPointer mStaticImageRaw; BOOL mNeedsCreateTexture; BOOL mStaticImageInvalid; - LLVector3 mAvgDistortionVec; + LLVector4a mAvgDistortionVec; F32 mCachedEffectiveWeight; public: @@ -155,18 +155,18 @@ public: // LLViewerVisualParam Virtual functions /*virtual*/ F32 getTotalDistortion() { return 1.f; } - /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; } + /*virtual*/ const LLVector4a& getAvgDistortion() { return mAvgDistortionVec; } /*virtual*/ F32 getMaxDistortion() { return 3.f; } - /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); } - /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; - /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; + /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector4a(1.f, 1.f, 1.f); } + /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;}; + /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;}; // New functions LLColor4 getNetColor() const; protected: virtual void onGlobalColorChanged(bool upload_bake) {} private: - LLVector3 mAvgDistortionVec; + LLVector4a mAvgDistortionVec; }; class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h index 8eaa0af0a..259c0d6ee 100644 --- a/indra/newview/llviewervisualparam.h +++ b/indra/newview/llviewervisualparam.h @@ -84,11 +84,11 @@ public: // New Virtual functions virtual F32 getTotalDistortion() = 0; - virtual const LLVector3& getAvgDistortion() = 0; + virtual const LLVector4a& getAvgDistortion() = 0; virtual F32 getMaxDistortion() = 0; - virtual LLVector3 getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0; - virtual const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0; - virtual const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0; + virtual LLVector4a getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0; + virtual const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0; + virtual const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0; // interface methods F32 getDisplayOrder() const { return getInfo()->mEditGroupDisplayOrder; } From 4cbdb7897dc50e9d3d2bb93450785827b2cd492b Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 03:08:47 -0500 Subject: [PATCH 007/103] MAINT-646: Knock out some extraneous performance timers. https://bitbucket.org/davep/viewer-development/changeset/71673401390a --- indra/newview/llviewerobject.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 54ed9ac8d..5732027be 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2245,8 +2245,9 @@ BOOL LLViewerObject::isActive() const BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) { - static LLFastTimer::DeclareTimer ftm("Viewer Object"); - LLFastTimer t(ftm); + //static LLFastTimer::DeclareTimer ftm("Viewer Object"); + //LLFastTimer t(ftm); + if (mDead) { // It's dead. Don't update it. From 6736e91ce0367b184ee34369e94d24323b2ce7c2 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 03:09:16 -0500 Subject: [PATCH 008/103] MAINT-1147: Don't rebuild volume meshes on region crossing. https://bitbucket.org/davep/viewer-development/changeset/0f20bb7cb9ee --- indra/newview/llspatialpartition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 784a0e69c..20c390931 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -805,7 +805,7 @@ void LLSpatialGroup::shift(const LLVector4a &offset) mObjectExtents[0].add(offset); mObjectExtents[1].add(offset); - //if (!mSpatialPartition->mRenderByGroup) + if (!mSpatialPartition->mRenderByGroup) { setState(GEOM_DIRTY); gPipeline.markRebuild(this, TRUE); From d8fc6916259edd9822ea36424dfb250cbfbe8160 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 20:26:43 -0500 Subject: [PATCH 009/103] MAINT-646: Hotspot in LLViewerObjectList::update --- indra/newview/llviewerobject.cpp | 1 + indra/newview/llviewerobject.h | 5 ++ indra/newview/llviewerobjectlist.cpp | 79 ++++++++++++++++++++++------ indra/newview/llviewerobjectlist.h | 4 +- 4 files changed, 72 insertions(+), 17 deletions(-) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 5732027be..be2d1e065 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -208,6 +208,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mID(id), mLocalID(0), mTotalCRC(0), + mListIndex(-1), mTEImages(NULL), mGLName(0), mbCanSelect(TRUE), diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 403b27490..ee266ce99 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -233,6 +233,8 @@ public: const LLUUID &getID() const { return mID; } U32 getLocalID() const { return mLocalID; } U32 getCRC() const { return mTotalCRC; } + S32 getListIndex() const { return mListIndex; } + void setListIndex(S32 idx) { mListIndex = idx; } virtual BOOL isFlexible() const { return FALSE; } virtual BOOL isSculpted() const { return FALSE; } @@ -604,6 +606,9 @@ public: // Last total CRC received from sim, used for caching U32 mTotalCRC; + // index into LLViewerObjectList::mActiveObjects or -1 if not in list + S32 mListIndex; + LLPointer *mTEImages; // Selection, picking and rendering variables diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 758a8c3e9..1886e4fb8 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -932,21 +932,30 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) LLViewerObject *objectp = NULL; // Make a copy of the list in case something in idleUpdate() messes with it - std::vector idle_list; - + static std::vector idle_list; + + U32 idle_count = 0; + static LLFastTimer::DeclareTimer idle_copy("Idle Copy"); { LLFastTimer t(idle_copy); - idle_list.reserve( mActiveObjects.size() ); - - for (std::set >::iterator active_iter = mActiveObjects.begin(); + + for (std::vector >::iterator active_iter = mActiveObjects.begin(); active_iter != mActiveObjects.end(); active_iter++) { objectp = *active_iter; if (objectp) { - idle_list.push_back( objectp ); + if (idle_count >= idle_list.size()) + { + idle_list.push_back( objectp ); + } + else + { + idle_list[idle_count] = objectp; + } + ++idle_count; } else { // There shouldn't be any NULL pointers in the list, but they have caused @@ -956,11 +965,12 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } } + std::vector::iterator idle_end = idle_list.begin()+idle_count; static const LLCachedControl freeze_time("FreezeTime",0); if (freeze_time) { for (std::vector::iterator iter = idle_list.begin(); - iter != idle_list.end(); iter++) + iter != idle_end; iter++) { objectp = *iter; if ( @@ -976,17 +986,17 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) else { for (std::vector::iterator idle_iter = idle_list.begin(); - idle_iter != idle_list.end(); idle_iter++) + idle_iter != idle_end; idle_iter++) { objectp = *idle_iter; - if (!objectp->idleUpdate(agent, world, frame_time)) + if (objectp->idleUpdate(agent, world, frame_time)) { - // If Idle Update returns false, kill object! - kill_list.push_back(objectp); + num_active_objects++; } else { - num_active_objects++; + // If Idle Update returns false, kill object! + kill_list.push_back(objectp); } } for (std::vector::iterator kill_iter = kill_list.begin(); @@ -1229,7 +1239,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl; objectp->setOnActiveList(FALSE); - mActiveObjects.erase(objectp); + removeFromActiveList(objectp); } if (objectp->isOnMap()) @@ -1296,6 +1306,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) return TRUE; } + return FALSE; } @@ -1419,6 +1430,26 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) mNumDeadObjects = 0; } +void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) +{ + S32 idx = objectp->getListIndex(); + if (idx != -1) + { //remove by moving last element to this object's position + llassert(mActiveObjects[idx] == objectp); + + objectp->setListIndex(-1); + + S32 last_index = mActiveObjects.size()-1; + + if (idx != last_index) + { + mActiveObjects[idx] = mActiveObjects[last_index]; + mActiveObjects[idx]->setListIndex(idx); + mActiveObjects.pop_back(); + } + } +} + void LLViewerObjectList::updateActive(LLViewerObject *objectp) { LLMemType mt(LLMemType::MTYPE_OBJECT); @@ -1433,13 +1464,29 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) if (active) { //llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl; - mActiveObjects.insert(objectp); - objectp->setOnActiveList(TRUE); + S32 idx = objectp->getListIndex(); + if (idx <= -1) + { + mActiveObjects.push_back(objectp); + objectp->setListIndex(mActiveObjects.size()-1); + objectp->setOnActiveList(TRUE); + } + else + { + llassert(idx < (S32)mActiveObjects.size()); + llassert(mActiveObjects[idx] == objectp); + + if (idx >= (S32)mActiveObjects.size() || + mActiveObjects[idx] != objectp) + { + llwarns << "Invalid object list index detected!" << llendl; + } + } } else { //llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl; - mActiveObjects.erase(objectp); + removeFromActiveList(objectp); objectp->setOnActiveList(FALSE); } } diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 9266dcf2d..5a48656b7 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -128,7 +128,9 @@ public: void dirtyAllObjectInventory(); + void removeFromActiveList(LLViewerObject* objectp); void updateActive(LLViewerObject *objectp); + void updateAvatarVisibility(); // Selection related stuff @@ -206,7 +208,7 @@ public: typedef std::vector > vobj_list_t; vobj_list_t mObjects; - std::set > mActiveObjects; + std::vector > mActiveObjects; vobj_list_t mMapObjects; From 77dca2ddb2278ed1a5aa74e51414204390ee680f Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 21:04:21 -0500 Subject: [PATCH 010/103] FMODEx diagnostics. SHFMODExStreamBufferSize added. Determines stream buffer size in ms. (stream restart required) SHFMODExDecodeBufferSize added. Determines decode buffer size in ms. (stream restart required) Streams will mute themselves if they are starving, until they are free of starvation for 5 full seconds. Streams that fail to accumulate any buffer progress while starving for 10 full updates will be stopped. Stream buffer progress(buffer percent) is llinfos spewed every update. (temporary) Doubled default stream buffer size Increased default decode buffer size to 1000ms (from 400) Temporarily using FMOD::Memory_Initialize to display raw stream/decode buffer sizes via llinfos. Added llwarns messages for SigmaTel hardware or bad audio acceleration configuration. --- indra/llaudio/llaudioengine_fmodex.cpp | 28 +++++++++ indra/llaudio/llstreamingaudio.h | 3 + indra/llaudio/llstreamingaudio_fmodex.cpp | 68 ++++++++++++++++++++-- indra/llaudio/llstreamingaudio_fmodex.h | 7 +++ indra/newview/app_settings/settings_sh.xml | 22 +++++++ indra/newview/llviewerparcelmedia.cpp | 4 ++ 6 files changed, 126 insertions(+), 6 deletions(-) diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 2b2bd19d5..83ef4c5b4 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -95,6 +95,28 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) return true; } +void* __stdcall decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) +{ + if(type & FMOD_MEMORY_STREAM_DECODE) + { + llinfos << "Decode buffer size: " << size << llendl; + } + else if(type & FMOD_MEMORY_STREAM_FILE) + { + llinfos << "Strean buffer size: " << size << llendl; + } + return new char[size]; +} +void* __stdcall decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) +{ + memset(ptr,0,size); + return ptr; +} +void __stdcall decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) +{ + delete[] ptr; +} + bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) { @@ -108,6 +130,10 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL; + result = FMOD::Memory_Initialize(NULL, NULL, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE); + if(Check_FMOD_Error(result, "FMOD::Memory_Initialize")) + return false; + result = FMOD::System_Create(&mSystem); if(Check_FMOD_Error(result, "FMOD::System_Create")) return false; @@ -156,12 +182,14 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) */ result = mSystem->setDSPBufferSize(1024, 10); Check_FMOD_Error(result, "FMOD::System::setDSPBufferSize"); + llwarns << "Windows audio acceleration is disabled. This may introduce latency issues." << llendl; } result = mSystem->getDriverInfo(0, name, 256, 0); Check_FMOD_Error(result, "FMOD::System::getDriverInfo"); if (strstr(name, "SigmaTel")) { + llwarns << "SigmaTel device detected. This may introduce audio quality issues." << llendl; /* Sigmatel sound devices crackle for some reason if the format is PCM 16bit. PCM floating point output seems to solve it. diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h index 0e81cc530..3fb9ad4e3 100644 --- a/indra/llaudio/llstreamingaudio.h +++ b/indra/llaudio/llstreamingaudio.h @@ -58,6 +58,9 @@ class LLStreamingAudioInterface virtual const LLSD *getMetaData() = 0; virtual bool supportsWaveData() = 0; virtual bool getWaveData(float* arr, S32 count, S32 stride = 1) = 0; + + virtual bool supportsAdjustableBufferSizes(){return false;} + virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime){}; }; #endif // LL_STREAMINGAUDIO_H diff --git a/indra/llaudio/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp index 6d97bcc49..c57f7d59b 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.cpp +++ b/indra/llaudio/llstreamingaudio_fmodex.cpp @@ -50,7 +50,7 @@ public: const std::string& getURL() { return mInternetStreamURL; } - FMOD_OPENSTATE getOpenState(); + FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL); protected: FMOD::System* mSystem; FMOD::Channel* mStreamChannel; @@ -70,11 +70,13 @@ LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) : mCurrentInternetStreamp(NULL), mFMODInternetStreamChannelp(NULL), mGain(1.0f), - mMetaData(NULL) + mMetaData(NULL), + mStarvedProgress(0), + mStarvedNoProgressFrames(0) { // Number of milliseconds of audio to buffer for the audio card. // Must be larger than the usual Second Life frame stutter time. - const U32 buffer_seconds = 5; //sec + const U32 buffer_seconds = 10; //sec const U32 estimated_bitrate = 128; //kbit/sec mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES); @@ -145,7 +147,10 @@ void LLStreamingAudio_FMODEX::update() return; } - FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(); + unsigned int progress; + bool starving; + bool diskbusy; + FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy); if (open_state == FMOD_OPENSTATE_READY) { @@ -158,6 +163,7 @@ void LLStreamingAudio_FMODEX::update() // Reset volume to previously set volume setGain(getGain()); mFMODInternetStreamChannelp->setPaused(false); + mLastStarved.stop(); } } else if(open_state == FMOD_OPENSTATE_ERROR) @@ -168,6 +174,7 @@ void LLStreamingAudio_FMODEX::update() if(mFMODInternetStreamChannelp) { + llinfos << "progress = " << progress << llendl; if(!mMetaData) mMetaData = new LLSD; @@ -237,12 +244,46 @@ void LLStreamingAudio_FMODEX::update() } } } + if(starving) + { + if(!mLastStarved.getStarted()) + { + llinfos << "Stream starvation detected! Muting stream audio until it clears." << llendl; + llinfos << " (diskbusy="<setMute(true); + mStarvedProgress = progress; + mStarvedNoProgressFrames = 0; + } + else if(mStarvedProgress == progress) + { + if(++mStarvedNoProgressFrames >= 10) + { + //we got 10 consecutive updates of 0 progress made on the stream buffer. It probably stalled. + llinfos << "Stream unable to recover from starvation. Halting." << llendl; + stop(); + return; + } + } + else + { + mStarvedNoProgressFrames = 0; + mStarvedProgress = progress; + } + mLastStarved.start(); + } + else if(mLastStarved.getStarted() && mLastStarved.getElapsedTimeF32() > 5.f) + { + mLastStarved.stop(); + mFMODInternetStreamChannelp->setMute(false); + } } } } void LLStreamingAudio_FMODEX::stop() { + mLastStarved.stop(); if(mMetaData) { delete mMetaData; @@ -341,6 +382,11 @@ void LLStreamingAudio_FMODEX::setGain(F32 vol) if(!mFMODInternetStreamChannelp || !mCurrentInternetStreamp) return false; + bool muted=false; + mFMODInternetStreamChannelp->getMute(&muted); + if(muted) + return false; + static std::vector local_array(count); //Have to have an extra buffer to mix channels. Bleh. if(count > (S32)local_array.size()) //Expand the array if needed. Try to minimize allocation calls, so don't ever shrink. local_array.resize(count); @@ -442,9 +488,19 @@ bool LLAudioStreamManagerFMODEX::stopStream() } } -FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState() +FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy) { FMOD_OPENSTATE state; - mInternetStream->getOpenState(&state,NULL,NULL,NULL); + mInternetStream->getOpenState(&state,percentbuffered,starving,diskbusy); return state; } + +void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime) +{ + mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES); + FMOD_ADVANCEDSETTINGS settings; + memset(&settings,0,sizeof(settings)); + settings.cbsize=sizeof(settings); + settings.defaultDecodeBufferSize = decodebuffertime;//ms + mSystem->setAdvancedSettings(&settings); +} \ No newline at end of file diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h index 064b266e6..46c0ea553 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.h +++ b/indra/llaudio/llstreamingaudio_fmodex.h @@ -37,6 +37,7 @@ #include "stdtypes.h" // from llcommon #include "llstreamingaudio.h" +#include "lltimer.h" //Stubs class LLAudioStreamManagerFMODEX; @@ -66,6 +67,8 @@ class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface /*virtual*/ const LLSD *getMetaData(){return mMetaData;} //return NULL if not playing. /*virtual*/ bool supportsWaveData(){return true;} /*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1); + /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} + /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); private: FMOD::System *mSystem; @@ -76,6 +79,10 @@ private: std::string mURL; F32 mGain; + LLTimer mLastStarved; + unsigned int mStarvedProgress; + unsigned int mStarvedNoProgressFrames; + LLSD *mMetaData; }; diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index 803f7a12e..feae4cb77 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -40,6 +40,28 @@ Boolean Value 0 + + SHFMODExStreamBufferSize + + Comment + Sets the streaming buffer size (in milliseconds) + Persist + 1 + Type + U32 + Value + 7000 + + SHFMODExDecodeBufferSize + + Comment + Sets the streaming decode buffer size (in milliseconds) + Persist + 1 + Type + U32 + Value + 1000 SHAllowScriptCommands diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 9e7df265e..1349429ee 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -54,6 +54,7 @@ #include "llaudioengine.h" #include "lloverlaybar.h" #include "slfloatermediafilter.h" +#include "llstreamingaudio.h" // Static Variables @@ -661,6 +662,9 @@ void LLViewerParcelMedia::playStreamingMusic(LLParcel* parcel, bool filter) else if (gAudiop) { LLStringUtil::trim(music_url); + LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl(); + if(stream && stream->supportsAdjustableBufferSizes()) + stream->setBufferSizes(gSavedSettings.getU32("SHFMODExStreamBufferSize"),gSavedSettings.getU32("SHFMODExDecodeBufferSize")); gAudiop->startInternetStream(music_url); if (music_url.empty()) { From 1a3c9ac5ef16954e97d80164577c43ec9d6fb671 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Wed, 18 Jul 2012 21:27:02 -0500 Subject: [PATCH 011/103] GCC being GCC-ey. Fix a couple errors and warnings --- indra/llaudio/llaudioengine_fmodex.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 83ef4c5b4..c745dbcd1 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -95,7 +95,7 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) return true; } -void* __stdcall decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) +void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) { if(type & FMOD_MEMORY_STREAM_DECODE) { @@ -107,14 +107,14 @@ void* __stdcall decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const cha } return new char[size]; } -void* __stdcall decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) +void* F_STDCALL decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) { memset(ptr,0,size); return ptr; } -void __stdcall decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) +void F_STDCALL decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) { - delete[] ptr; + delete[] (char*)ptr; } bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) @@ -130,7 +130,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL; - result = FMOD::Memory_Initialize(NULL, NULL, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE); + result = FMOD::Memory_Initialize(NULL, 0, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE); if(Check_FMOD_Error(result, "FMOD::Memory_Initialize")) return false; From 6673c89791f0d939de24e5045edb680a3bf64475 Mon Sep 17 00:00:00 2001 From: Ruby Date: Thu, 19 Jul 2012 16:36:39 -0400 Subject: [PATCH 012/103] Add Antispam code from NaCl (Chalice Yao) Amended by: Lirusaito --- indra/newview/CMakeLists.txt | 2 + indra/newview/NACLantispam.cpp | 390 ++++++++++++++++++++++++ indra/newview/NACLantispam.h | 90 ++++++ indra/newview/app_settings/settings.xml | 68 ++++- indra/newview/llagent.cpp | 6 + indra/newview/llstartup.cpp | 8 + indra/newview/llviewercontrol.cpp | 27 ++ indra/newview/llviewermessage.cpp | 137 ++++++++- 8 files changed, 726 insertions(+), 2 deletions(-) create mode 100644 indra/newview/NACLantispam.cpp create mode 100644 indra/newview/NACLantispam.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c41698c34..66e02cfca 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -115,6 +115,7 @@ set(viewer_SOURCE_FILES jcfloaterareasearch.cpp chatbar_as_cmdline.cpp qtoolalign.cpp + NACLantispam.cpp llaccountingcostmanager.cpp llagent.cpp llagentaccess.cpp @@ -574,6 +575,7 @@ set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake + NACLantispam.h sgmemstat.h sgversion.h llviewerobjectbackup.h diff --git a/indra/newview/NACLantispam.cpp b/indra/newview/NACLantispam.cpp new file mode 100644 index 000000000..5e6be5d9d --- /dev/null +++ b/indra/newview/NACLantispam.cpp @@ -0,0 +1,390 @@ +#include "llviewerprecompiledheaders.h" +#include "NACLantispam.h" +#include "llviewercontrol.h" +#include "llnotificationsutil.h" +#include "llviewerobjectlist.h" +#include "llagent.h" +#include + +U32 NACLAntiSpamRegistry::globalAmount; +U32 NACLAntiSpamRegistry::globalTime; +bool NACLAntiSpamRegistry::bGlobalQueue; +NACLAntiSpamQueue* NACLAntiSpamRegistry::queues[NACLAntiSpamRegistry::QUEUE_MAX] = {0}; +std::tr1::unordered_map NACLAntiSpamRegistry::globalEntries; +std::tr1::unordered_map::iterator NACLAntiSpamRegistry::it2; + +const std::string COLLISION_SOUNDS[] ={"dce5fdd4-afe4-4ea1-822f-dd52cac46b08","51011582-fbca-4580-ae9e-1a5593f094ec","68d62208-e257-4d0c-bbe2-20c9ea9760bb","75872e8c-bc39-451b-9b0b-042d7ba36cba","6a45ba0b-5775-4ea8-8513-26008a17f873","992a6d1b-8c77-40e0-9495-4098ce539694","2de4da5a-faf8-46be-bac6-c4d74f1e5767","6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d","14209133-4961-4acc-9649-53fc38ee1667","bc4a4348-cfcc-4e5e-908e-8a52a8915fe6","9e5c1297-6eed-40c0-825a-d9bcd86e3193","e534761c-1894-4b61-b20c-658a6fb68157","8761f73f-6cf9-4186-8aaa-0948ed002db1","874a26fd-142f-4173-8c5b-890cd846c74d","0e24a717-b97e-4b77-9c94-b59a5a88b2da","75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2","153c8bf7-fb89-4d89-b263-47e58b1b4774","55c3e0ce-275a-46fa-82ff-e0465f5e8703","24babf58-7156-4841-9a3f-761bdbb8e237","aca261d8-e145-4610-9e20-9eff990f2c12","0642fba6-5dcf-4d62-8e7b-94dbb529d117","25a863e8-dc42-4e8a-a357-e76422ace9b5","9538f37c-456e-4047-81be-6435045608d4","8c0f84c3-9afd-4396-b5f5-9bca2c911c20","be582e5d-b123-41a2-a150-454c39e961c8","c70141d4-ba06-41ea-bcbc-35ea81cb8335","7d1826f4-24c4-4aac-8c2e-eff45df37783","063c97d3-033a-4e9b-98d8-05c8074922cb","00000000-0000-0000-0000-000000000120"}; +const int COLLISION_SOUNDS_SIZE=29; + +// NaClAntiSpamQueueEntry + +NACLAntiSpamQueueEntry::NACLAntiSpamQueueEntry() +{ + entryTime=0; + entryAmount=0; + blocked=false; +} +void NACLAntiSpamQueueEntry::clearEntry() +{ + entryTime=0; + entryAmount=0; + blocked=false; +} +U32 NACLAntiSpamQueueEntry::getEntryAmount() +{ + return entryAmount; +} +U32 NACLAntiSpamQueueEntry::getEntryTime() +{ + return entryTime; +} +void NACLAntiSpamQueueEntry::updateEntryAmount() +{ + entryAmount++; +} +void NACLAntiSpamQueueEntry::updateEntryTime() +{ + entryTime=time(0); +} +void NACLAntiSpamQueueEntry::setBlocked() +{ + blocked=true; +} +bool NACLAntiSpamQueueEntry::getBlocked() +{ + return blocked; +} + +// NaClAntiSpamQueue + +NACLAntiSpamQueue::NACLAntiSpamQueue(U32 time, U32 amount) +{ + queueTime=time; + queueAmount=amount; +} +void NACLAntiSpamQueue::setAmount(U32 amount) +{ + queueAmount=amount; +} +void NACLAntiSpamQueue::setTime(U32 time) +{ + queueTime=time; +} +void NACLAntiSpamQueue::clearEntries() +{ + for(it = entries.begin(); it != entries.end(); it++) + { + it->second->clearEntry(); + } +} +void NACLAntiSpamQueue::purgeEntries() +{ + for(it = entries.begin(); it != entries.end(); it++) + { + delete it->second; + } + entries.clear(); +} +void NACLAntiSpamQueue::blockEntry(LLUUID& source) +{ + it=entries.find(source.asString()); + if(it == entries.end()) + { + entries[source.asString()]=new NACLAntiSpamQueueEntry(); + } + entries[source.asString()]->setBlocked(); +} +int NACLAntiSpamQueue::checkEntry(LLUUID& name, U32 multiplier) +{ + it=entries.find(name.asString()); + if(it != entries.end()) + { + if(it->second->getBlocked()) return 2; + U32 eTime=it->second->getEntryTime(); + U32 currentTime=time(0); + if((currentTime-eTime) <= queueTime) + { + it->second->updateEntryAmount(); + U32 eAmount=it->second->getEntryAmount(); + if(eAmount > (queueAmount*multiplier)) + { + it->second->setBlocked(); + return 1; + } + else + return 0; + } + else + { + it->second->clearEntry(); + it->second->updateEntryAmount(); + it->second->updateEntryTime(); + return 0; + } + } + else + { + entries[name.asString()]=new NACLAntiSpamQueueEntry(); + entries[name.asString()]->updateEntryAmount(); + entries[name.asString()]->updateEntryTime(); + return 0; + } +} + +// NaClAntiSpamRegistry + +static const char* QUEUE_NAME[NACLAntiSpamRegistry::QUEUE_MAX] = { +"Chat", +"Inventory", +"Instant Message", +"Calling Card", +"Sound", +"Sound Preload", +"Script Dialog", +"Teleport"}; + +NACLAntiSpamRegistry::NACLAntiSpamRegistry(U32 time, U32 amount) +{ + globalTime=time; + globalAmount=amount; + static LLCachedControl _NACL_AntiSpamGlobalQueue(gSavedSettings,"_NACL_AntiSpamGlobalQueue"); + bGlobalQueue=_NACL_AntiSpamGlobalQueue; + for(int queue = 0; queue < QUEUE_MAX; ++queue) + { + queues[queue] = new NACLAntiSpamQueue(time,amount); + } +} +const char* NACLAntiSpamRegistry::getQueueName(U32 queue_id) +{ + if(queue_id >= QUEUE_MAX) + return "Unknown"; + return QUEUE_NAME[queue_id]; +} +void NACLAntiSpamRegistry::registerQueues(U32 time, U32 amount) +{ + globalTime=time; + globalAmount=amount; + static LLCachedControl _NACL_AntiSpamGlobalQueue(gSavedSettings,"_NACL_AntiSpamGlobalQueue"); + bGlobalQueue=_NACL_AntiSpamGlobalQueue; + for(int queue = 0; queue < QUEUE_MAX; ++queue) + { + queues[queue] = new NACLAntiSpamQueue(time,amount); + } +} +void NACLAntiSpamRegistry::registerQueue(U32 name, U32 time, U32 amount) +{ + /* + it=queues.find(name); + if(it == queues.end()) + { + queues[name]=new NACLAntiSpamQueue(time,amount); + } + */ +} +void NACLAntiSpamRegistry::setRegisteredQueueTime(U32 name, U32 time) +{ + if(name >= QUEUE_MAX || queues[name] == 0) + { + LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(name) << llendl; + return; + } + + queues[name]->setTime(time); +} +void NACLAntiSpamRegistry::setRegisteredQueueAmount(U32 name, U32 amount) +{ + if(name >= QUEUE_MAX || queues[name] == 0) + { + LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(name) << llendl; + return; + } + + queues[name]->setAmount(amount); +} +void NACLAntiSpamRegistry::setAllQueueTimes(U32 time) +{ + globalTime=time; + for(int queue = 0; queue < QUEUE_MAX; ++queue) + queues[queue]->setTime(time); +} +void NACLAntiSpamRegistry::setAllQueueAmounts(U32 amount) +{ + globalAmount=amount; + for(int queue = 0; queue < QUEUE_MAX; ++queue) + { + if(queue == QUEUE_SOUND || queue == QUEUE_SOUND_PRELOAD) + queues[queue]->setAmount(amount*5); + else + queues[queue]->setAmount(amount); + } +} +void NACLAntiSpamRegistry::clearRegisteredQueue(U32 name) +{ + if(name >= QUEUE_MAX || queues[name] == 0) + { + LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(name) << llendl; + return; + } + + queues[name]->clearEntries(); +} +void NACLAntiSpamRegistry::purgeRegisteredQueue(U32 name) +{ + if(name >= QUEUE_MAX || queues[name] == 0) + { + LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(name) << llendl; + return; + } + + queues[name]->purgeEntries(); +} +void NACLAntiSpamRegistry::blockOnQueue(U32 name, LLUUID& source) +{ + if(bGlobalQueue) + { + NACLAntiSpamRegistry::blockGlobalEntry(source); + } + else + { + if(name >= QUEUE_MAX || queues[name] == 0) + { + LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(name) << llendl; + return; + } + queues[name]->blockEntry(source); + } +} +void NACLAntiSpamRegistry::blockGlobalEntry(LLUUID& source) +{ + it2=globalEntries.find(source.asString()); + if(it2 == globalEntries.end()) + { + globalEntries[source.asString()]=new NACLAntiSpamQueueEntry(); + } + globalEntries[source.asString()]->setBlocked(); +} +bool NACLAntiSpamRegistry::checkQueue(U32 name, LLUUID& source, U32 multiplier, bool silent) +{ + if(source.isNull()) return false; + if(gAgent.getID() == source) return false; + LLViewerObject *obj=gObjectList.findObject(source); + if(obj) + if(obj->permYouOwner()) return false; + + int result; + if(bGlobalQueue) + { + result=NACLAntiSpamRegistry::checkGlobalEntry(source,multiplier); + } + else + { + if(name >= QUEUE_MAX || queues[name] == 0) + { + LL_ERRS("AntiSpam") << "CODE BUG: Attempting to use a antispam queue that was not created or was outside of the reasonable range of queues. Queue: " << getQueueName(name) << llendl; + return false; + } + result=queues[name]->checkEntry(source,multiplier); + } + if(result==0) + { + return false; + } + else if(result==2) + { + return true; + } + else + { + if(!silent) + { + LLSD args; + args["MESSAGE"] = std::string(getQueueName(name))+": Blocked object "+source.asString(); + LLNotificationsUtil::add("SystemMessageTip", args); + } + return true; + } +} + +// Global queue stoof +void NACLAntiSpamRegistry::setGlobalQueue(bool value) +{ + NACLAntiSpamRegistry::purgeAllQueues(); + bGlobalQueue=value; +} +void NACLAntiSpamRegistry::setGlobalAmount(U32 amount) +{ + globalAmount=amount; +} +void NACLAntiSpamRegistry::setGlobalTime(U32 time) +{ + globalTime=time; +} +void NACLAntiSpamRegistry::clearAllQueues() +{ + if(bGlobalQueue) + NACLAntiSpamRegistry::clearGlobalEntries(); + else + for(int queue = 0; queue < QUEUE_MAX; ++queue) + { + queues[queue]->clearEntries(); + } +} +void NACLAntiSpamRegistry::purgeAllQueues() +{ + if(bGlobalQueue) + NACLAntiSpamRegistry::purgeGlobalEntries(); + else + for(int queue = 0; queue < QUEUE_MAX; ++queue) + { + queues[queue]->purgeEntries(); + } +} +int NACLAntiSpamRegistry::checkGlobalEntry(LLUUID& name, U32 multiplier) +{ + it2=globalEntries.find(name.asString()); + if(it2 != globalEntries.end()) + { + if(it2->second->getBlocked()) return 2; + U32 eTime=it2->second->getEntryTime(); + U32 currentTime=time(0); + if((currentTime-eTime) <= globalTime) + { + it2->second->updateEntryAmount(); + U32 eAmount=it2->second->getEntryAmount(); + if(eAmount > (globalAmount*multiplier)) + return 1; + else + return 0; + } + else + { + it2->second->clearEntry(); + it2->second->updateEntryAmount(); + it2->second->updateEntryTime(); + return 0; + } + } + else + { + globalEntries[name.asString()]=new NACLAntiSpamQueueEntry(); + globalEntries[name.asString()]->updateEntryAmount(); + globalEntries[name.asString()]->updateEntryTime(); + return 0; + } +} +void NACLAntiSpamRegistry::clearGlobalEntries() +{ + for(it2 = globalEntries.begin(); it2 != globalEntries.end(); it2++) + { + it2->second->clearEntry(); + } +} +void NACLAntiSpamRegistry::purgeGlobalEntries() +{ + for(it2 = globalEntries.begin(); it2 != globalEntries.end(); it2++) + { + delete it2->second; + it2->second = 0; + } + globalEntries.clear(); +} \ No newline at end of file diff --git a/indra/newview/NACLantispam.h b/indra/newview/NACLantispam.h new file mode 100644 index 000000000..8706aa124 --- /dev/null +++ b/indra/newview/NACLantispam.h @@ -0,0 +1,90 @@ +#ifndef NACLANTISPAM_H +#define NACLANTISPAM_H +#include +#include "stdtypes.h" +#include "lluuid.h" +class NACLAntiSpamQueueEntry +{ + friend class NACLAntiSpamQueue; + friend class NACLAntiSpamRegistry; +protected: + NACLAntiSpamQueueEntry(); + void clearEntry(); + U32 getEntryAmount(); + U32 getEntryTime(); + void updateEntryAmount(); + void updateEntryTime(); + bool getBlocked(); + void setBlocked(); +private: + U32 entryAmount; + U32 entryTime; + bool blocked; +}; +class NACLAntiSpamQueue +{ + friend class NACLAntiSpamRegistry; +protected: + NACLAntiSpamQueue(U32 time, U32 amount); + void setAmount(U32 amount); + void setTime(U32 time); + void clearEntries(); + void purgeEntries(); + void blockEntry(LLUUID& source); + int checkEntry(LLUUID& source, U32 multiplier); +private: + std::tr1::unordered_map entries; + std::tr1::unordered_map::iterator it; + U32 queueAmount; + U32 queueTime; +}; +class NACLAntiSpamRegistry +{ +public: + NACLAntiSpamRegistry(U32 time=2, U32 amount=10); + static void registerQueues(U32 time=2, U32 amount=10); + static void registerQueue(U32 name, U32 time, U32 amount); + static void setRegisteredQueueTime(U32 name, U32 time); + static void setRegisteredQueueAmount(U32 name,U32 amount); + static void setAllQueueTimes(U32 amount); + static void setAllQueueAmounts(U32 time); + static bool checkQueue(U32 name, LLUUID& source, U32 multiplier=1, bool silent=false); + static void clearRegisteredQueue(U32 name); + static void purgeRegisteredQueue(U32 name); + static void clearAllQueues(); + static void purgeAllQueues(); + static void setGlobalQueue(bool value); + static void setGlobalAmount(U32 amount); + static void setGlobalTime(U32 time); + static void blockOnQueue(U32 name,LLUUID& owner_id); + enum { + QUEUE_CHAT, + QUEUE_INVENTORY, + QUEUE_IM, + QUEUE_CALLING_CARD, + QUEUE_SOUND, + QUEUE_SOUND_PRELOAD, + QUEUE_SCRIPT_DIALOG, + QUEUE_TELEPORT, + QUEUE_MAX + }; +private: + static const char* getQueueName(U32 queue_id); + static NACLAntiSpamQueue* queues[QUEUE_MAX]; + static std::tr1::unordered_map globalEntries; + static std::tr1::unordered_map::iterator it2; + static U32 globalTime; + static U32 globalAmount; + static bool bGlobalQueue; + + static int checkGlobalEntry(LLUUID& source, U32 multiplier); + static void clearGlobalEntries(); + static void purgeGlobalEntries(); + static void blockGlobalEntry(LLUUID& source); +}; + + +extern const std::string COLLISION_SOUNDS[]; +extern const int COLLISION_SOUNDS_SIZE; + +#endif //NACLANTISPAM_H diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5dc30d0c3..f6a4526fe 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8,7 +8,6 @@ settings_sh.xml settings_rlv.xml - SianaRenderDeferredInvisiprim Comment @@ -895,6 +894,72 @@ Value 1 + _NACL_AntiSpamGlobalQueue + + Comment + + Persist + 1 + Type + Boolean + Value + 0 + + _NACL_AntiSpamTime + + Comment + + Persist + 1 + Type + U32 + Value + 2 + + _NACL_AntiSpamAmount + + Comment + + Persist + 1 + Type + U32 + Value + 10 + + _NACL_AntiSpamSoundMulti + + Comment + + Persist + 1 + Type + U32 + Value + 4 + + _NACL_AntiSpamNewlines + + Comment + How many newlines a message can have before it's considered spam. + Persist + 1 + Type + U32 + Value + 30 + + _NACL_AntiSpamSoundPreloadMulti + + Comment + + Persist + 1 + Type + U32 + Value + 4 + AgentChatColor @@ -15097,3 +15162,4 @@ + diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d0ba0a140..ac99480f0 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -100,6 +100,8 @@ #include "llattachmentsmgr.h" // [/RLVa:KB] +#include "NACLantispam.h" // for NaCl Antispam Registry + using namespace LLVOAvatarDefines; const BOOL ANIMATE = TRUE; @@ -665,6 +667,10 @@ void LLAgent::setRegion(LLViewerRegion *regionp) << " located at " << ip << llendl; if (mRegionp) { + // NaCl - Antispam Registry + NACLAntiSpamRegistry::purgeAllQueues(); + // NaCl End + // We've changed regions, we're now going to change our agent coordinate frame. mAgentOriginGlobal = regionp->getOriginGlobal(); LLVector3d agent_offset_global = mRegionp->getOriginGlobal(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 18aaabef4..856b6d43b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -233,6 +233,8 @@ #include "lldxhardware.h" #endif +#include "NACLantispam.h" // for NaCl Antispam Registry + // // exported globals // @@ -1057,6 +1059,12 @@ bool idle_startup() LLFile::mkdir(gDirUtilp->getChatLogsDir()); LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); + // NaCl - Antispam + U32 antispam_time = gSavedSettings.getU32("_NACL_AntiSpamTime"); + U32 antispam_amount = gSavedSettings.getU32("_NACL_AntiSpamAmount"); + NACLAntiSpamRegistry::registerQueues(antispam_time, antispam_amount); + // NaCl End + //good as place as any to create user windlight directories std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", "")); LLFile::mkdir(user_windlight_path_name.c_str()); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 755e97e1c..d884029ab 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -83,6 +83,8 @@ #include "lldrawpoolbump.h" #include "emeraldboobutils.h" +#include "NACLantispam.h" // for NaCl Antispam Registry + #ifdef TOGGLE_HACKED_GODLIKE_VIEWER BOOL gHackGodmode = FALSE; #endif @@ -572,6 +574,25 @@ bool handleVoiceClientPrefsChanged(const LLSD& newvalue) return true; } +// NaCl - Antispam Registry +bool handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue) +{ + NACLAntiSpamRegistry::setGlobalQueue(newvalue.asBoolean()); + return true; +} +bool handleNaclAntiSpamTimeChanged(const LLSD& newvalue) +{ + NACLAntiSpamRegistry::setAllQueueTimes(newvalue.asInteger()); + return true; +} +bool handleNaclAntiSpamAmountChanged(const LLSD& newvalue) +{ + NACLAntiSpamRegistry::setAllQueueAmounts(newvalue.asInteger()); + return true; +} +// NaCl End + + bool handleTranslateChatPrefsChanged(const LLSD& newvalue) { LLFloaterChat* floaterp = LLFloaterChat::getInstance(); @@ -794,6 +815,12 @@ void settings_setup_listeners() // [/Ansariel: Display name support] gSavedSettings.getControl("AllowLargeSounds")->getSignal()->connect(boost::bind(&handleAllowLargeSounds, _2)); + + // NaCl - Antispam Registry + gSavedSettings.getControl("_NACL_AntiSpamGlobalQueue")->getSignal()->connect(boost::bind(&handleNaclAntiSpamGlobalQueueChanged, _2)); + gSavedSettings.getControl("_NACL_AntiSpamTime")->getSignal()->connect(boost::bind(&handleNaclAntiSpamTimeChanged, _2)); + gSavedSettings.getControl("_NACL_AntiSpamAmount")->getSignal()->connect(boost::bind(&handleNaclAntiSpamAmountChanged, _2)); + // NaCl End } void onCommitControlSetting_gSavedSettings(LLUICtrl* ctrl, void* name) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 00ec70cd1..45b33e1cb 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -179,6 +179,13 @@ #include "llwindebug.h" // For the invalid message handler #endif +// NaCl - Antispam Registry +#include "NACLantispam.h" +// NaCl - Newline flood protection +#include +static const boost::regex NEWLINES("\\n{1}"); +// NaCl End + // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) #include "llfloateravatarinfo.h" extern LLMap< const LLUUID, LLFloaterAvatarInfo* > gAvatarInfoInstances; // Only defined in llfloateravatarinfo.cpp @@ -1698,6 +1705,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) { + // NaCl - Antispam Registry + if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_INVENTORY,info->mFromID)) + return; + // NaCl End + //Until throttling is implmented, busy mode should reject inventory instead of silently //accepting it. SEE SL-39554 if (gAgent.getBusy()) @@ -1987,6 +1999,24 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) //msg->getData("MessageBlock", "Count", &count); msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name); msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message); + // NaCl - Newline flood protection + LLViewerObject* obj=gObjectList.findObject(from_id); + if(!from_id.isNull() //Not from nothing. + && gAgent.getID() != from_id //Not from self. + && !(obj && obj->permYouOwner())) //Not from own object. + { + static LLCachedControl SpamNewlines(gSavedSettings,"_NACL_AntiSpamNewlines"); + boost::sregex_iterator iter(message.begin(), message.end(), NEWLINES); + if(std::abs(std::distance(iter, boost::sregex_iterator())) > SpamNewlines) + { + NACLAntiSpamRegistry::blockOnQueue((U32)NACLAntiSpamRegistry::QUEUE_IM,from_id); + LLSD args; + args["MESSAGE"] = "Message: Blocked newline flood from "+from_id.asString(); + LLNotificationsUtil::add("SystemMessageTip", args); + return; + } + } + // NaCl End msg->getU32Fast(_PREHASH_MessageBlock, _PREHASH_ParentEstateID, parent_estate_id); msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_RegionID, region_id); msg->getVector3Fast(_PREHASH_MessageBlock, _PREHASH_Position, position); @@ -1994,6 +2024,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket); EInstantMessage dialog = (EInstantMessage)d; + // NaCl - Antispam Registry + if((dialog != IM_TYPING_START && dialog != IM_TYPING_STOP) + && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_IM,from_id)) + return; + // NaCl End + // make sure that we don't have an empty or all-whitespace name LLStringUtil::trim(name); if (name.empty()) @@ -3196,6 +3232,12 @@ void process_offer_callingcard(LLMessageSystem* msg, void**) LLUUID source_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, source_id); + + // NaCl - Antispam Registry + if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_CALLING_CARD,source_id)) + return; + // NaCl End + LLUUID tid; msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid); @@ -3385,6 +3427,14 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) msg->getU8("ChatData", "ChatType", type_temp); chat.mChatType = (EChatType)type_temp; + + // NaCL - Antispam Registry + if((chat.mChatType != CHAT_TYPE_START && chat.mChatType != CHAT_TYPE_STOP) //Chat type isn't typing + &&((owner_id.isNull() && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_CHAT,from_id)) //Spam from an object? + ||(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_CHAT,owner_id)))) //Spam from a resident? + return; + // NaCl End + msg->getU8Fast(_PREHASH_ChatData, _PREHASH_Audible, audible_temp); chat.mAudible = (EChatAudible)audible_temp; @@ -3509,6 +3559,25 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) if (is_audible) { msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg); + + // NaCl - Newline flood protection + LLViewerObject* obj=gObjectList.findObject(from_id); + if(!(from_id.isNull()) //Not from nothing. + || !(gAgent.getID() != from_id) //Not from self. + || !(obj && obj->permYouOwner())) //Not from own object. + { + static LLCachedControl SpamNewlines(gSavedSettings,"_NACL_AntiSpamNewlines"); + boost::sregex_iterator iter(mesg.begin(), mesg.end(), NEWLINES); + if(std::abs(std::distance(iter, boost::sregex_iterator())) > SpamNewlines) + { + NACLAntiSpamRegistry::blockOnQueue((U32)NACLAntiSpamRegistry::QUEUE_CHAT,owner_id); + LLSD args; + args["MESSAGE"] = "Chat: Blocked newline flood from "+owner_id.asString(); + LLNotificationsUtil::add("SystemMessageTip", args); + return; + } + } + // NaCl End static std::map sChatObjectAuth; @@ -4840,6 +4909,23 @@ void process_sound_trigger(LLMessageSystem *msg, void **) msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_SoundID, sound_id); msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_OwnerID, owner_id); msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ObjectID, object_id); + + // NaCl - Antispam Registry + /*if(owner_id.isNull()) + {*/ + bool bDoSpamCheck=1; + std::string sSound=sound_id.asString(); + static LLCachedControl _NACL_AntiSpamSoundMulti(gSavedSettings,"_NACL_AntiSpamSoundMulti"); + for(int i=0;i< COLLISION_SOUNDS_SIZE;i++) + if(COLLISION_SOUNDS[i] == sSound) + bDoSpamCheck=0; + if(bDoSpamCheck) + if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND,object_id, _NACL_AntiSpamSoundMulti,true)) return; + /*} + else + if(NACLAntiSpamRegistry::checkQueue("Soundspam",owner_id)) return;*/ + // NaCl End + msg->getUUIDFast(_PREHASH_SoundData, _PREHASH_ParentID, parent_id); msg->getU64Fast(_PREHASH_SoundData, _PREHASH_Handle, region_handle); msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local); @@ -4903,6 +4989,14 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data) msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id); msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id); + // NaCl - Antispam Registry + static LLCachedControl _NACL_AntiSpamSoundPreloadMulti(gSavedSettings,"_NACL_AntiSpamSoundPreloadMulti"); + if((owner_id.isNull() + && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND_PRELOAD,object_id,_NACL_AntiSpamSoundPreloadMulti)) + || NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND_PRELOAD,owner_id,_NACL_AntiSpamSoundPreloadMulti)) + return; + // NaCl End + LLViewerObject *objectp = gObjectList.findObject(object_id); if (!objectp) return; @@ -4938,6 +5032,14 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data) msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_SoundID, sound_id); msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_ObjectID, object_id); msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_OwnerID, owner_id); + + // NaCl - Antispam Registry + if(/*owner_id.isNull() + &&*/ NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SOUND,object_id)) + /*|| (NACLAntiSpamRegistry::checkQueue("Soundspam",owner_id))*/ + return; + // NaCl End + msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain); msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags); @@ -6030,6 +6132,12 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/) void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted) { + + // NaCl - Antispam Registry + if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, notification["payload"]["task_id"].asUUID())) + return; + // NaCl End + // only continue if at least some permissions were requested if (orig_questions) { @@ -6210,6 +6318,14 @@ void process_script_question(LLMessageSystem *msg, void **user_data) msg->getUUIDFast(_PREHASH_Data, _PREHASH_TaskID, taskid ); // itemid -> script asset key of script requesting permissions msg->getUUIDFast(_PREHASH_Data, _PREHASH_ItemID, itemid ); + + // NaCl - Antispam Registry + if((taskid.isNull() + && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,itemid)) + || NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,taskid)) + return; + // NaCl End + msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectName, object_name); msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, owner_name); msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions ); @@ -6874,11 +6990,22 @@ void process_script_dialog(LLMessageSystem* msg, void**) LLUUID object_id; msg->getUUID("Data", "ObjectID", object_id); -// For compability with OS grids first check for presence of extended packet before fetching data. + // NaCl - Antispam Registry + if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,object_id)) + return; + // NaCl End + + // For compability with OS grids first check for presence of extended packet before fetching data. LLUUID owner_id; if (gMessageSystem->getNumberOfBlocks("OwnerData") > 0) { msg->getUUID("OwnerData", "OwnerID", owner_id); + + // NaCl - Antispam Registry + if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,owner_id)) + return; + // NaCl End + } if (LLMuteList::getInstance()->isMuted(object_id) || LLMuteList::getInstance()->isMuted(owner_id)) @@ -7048,6 +7175,14 @@ void process_load_url(LLMessageSystem* msg, void**) msg->getString("Data", "ObjectName", 256, object_name); msg->getUUID( "Data", "ObjectID", object_id); msg->getUUID( "Data", "OwnerID", owner_id); + + // NaCl - Antispam Registry + if((owner_id.isNull() + && NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,object_id)) + || NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,owner_id)) + return; + // NaCl End + msg->getBOOL( "Data", "OwnerIsGroup", owner_is_group); msg->getString("Data", "Message", 256, message); msg->getString("Data", "URL", 256, url); From 8bfdc98ef4b21e86dcd639012a0f4ec485e7c190 Mon Sep 17 00:00:00 2001 From: Drake Arconis Date: Thu, 19 Jul 2012 17:44:13 -0400 Subject: [PATCH 013/103] Improvements! Fixed Boost library to not throw warnings Changed PNG cmake slightly Updated 32lib package for correct locations Cleaned up flags a bit for linux64 --- indra/cmake/00-Common.cmake | 10 +++++----- indra/cmake/PNG.cmake | 2 +- indra/llimage/llpngwrapper.h | 2 +- install.xml | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 9006b2247..5c0d433be 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -190,10 +190,10 @@ if (LINUX) endif (NOT STANDALONE) if (${ARCH} STREQUAL "x86_64") add_definitions(-DLINUX64=1 -pipe) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fomit-frame-pointer -mmmx -msse -mfpmath=sse -msse2 -ffast-math -ftree-vectorize -fweb -fexpensive-optimizations -frename-registers") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffast-math -funroll-loops") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -ffast-math -funroll-loops") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -ffast-math") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ffast-math") else (${ARCH} STREQUAL "x86_64") if (NOT STANDALONE) set(MARCH_FLAG " -march=pentium4") @@ -327,7 +327,7 @@ else (STANDALONE) glib-2.0 gstreamer-0.10 gtk-2.0 - llfreetype2 + freetype2 pango-1.0 ) endif (STANDALONE) diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake index 269b54de7..011b87f64 100644 --- a/indra/cmake/PNG.cmake +++ b/indra/cmake/PNG.cmake @@ -15,5 +15,5 @@ else (STANDALONE) else(LINUX) set(PNG_LIBRARIES png15) endif() - set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libpng15) + set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/) endif (STANDALONE) diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h index a4c3d80b5..7def0c713 100644 --- a/indra/llimage/llpngwrapper.h +++ b/indra/llimage/llpngwrapper.h @@ -32,7 +32,7 @@ #ifndef LL_LLPNGWRAPPER_H #define LL_LLPNGWRAPPER_H -#include "png.h" +#include "libpng15/png.h" #include "llimage.h" class LLPngWrapper diff --git a/install.xml b/install.xml index 405dd7233..dd94fa71c 100644 --- a/install.xml +++ b/install.xml @@ -20,9 +20,9 @@ linux64 md5sum - cbaafc55fb8b14283541791e82f13462 + 5add23ded1a53f57044132cb1aed4950 url - http://imprudenceviewer.org/download/libs/linux64-32bitcompatibilitylibs-20100903.tar.bz2 + https://github.com/downloads/LightDrake/Public-Libraries/linux64-32bitcompatibilitylibs-20100903_1.tar.bz2 @@ -188,9 +188,9 @@ linux64 md5sum - a7c23f5395f79033dbb09b201f16a4ce + ac6e5b52d5cf13443607c09d8c62b6c5 url - https://github.com/downloads/LightDrake/Public-Libraries/boost-1.48.0-linux-x86_64-20120514.tar.bz2 + https://github.com/downloads/LightDrake/Public-Libraries/boost-1.48.0-linux-x86_64-20120719.tar.bz2 windows From f3f8bee83b275f6a1fbb179c0e97c9ae2cdfb9a8 Mon Sep 17 00:00:00 2001 From: Lirusaito Date: Thu, 19 Jul 2012 23:40:07 -0400 Subject: [PATCH 014/103] Remove old spam stuffs, Clean up new spam stuffs to compile, UI new spam stuffs. --- indra/newview/NACLantispam.cpp | 18 +- indra/newview/NACLantispam.h | 3 + indra/newview/app_settings/settings.xml | 11 ++ indra/newview/app_settings/settings_sh.xml | 88 ---------- indra/newview/ascentprefschat.cpp | 43 +++-- indra/newview/ascentprefschat.h | 11 +- indra/newview/llstartup.cpp | 4 + indra/newview/llviewercontrol.cpp | 25 --- indra/newview/llviewermessage.cpp | 166 +++++++----------- .../en-us/panel_preferences_ascent_chat.xml | 22 +-- 10 files changed, 138 insertions(+), 253 deletions(-) diff --git a/indra/newview/NACLantispam.cpp b/indra/newview/NACLantispam.cpp index 5e6be5d9d..95aad581b 100644 --- a/indra/newview/NACLantispam.cpp +++ b/indra/newview/NACLantispam.cpp @@ -387,4 +387,20 @@ void NACLAntiSpamRegistry::purgeGlobalEntries() it2->second = 0; } globalEntries.clear(); -} \ No newline at end of file +} +bool NACLAntiSpamRegistry::handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue) +{ + setGlobalQueue(newvalue.asBoolean()); + return true; +} +bool NACLAntiSpamRegistry::handleNaclAntiSpamTimeChanged(const LLSD& newvalue) +{ + setAllQueueTimes(newvalue.asInteger()); + return true; +} +bool NACLAntiSpamRegistry::handleNaclAntiSpamAmountChanged(const LLSD& newvalue) +{ + setAllQueueAmounts(newvalue.asInteger()); + return true; +} + diff --git a/indra/newview/NACLantispam.h b/indra/newview/NACLantispam.h index 8706aa124..2f65fc423 100644 --- a/indra/newview/NACLantispam.h +++ b/indra/newview/NACLantispam.h @@ -49,6 +49,9 @@ public: static void setAllQueueTimes(U32 amount); static void setAllQueueAmounts(U32 time); static bool checkQueue(U32 name, LLUUID& source, U32 multiplier=1, bool silent=false); + static bool handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue); + static bool handleNaclAntiSpamTimeChanged(const LLSD& newvalue); + static bool handleNaclAntiSpamAmountChanged(const LLSD& newvalue); static void clearRegisteredQueue(U32 name); static void purgeRegisteredQueue(U32 name); static void clearAllQueues(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f6a4526fe..45121a899 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -893,6 +893,17 @@ Boolean Value 1 + + _NACL_Antispam + + Comment + When true, all dialogs will be blocked, resets on restart. + Persist + 0 + Type + Boolean + Value + 0 _NACL_AntiSpamGlobalQueue diff --git a/indra/newview/app_settings/settings_sh.xml b/indra/newview/app_settings/settings_sh.xml index feae4cb77..81659467c 100644 --- a/indra/newview/app_settings/settings_sh.xml +++ b/indra/newview/app_settings/settings_sh.xml @@ -141,94 +141,6 @@ 1.0 - SGBlockGeneralSpam - - Comment - Enable automatic general spam blocking - Persist - 1 - Type - Boolean - Value - 0 - - SGBlockCardSpam - - Comment - Enable automatic calling card spam blocking - Persist - 1 - Type - Boolean - Value - 1 - - SGBlockChatSpam - - Comment - Enable automatic chat spam blocking - Persist - 1 - Type - Boolean - Value - 0 - - SGBlockDialogSpam - - Comment - Enable automatic dialog spam blocking - Persist - 1 - Type - Boolean - Value - 1 - - SGSpamTime - - Comment - Time of Evalulating spam. (Default: 1.000) - Persist - 1 - Type - F32 - Value - 1.0 - - SGSpamCount - - Comment - Number of items spammed per time period in SGSpamTime. (Default: 4) - Persist - 1 - Type - U32 - Value - 4 - - SGChatSpamTime - - Comment - Time of Evalulating spam. (Default: 1.000) - Persist - 1 - Type - F32 - Value - 1.0 - - SGChatSpamCount - - Comment - Number of items spammed per time set in SGSpamTime. (Default: 10) - Persist - 1 - Type - U32 - Value - 10.0 - ShyotlUseLegacyTextureBatching Comment diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index 0410ce2aa..29e5d3ff0 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -40,6 +40,7 @@ #include "llradiogroup.h" #include "lluictrlfactory.h" #include "llviewercontrol.h" +#include "NACLantispam.h" #include "lgghunspell_wrapper.h" #include "llstartup.h" @@ -78,7 +79,8 @@ LLPrefsAscentChat::LLPrefsAscentChat() addChild(mObjectDropTarget); } - if (LLStartUp::getStartupState() == STATE_STARTED) + bool started = LLStartUp::getStartupState() == STATE_STARTED; + if (started) { LLUUID itemid = (LLUUID)gSavedPerAccountSettings.getString("AscentInstantMessageResponseItemData"); LLViewerInventoryItem* item = gInventory.getItem(itemid); @@ -91,6 +93,9 @@ LLPrefsAscentChat::LLPrefsAscentChat() childSetCommitCallback("im_response", onCommitAutoResponse, this); + childSetEnabled("reset_antispam", started); + childSetCommitCallback("reset_antispam", onCommitResetAS, this); + childSetCommitCallback("KeywordsOn", onCommitKeywords, this); childSetCommitCallback("KeywordsList", onCommitKeywords, this); childSetCommitCallback("KeywordsSound", onCommitKeywords, this); @@ -218,7 +223,7 @@ void LLPrefsAscentChat::onCommitTimeDate(LLUICtrl* ctrl, void* userdata) //static void LLPrefsAscentChat::onCommitAutoResponse(LLUICtrl* ctrl, void* user_data) { - LLPrefsAscentChat* self = (LLPrefsAscentChat*)user_data; + LLPrefsAscentChat* self = (LLPrefsAscentChat*)user_data; gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseAnyone", self->childGetValue("AscentInstantMessageResponseAnyone")); gSavedPerAccountSettings.setBOOL("AscentInstantMessageResponseFriends", self->childGetValue("AscentInstantMessageResponseFriends")); @@ -237,6 +242,12 @@ void LLPrefsAscentChat::SinguIMResponseItemDrop(LLViewerInventoryItem* item) sInst->childSetValue("im_give_disp_rect_txt","Currently set to: "+item->getName()); } +//static +void LLPrefsAscentChat::onCommitResetAS(LLUICtrl*, void*) +{ + NACLAntiSpamRegistry::purgeAllQueues(); +} + //static void LLPrefsAscentChat::onCommitKeywords(LLUICtrl* ctrl, void* user_data) { @@ -316,13 +327,13 @@ void LLPrefsAscentChat::refreshValues() mIMResponseText = gSavedPerAccountSettings.getString("AscentInstantMessageResponse"); //Spam -------------------------------------------------------------------------------- - mBlockChatSpam = gSavedSettings.getBOOL("SGBlockChatSpam"); - mChatSpamCount = gSavedSettings.getU32("SGChatSpamCount"); - mChatSpamTime = gSavedSettings.getF32("SGChatSpamTime"); - mBlockDialogSpam = gSavedSettings.getBOOL("SGBlockDialogSpam"); - mBlockCardSpam = gSavedSettings.getBOOL("SGBlockCardSpam"); - mSpamCount = gSavedSettings.getU32("SGSpamCount"); - mSpamTime = gSavedSettings.getF32("SGSpamTime"); + mGlobalQueue = gSavedSettings.getBOOL("_NACL_AntiSpamGlobalQueue"); + mChatSpamCount = gSavedSettings.getU32("_NACL_AntiSpamAmount"); + mChatSpamTime = gSavedSettings.getU32("_NACL_AntiSpamTime"); + mBlockDialogSpam = gSavedSettings.getBOOL("_NACL_Antispam"); + mSoundMulti = gSavedSettings.getU32("_NACL_AntiSpamSoundMulti"); + mNewLines = gSavedSettings.getU32("_NACL_AntiSpamNewlines"); + mPreloadMulti = gSavedSettings.getU32("_NACL_AntiSpamSoundPreloadMulti"); //Text Options ------------------------------------------------------------------------ mSpellDisplay = gSavedSettings.getBOOL("SpellDisplay"); @@ -503,13 +514,13 @@ void LLPrefsAscentChat::cancel() gSavedPerAccountSettings.setString("AscentInstantMessageResponse", mIMResponseText); //Spam -------------------------------------------------------------------------------- - gSavedSettings.setBOOL("SGBlockChatSpam", mBlockChatSpam); - gSavedSettings.setU32("SGChatSpamCount", mChatSpamCount); - gSavedSettings.setF32("SGChatSpamTime", mChatSpamTime); - gSavedSettings.setBOOL("SGBlockDialogSpam", mBlockDialogSpam); - gSavedSettings.setBOOL("SGBlockCardSpam", mBlockCardSpam); - gSavedSettings.setU32("SGSpamCount", mSpamCount); - gSavedSettings.setF32("SGSpamTime", mSpamTime); + gSavedSettings.setBOOL("_NACL_AntiSpamGlobalQueue", mGlobalQueue); + gSavedSettings.setU32("_NACL_AntiSpamAmount", mChatSpamCount); + gSavedSettings.setU32("_NACL_AntiSpamTime", mChatSpamTime); + gSavedSettings.setBOOL("_NACL_Antispam", mBlockDialogSpam); + gSavedSettings.setU32("_NACL_AntiSpamSoundMulti", mSoundMulti); + gSavedSettings.setU32("_NACL_AntiSpamNewlines", mNewLines); + gSavedSettings.setU32("_NACL_AntiSpamSoundPreloadMulti", mPreloadMulti); //Text Options ------------------------------------------------------------------------ gSavedSettings.setBOOL("SpellDisplay", mSpellDisplay); diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index 15c7a44be..d83b5b2d9 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -56,6 +56,7 @@ protected: static void onSpellBaseComboBoxCommit(LLUICtrl* ctrl, void* userdata); static void onCommitTimeDate(LLUICtrl* ctrl, void *userdata); static void onCommitAutoResponse(LLUICtrl* ctrl, void* user_data); + static void onCommitResetAS(LLUICtrl*,void*); static void onCommitKeywords(LLUICtrl* ctrl, void* user_data); //Chat/IM ----------------------------------------------------------------------------- @@ -84,13 +85,13 @@ protected: std::string mIMResponseText; //Spam -------------------------------------------------------------------------------- - BOOL mBlockChatSpam; + BOOL mGlobalQueue; U32 mChatSpamCount; - F32 mChatSpamTime; + U32 mChatSpamTime; BOOL mBlockDialogSpam; - BOOL mBlockCardSpam; - U32 mSpamCount; - F32 mSpamTime; + BOOL mSoundMulti; + U32 mNewLines; + U32 mPreloadMulti; //Text Options ------------------------------------------------------------------------ BOOL mSpellDisplay; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 856b6d43b..26773586c 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1063,6 +1063,9 @@ bool idle_startup() U32 antispam_time = gSavedSettings.getU32("_NACL_AntiSpamTime"); U32 antispam_amount = gSavedSettings.getU32("_NACL_AntiSpamAmount"); NACLAntiSpamRegistry::registerQueues(antispam_time, antispam_amount); + gSavedSettings.getControl("_NACL_AntiSpamGlobalQueue")->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamGlobalQueueChanged, _2)); + gSavedSettings.getControl("_NACL_AntiSpamTime")->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamTimeChanged, _2)); + gSavedSettings.getControl("_NACL_AntiSpamAmount")->getSignal()->connect(boost::bind(&NACLAntiSpamRegistry::handleNaclAntiSpamAmountChanged, _2)); // NaCl End //good as place as any to create user windlight directories @@ -4362,3 +4365,4 @@ bool process_login_success_response(std::string& password) } return success; } + diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index d884029ab..b6c442c6e 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -574,25 +574,6 @@ bool handleVoiceClientPrefsChanged(const LLSD& newvalue) return true; } -// NaCl - Antispam Registry -bool handleNaclAntiSpamGlobalQueueChanged(const LLSD& newvalue) -{ - NACLAntiSpamRegistry::setGlobalQueue(newvalue.asBoolean()); - return true; -} -bool handleNaclAntiSpamTimeChanged(const LLSD& newvalue) -{ - NACLAntiSpamRegistry::setAllQueueTimes(newvalue.asInteger()); - return true; -} -bool handleNaclAntiSpamAmountChanged(const LLSD& newvalue) -{ - NACLAntiSpamRegistry::setAllQueueAmounts(newvalue.asInteger()); - return true; -} -// NaCl End - - bool handleTranslateChatPrefsChanged(const LLSD& newvalue) { LLFloaterChat* floaterp = LLFloaterChat::getInstance(); @@ -815,12 +796,6 @@ void settings_setup_listeners() // [/Ansariel: Display name support] gSavedSettings.getControl("AllowLargeSounds")->getSignal()->connect(boost::bind(&handleAllowLargeSounds, _2)); - - // NaCl - Antispam Registry - gSavedSettings.getControl("_NACL_AntiSpamGlobalQueue")->getSignal()->connect(boost::bind(&handleNaclAntiSpamGlobalQueueChanged, _2)); - gSavedSettings.getControl("_NACL_AntiSpamTime")->getSignal()->connect(boost::bind(&handleNaclAntiSpamTimeChanged, _2)); - gSavedSettings.getControl("_NACL_AntiSpamAmount")->getSignal()->connect(boost::bind(&handleNaclAntiSpamAmountChanged, _2)); - // NaCl End } void onCommitControlSetting_gSavedSettings(LLUICtrl* ctrl, void* name) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 45b33e1cb..ca174d71a 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -246,75 +246,6 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = FALSE // ControlYourCamera }; -template -class SH_SpamHandler -{ -public: - SH_SpamHandler(const char *pToggleCtrl, const char *pDurCtrl, const char *pFreqCtrl) : - mDuration(pDurCtrl, 1.f), - mFrequency(pFreqCtrl, 5), - mEnabled(false) - { - gSavedSettings.getControl(pToggleCtrl)->getSignal()->connect(boost::bind(&SH_SpamHandler::CtrlToggle, this, _2)); - CtrlToggle(gSavedSettings.getBOOL(pToggleCtrl)); - } - bool CtrlToggle(const LLSD& newvalue) - { - bool on = newvalue.asBoolean(); - if(on == mEnabled) - return true; - mEnabled = on; - mTimer.stop(); - mActiveList.clear(); - mBlockedList.clear(); - return true; - } - bool isBlocked(const T &owner, const LLUUID &source_id, const char *pNotification, LLSD args=LLSD()) - { - if(!mEnabled || isAgent(owner)) - return false; - if(mBlockedList.find(owner) != mBlockedList.end()) - return true; - if(mTimer.getStarted() && mTimer.getElapsedTimeF32() < mDuration) - { - typename std::map::iterator it = mActiveList.insert(std::pair(owner,0)).first; - if(++(it->second)>=mFrequency) - { - mBlockedList.insert(owner); - if(pNotification) - { - args["OWNER"] = owner; - args["SOURCE"] = source_id; - LLNotifications::getInstance()->add(pNotification,args); - } - return true; - } - } - else - { - mActiveList.clear(); - mTimer.start(); - } - return false; - } -private: - //Owner is either a key, or a name. Do not look up perms since object may be unknown. - static bool isAgent(const T &owner); - bool mEnabled; - LLFrameTimer mTimer; - const LLCachedControl mDuration; - const LLCachedControl mFrequency; - std::map mActiveList; - std::set mBlockedList; -}; -template<> bool SH_SpamHandler::isAgent(const LLUUID &owner) { return gAgent.getID() == owner; } -template<> bool SH_SpamHandler::isAgent(const std::string &owner) -{ - std::string str; - gAgent.getName(str); - return str == owner; -} - bool friendship_offer_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -1705,11 +1636,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) { - // NaCl - Antispam Registry - if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_INVENTORY,info->mFromID)) - return; - // NaCl End - //Until throttling is implmented, busy mode should reject inventory instead of silently //accepting it. SEE SL-39554 if (gAgent.getBusy()) @@ -1717,7 +1643,12 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) info->forceResponse(IOR_BUSY); return; } - + + // NaCl - Antispam Registry + static LLCachedControl antispam(gSavedSettings,"_NACL_Antispam"); + if(antispam || NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_INVENTORY,info->mFromID)) + return; + // NaCl End //If muted, don't even go through the messaging stuff. Just curtail the offer here. if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName)) { @@ -1971,6 +1902,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { return; } + static LLCachedControl antispam(gSavedSettings,"_NACL_Antispam"); LLUUID from_id; BOOL from_group; LLUUID to_id; @@ -2059,15 +1991,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { LLSD args; args["NAME"] = name; - static SH_SpamHandler avatar_spam_check("SGBlockGeneralSpam","SGSpamTime","SGSpamCount"); - static SH_SpamHandler object_spam_check("SGBlockGeneralSpam","SGSpamTime","SGSpamCount"); - if(d==IM_FROM_TASK||d==IM_GOTO_URL||d==IM_FROM_TASK_AS_ALERT||d==IM_TASK_INVENTORY_OFFERED||d==IM_TASK_INVENTORY_ACCEPTED||d==IM_TASK_INVENTORY_DECLINED) - { - if(object_spam_check.isBlocked(from_id,session_id,"BlockedGeneralObjects",args)) - return; - } - else if(avatar_spam_check.isBlocked(from_id,from_id,"BlockedGeneralAvatar",args)) - return; } LLViewerObject *source = gObjectList.findObject(session_id); //Session ID is probably the wrong thing. @@ -2501,6 +2424,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_GROUP_NOTICE: case IM_GROUP_NOTICE_REQUESTED: { + // NaCl - Antispam + if(antispam) + return; + // NaCl End LL_INFOS("Messaging") << "Received IM_GROUP_NOTICE message." << LL_ENDL; // Read the binary bucket for more information. struct notice_bucket_header_t @@ -2596,6 +2523,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) break; case IM_GROUP_INVITATION: { + // NaCl - Antispam + if(antispam) + return; + // NaCl End //if (!is_linden && (is_busy || is_muted)) if ((is_busy || is_muted)) { @@ -2640,6 +2571,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_TASK_INVENTORY_OFFERED: // Someone has offered us some inventory. { + // NaCl - Antispam + if(antispam) + return; + // NaCl End LLOfferInfo* info = new LLOfferInfo; if (IM_INVENTORY_OFFERED == dialog) @@ -2892,6 +2827,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } break; case IM_FROM_TASK_AS_ALERT: + // NaCl - Antispam + if(antispam) + return; + // NaCl End if (is_busy && !is_owned_by_me) { return; @@ -2929,6 +2868,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_LURE_USER: { + if(antispam) return; //NaCl Antispam // [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c // If the lure sender is a specific @accepttp exception they will override muted and busy status bool fRlvSummon = (rlv_handler_t::isEnabled()) && (gRlvHandler.isException(RLV_BHVR_ACCEPTTP, from_id)); @@ -3069,6 +3009,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_GOTO_URL: { + // NaCl - Antispam + if(antispam) + return; + // NaCl End LLSD args; // n.b. this is for URLs sent by the system, not for // URLs sent by scripts (i.e. llLoadURL) @@ -3093,6 +3037,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_FRIENDSHIP_OFFERED: { + // NaCl - Antispam + if(antispam) + return; + // NaCl End LLSD payload; payload["from_id"] = from_id; payload["session_id"] = session_id;; @@ -3227,6 +3175,11 @@ static LLNotificationFunctorRegistration callingcard_offer_cb_reg("OfferCallingC void process_offer_callingcard(LLMessageSystem* msg, void**) { + // NaCl - Antispam + static LLCachedControl antispam(gSavedSettings,"_NACL_Antispam"); + if(antispam) + return; + // NaCl End // someone has offered to form a friendship LL_DEBUGS("Messaging") << "callingcard offer" << LL_ENDL; @@ -3270,9 +3223,6 @@ void process_offer_callingcard(LLMessageSystem* msg, void**) } else { - static SH_SpamHandler spam_check("SGBlockCardSpam","SHSpamTime","SGSpamCount"); - if(spam_check.isBlocked(source_id,source_id,"BlockedCards",args)) - return; LLNotificationsUtil::add("OfferCallingCard", args, payload); } } @@ -3482,12 +3432,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) { LLSD args; args["NAME"] = from_name; - static SH_SpamHandler avatar_spam_check("SGBlockChatSpam","SGChatSpamTime","SGChatSpamCount"); - static SH_SpamHandler object_spam_check("SGBlockChatSpam","SGChatSpamTime","SGChatSpamCount"); - if( (chatter->isAvatar() && avatar_spam_check.isBlocked(from_id,from_id,"BlockedChatterAvatar",args)) || - (!chatter->isAvatar() && object_spam_check.isBlocked(owner_id,from_id,"BlockedChatterObjects",args)) ) - return; - chat.mPosAgent = chatter->getPositionAgent(); // Make swirly things only for talking objects. (not script debug messages, though) @@ -6132,12 +6076,10 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/) void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted) { - - // NaCl - Antispam Registry - if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG, notification["payload"]["task_id"].asUUID())) - return; - // NaCl End - + // NaCl - Antispam Registry + LLUUID task_id = notification["payload"]["task_id"].asUUID(); + if(NACLAntiSpamRegistry::checkQueue((U32)NACLAntiSpamRegistry::QUEUE_SCRIPT_DIALOG,task_id)) return; + // NaCl End // only continue if at least some permissions were requested if (orig_questions) { @@ -6304,7 +6246,12 @@ static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestio void process_script_question(LLMessageSystem *msg, void **user_data) { - // *TODO:translate owner name -> [FIRST] [LAST] + // NaCl - Antispam + static LLCachedControl antispam(gSavedSettings,"_NACL_Antispam"); + if(antispam) + return; + // NaCl End + // *TODO: Translate owner name -> [FIRST] [LAST] LLHost sender = msg->getSender(); @@ -6984,6 +6931,11 @@ static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDia void process_script_dialog(LLMessageSystem* msg, void**) { + // NaCl - Antispam + static LLCachedControl antispam(gSavedSettings,"_NACL_Antispam"); + if(antispam) + return; + // NaCl End S32 i; LLSD payload; @@ -7078,10 +7030,6 @@ void process_script_dialog(LLMessageSystem* msg, void**) { args["NAME"] = LLCacheName::buildFullName(first_name, last_name); - static SH_SpamHandler spam_check("SGBlockDialogSpam","SGSpamTime","SGSpamCount"); - if(spam_check.isBlocked(first_name + " " + last_name,object_id,"BlockedDialogs",args)) - return; - if (is_text_box) { args["DEFAULT"] = default_text; @@ -7165,6 +7113,11 @@ void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool void process_load_url(LLMessageSystem* msg, void**) { + // NaCl - Antispam + static LLCachedControl antispam(gSavedSettings,"_NACL_Antispam"); + if(antispam) + return; + // NaCl End LLUUID object_id; LLUUID owner_id; BOOL owner_is_group; @@ -7255,6 +7208,11 @@ void process_initiate_download(LLMessageSystem* msg, void**) void process_script_teleport_request(LLMessageSystem* msg, void**) { + // NaCl - Antispam + static LLCachedControl antispam(gSavedSettings,"_NACL_Antispam"); + if(antispam) + return; + // NaCl End if (!gSavedSettings.getBOOL("ScriptsCanShowUI")) return; std::string object_name; diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_chat.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_chat.xml index 62d8c0cd3..0d5167818 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_chat.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_chat.xml @@ -68,20 +68,14 @@ - - - - seconds - - - - - seconds + +