From cdb30d7498e27828535d26dc403912a8a95df152 Mon Sep 17 00:00:00 2001 From: Nicky Date: Sat, 2 Aug 2014 14:57:53 +0200 Subject: [PATCH] FIRE-14264; FPS drop due to particle patch. --- indra/newview/CMakeLists.txt | 2 - indra/newview/fsvopartgroup.cpp | 112 -------------------------- indra/newview/fsvopartgroup.h | 58 -------------- indra/newview/llface.cpp | 21 +---- indra/newview/llface.h | 9 +-- indra/newview/llviewerpartsim.cpp | 127 +++--------------------------- indra/newview/llviewerpartsim.h | 5 -- indra/newview/llvopartgroup.cpp | 99 ++--------------------- indra/newview/llvopartgroup.h | 13 +-- 9 files changed, 23 insertions(+), 423 deletions(-) delete mode 100644 indra/newview/fsvopartgroup.cpp delete mode 100644 indra/newview/fsvopartgroup.h diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7688e434b7..3b1d2cddd8 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -186,7 +186,6 @@ set(viewer_SOURCE_FILES fsradarmenu.cpp fsscriptlibrary.cpp fsslurlcommand.cpp - fsvopartgroup.cpp fswsassetblacklist.cpp groupchatlistener.cpp #growlmanager.cpp @@ -890,7 +889,6 @@ set(viewer_HEADER_FILES fsscriptlibrary.h fsslurl.h fsslurlcommand.h - fsvopartgroup.h fswsassetblacklist.h groupchatlistener.h llaccountingcost.h diff --git a/indra/newview/fsvopartgroup.cpp b/indra/newview/fsvopartgroup.cpp deleted file mode 100644 index 9f2fa8b6a0..0000000000 --- a/indra/newview/fsvopartgroup.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file fsvopartgroup.cpp - * @brief fsvopartgroup base class - * - * $LicenseInfo:firstyear=2014&license=fsviewerlgpl$ - * Phoenix Firestorm Viewer Source Code - * Copyright (C) 2014, The Phoenix Firestorm Project, Inc. - * - * 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. - * - * 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. - * - * 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 - * - * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA - * http://www.firestormviewer.org - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llviewerpartsim.h" // For LL_MAX_PARTICLE_COUNT - -#include "fsvopartgroup.h" - - -FSVOPartGroup::FSVOPartGroup() -{ - for (S32 i = 0; i < sFreeIndexSize; ++i) - { - setFreeIndex(i, 0); - } - setIndexGeneration(1); - setTotalParticles(0); - - U32 bitMasksTmp[ 32 ] = { 0xFFFFFFFF, 0x80000000, 0xC0000000, 0xE0000000, - 0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000, - 0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000, - 0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000, - 0xFFFF0000, 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, - 0xFFFFF000, 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, - 0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, - 0xFFFFFFF0, 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE }; - - for (S32 i = 0; i < 32; ++i) - { - bitMasks[i] = bitMasksTmp[i]; - } -} - - -bool FSVOPartGroup::findAvailableVBSlots( S32 &idxStart, S32 &idxEnd, U32 amount ) -{ - idxStart = idxEnd = -1; - - if( amount + getTotalParticles() > LL_MAX_PARTICLE_COUNT ) - amount = LL_MAX_PARTICLE_COUNT - getTotalParticles(); - - U32 u32Count = amount/32; - U32 bitsLeft = amount - (u32Count*32); - if( bitsLeft ) - ++u32Count; - U32 maskLast = bitMasks[ bitsLeft ]; - - int i = 0; - int maxI = LL_MAX_PARTICLE_COUNT/32-u32Count; - do - { - while( getFreeIndex(i) != 0xFFFFFFFF && i <= maxI ) - ++i; - - if( i > maxI ) - continue; - - int j = i; - while( getFreeIndex(j) == 0xFFFFFFFF && j <= LL_MAX_PARTICLE_COUNT/32 && (j-i) != u32Count ) - ++j; - - if( j > LL_MAX_PARTICLE_COUNT/32 || (i-j) != u32Count || (getFreeIndex(j-1) & maskLast) != maskLast ) - { - ++i; - continue; - } - - int k = 0; - idxStart = i*32; - idxEnd = i + amount; - while( k != amount ) - { - for( int l = 0; k != amount && l < 32; ++l ) - { - U32 mask = 1 << l; - setFreeIndex(i, getFreeIndex(i) & ~mask); - ++k; - } - ++i; - } - - setTotalParticles(getTotalParticles() + amount); - return true; - - } while( i <= maxI); - return false; -} diff --git a/indra/newview/fsvopartgroup.h b/indra/newview/fsvopartgroup.h deleted file mode 100644 index 217840f22a..0000000000 --- a/indra/newview/fsvopartgroup.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file fsvopartgroup.h - * @brief fsvopartgroup base class - * - * $LicenseInfo:firstyear=2014&license=fsviewerlgpl$ - * Phoenix Firestorm Viewer Source Code - * Copyright (C) 2014, The Phoenix Firestorm Project, Inc. - * - * 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. - * - * 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. - * - * 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 - * - * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA - * http://www.firestormviewer.org - * $/LicenseInfo$ - */ - -#ifndef FS_VOPARTGROUP_H -#define FS_VOPARTGROUP_H - -#include "stdtypes.h" - -#define sFreeIndexSize LL_MAX_PARTICLE_COUNT/32 - -class FSVOPartGroup -{ -public: - FSVOPartGroup(); - ~FSVOPartGroup() {}; - - U32 getFreeIndex(int i) {return sFreeIndex[i];} - U32 getIndexGeneration() {return sIndexGeneration;} - U32 getTotalParticles() {return sTotalParticles;} - - void setFreeIndex(int i, U32 val) {sFreeIndex[i] = val;} - void setIndexGeneration(U32 val) {sIndexGeneration = val;} - void setTotalParticles(U32 val) {sTotalParticles = val;} - - bool findAvailableVBSlots( S32 &idxStart, S32 &idxEnd, U32 amount ); - -private: - U32 sFreeIndex[sFreeIndexSize]; - U32 sIndexGeneration; - U32 sTotalParticles; - - U32 bitMasks[ 32 ]; -}; -#endif // FS_VOPARTGROUP_H diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index a7378b093c..9c0205765b 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -166,8 +166,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mBoundingSphereRadius = 0.0f ; mHasMedia = FALSE ; - - mParticleGeneration = 0; // Default = no particle } void LLFace::destroy() @@ -185,14 +183,9 @@ void LLFace::destroy() } } - // Make sure we released any allocated VB index if this was a particle - // if (isState(LLFace::PARTICLE)) - if (isState(LLFace::PARTICLE) || mParticleGeneration ) - // + if (isState(LLFace::PARTICLE)) { - LLVOPartGroup::freeVBSlot(getGeomIndex()/4,mParticleGeneration); - mParticleGeneration = 0; - + LLVOPartGroup::freeVBSlot(getGeomIndex()/4); clearState(LLFace::PARTICLE); } @@ -421,16 +414,8 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align) llassert(verify()); } -// Pass another flag to mark this index as from LLVOPartGroup, in that case it needs to be freed with LLVOPartGroup::LLVOPartGroup -// void LLFace::setGeomIndex(U16 idx) -void LLFace::setGeomIndex(U16 idx, U32 aParticleGeneration ) -// +void LLFace::setGeomIndex(U16 idx) { - if( mParticleGeneration && mGeomIndex != idx ) - LLVOPartGroup::freeVBSlot(getGeomIndex()/4,mParticleGeneration); - - mParticleGeneration = aParticleGeneration; - if (mGeomIndex != idx) { mGeomIndex = idx; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index b780322823..d3a561facc 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -207,11 +207,7 @@ public: BOOL verify(const U32* indices_array = NULL) const; void printDebugInfo() const; - // Pass another flag to mark this index as from LLVOPartGroup, in that case it needs to be freed with LLVOPartGroup::LLVOPartGroup - // void setGeomIndex(U16 idx); - void setGeomIndex(U16 idx, U32 aParticleGeneration = 0); - // - + void setGeomIndex(U16 idx); void setIndicesIndex(S32 idx); void setDrawInfo(LLDrawInfo* draw_info); @@ -363,9 +359,6 @@ public: lhs->getTexture() < rhs->getTexture(); } }; - -private: - U32 mParticleGeneration; }; #endif // LL_LLFACE_H diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 73f85c161d..f7eb7df46c 100755 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -284,36 +284,16 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) LLViewerCamera* camera = LLViewerCamera::getInstance(); LLViewerRegion *regionp = getRegion(); S32 end = (S32) mParticles.size(); - - // Instead of walking the current particles back to front, we first make a copy, then sort by adress and refill mParticles as needed. - mParticlesTemp.swap( mParticles ); - mParticles.erase( mParticles.begin(), mParticles.end() ); - std::sort( mParticlesTemp.begin(), mParticlesTemp.end() ); - - // for (S32 i = 0 ; i < (S32)mParticles.size(); ) - for (S32 i = 0 ; i < (S32)mParticlesTemp.size(); ++i ) - // + for (S32 i = 0 ; i < (S32)mParticles.size();) { - // LLVector3 a(0.f, 0.f, 0.f); // Unused - LLViewerPart* part = mParticlesTemp[i] ; + LLVector3 a(0.f, 0.f, 0.f); + LLViewerPart* part = mParticles[i] ; dt = lastdt + mSkippedTime - part->mSkipOffset; part->mSkipOffset = 0.f; // Update current time const F32 cur_time = part->mLastUpdateTime + dt; - - // Bail out as soon as possible to avoid all the complicated work down. - if( cur_time > part->mMaxAge || LLViewerPart::LL_PART_DEAD_MASK == part->mFlags ) - { - if (part->mVPCallback) - (*part->mVPCallback)(*part, dt); - - delete part ; - continue; - } - // - const F32 frac = cur_time / part->mMaxAge; // "Drift" the object based on the source object @@ -417,34 +397,26 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt) part->mLastUpdateTime = cur_time; - // We did that above // Kill dead particles (either flagged dead, or too old) - // if ((part->mLastUpdateTime > part->mMaxAge) || (LLViewerPart::LL_PART_DEAD_MASK == part->mFlags)) - // { - // mParticles[i] = mParticles.back() ; - // mParticles.pop_back() ; - // delete part ; - // } - // else - // + if ((part->mLastUpdateTime > part->mMaxAge) || (LLViewerPart::LL_PART_DEAD_MASK == part->mFlags)) + { + mParticles[i] = mParticles.back() ; + mParticles.pop_back() ; + delete part ; + } + else { F32 desired_size = calc_desired_size(camera, part->mPosAgent, part->mScale); if (!posInGroup(part->mPosAgent, desired_size)) { // Transfer particles between groups LLViewerPartSim::getInstance()->put(part) ; - - // No need for any transfer, just to not add to mParticles. - // mParticles[i] = mParticles.back() ; - // mParticles.pop_back() ; - // + mParticles[i] = mParticles.back() ; + mParticles.pop_back() ; } else { - // Keep current particle in this group. - // i++ ; - mParticles.push_back( part ); - // + i++ ; } } } @@ -920,76 +892,3 @@ void LLViewerPartSim::clearParticlesByOwnerID(const LLUUID& task_id) } } -// Object pool for LLViewerPart -U8 *sParts; -U8 *sPartsEnd; -U32 sFree[ LL_MAX_PARTICLE_COUNT/32 ]; -U32 sPartSize; - -S32 findFreeIndex() -{ - for( int i = 0; i < LL_MAX_PARTICLE_COUNT/32; ++i ) - { - if( sFree[i] ) - { - U32 val = sFree[i]; - U32 mask = 1; - int j(0); - for( j = 0; j < 32; ++j ) - { - if( mask & val ) - { - mask = ~mask; - break; - } - - mask <<= 1; - } - - sFree[ i ] = val & mask; - return i*32+j; - } - } - return -1; -} - -void* LLViewerPart::operator new(size_t size) -{ - if( !sParts ) - { - sPartSize = sizeof( LLViewerPart ); - sPartSize += 0xF; - sPartSize &= ~0xF; - sParts = reinterpret_cast( ll_aligned_malloc<16>( sPartSize * LL_MAX_PARTICLE_COUNT ) ); - for( int i = 0; i < LL_MAX_PARTICLE_COUNT/32; ++i ) - sFree[ i ] = 0xFFFFFFFF; - - sPartsEnd = sParts + sPartSize * LL_MAX_PARTICLE_COUNT; - } - - S32 i = findFreeIndex(); - if( i < 0 ) - return new char[ size ]; - - return reinterpret_cast< void* >( sParts + sPartSize*i ); -} - -void LLViewerPart::operator delete(void* ptr) -{ - if( ptr < sParts || ptr >= sPartsEnd ) - { - delete [] (char*)ptr; - return; - } - - U32 diff = static_cast( reinterpret_cast(ptr) - sParts ); - diff /= sPartSize; - - U32 i = (diff & ~0x0000001F) / 32; - U32 j = diff & 0x0000001F; - - U32 mask = 1 << j; - - sFree[ i ] |= mask; -} -// diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index 738d2f294a..40e8e1d45d 100755 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -81,10 +81,6 @@ public: static U32 sNextPartID; - // Object pool for LLViewerPart - void* operator new(size_t size); - void operator delete(void* ptr); - // }; @@ -112,7 +108,6 @@ public: typedef std::vector part_list_t; part_list_t mParticles; - part_list_t mParticlesTemp; // Temporary list for iteration in updateParticles const LLVector3 &getCenterAgent() const { return mCenterAgent; } S32 getCount() const { return (S32) mParticles.size(); } diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 1658811349..f90d827827 100755 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -51,9 +51,6 @@ extern U64MicrosecondsImplicit gFrameTime; LLPointer LLVOPartGroup::sVB = NULL; S32 LLVOPartGroup::sVBSlotCursor = 0; -#include "fsvopartgroup.h" // Fixing up/classifying Nicky D's fsvopartgroup code -FSVOPartGroup *LLVOPartGroup::fsvopartgroup = NULL; - void LLVOPartGroup::initClass() { @@ -62,16 +59,6 @@ void LLVOPartGroup::initClass() //static void LLVOPartGroup::restoreGL() { - if (fsvopartgroup == NULL) - { - fsvopartgroup = new FSVOPartGroup(); - } - // Fixing up/classifying Nicky D's fsvopartgroup code - fsvopartgroup->setIndexGeneration( fsvopartgroup->getIndexGeneration() + 2); - - for( int i = 0; i < LL_MAX_PARTICLE_COUNT/32; ++i ) - fsvopartgroup->setFreeIndex(i, 0xFFFFFFFF); - // //TODO: optimize out binormal mask here. Specular and normal coords as well. sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB); @@ -131,41 +118,12 @@ void LLVOPartGroup::destroyGL() //static S32 LLVOPartGroup::findAvailableVBSlot() { - // Fixing up/classifying Nicky D's fsvopartgroup code - /*if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT) + if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT) { //no more available slots return -1; } - return sVBSlotCursor++;*/ - - for( int i = 0; i < LL_MAX_PARTICLE_COUNT/32; ++i ) - { - if( fsvopartgroup->getFreeIndex(i) != 0 ) - { - U32 val = fsvopartgroup->getFreeIndex(i); - U32 mask = 1; - int j(0); - for( j = 0; j < 32; ++j ) - { - if( mask & val ) - { - mask = ~mask; - break; - } - - mask <<= 1; - } - - fsvopartgroup->setFreeIndex(i, val & mask); - fsvopartgroup->setTotalParticles(fsvopartgroup->getTotalParticles()+1); - - return i*32+j; - } - } - - return -1; - // + return sVBSlotCursor++; } bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) @@ -184,9 +142,7 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) } //static -// Fixing up/classifying Nicky D's fsvopartgroup code -// void LLVOPartGroup::freeVBSlot(S32 idx) -void LLVOPartGroup::freeVBSlot(S32 idx, U32 generation ) +void LLVOPartGroup::freeVBSlot(S32 idx) { /*llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); //llassert(sVBSlotCursor > sVBSlotFree); @@ -197,23 +153,6 @@ void LLVOPartGroup::freeVBSlot(S32 idx, U32 generation ) sVBSlotCursor--; *sVBSlotCursor = idx; }*/ - - if( idx < 0 || idx >= LL_MAX_PARTICLE_COUNT ) - return; - - // Fixing up/classifying Nicky D's fsvopartgroup code - fsvopartgroup->setTotalParticles(fsvopartgroup->getTotalParticles()-1); - - if( fsvopartgroup->getIndexGeneration() != generation ) - return; - - U32 i = (idx & ~0x0000001F) / 32; - U32 j = idx & 0x0000001F; - - U32 mask = 1 << j; - - fsvopartgroup->setFreeIndex(i, fsvopartgroup->getFreeIndex(i) | mask); - // } LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -223,10 +162,6 @@ LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegi setNumTEs(1); setTETexture(0, LLUUID::null); mbCanSelect = FALSE; // users can't select particle systems - if (fsvopartgroup == NULL) - { - fsvopartgroup = new FSVOPartGroup(); - } } @@ -924,14 +859,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; - // Free all vb slots. Then try to allocate an adjacent block of slots for all faces - for( std::vector::iterator itr = mFaceList.begin(); itr != mFaceList.end(); ++itr ) - (*itr)->setGeomIndex( 0 ); - - S32 idxStart, idxEnd; - bool bValidRange = LLVOPartGroup::getFsvopartgroup()->findAvailableVBSlots( idxStart, idxEnd, mFaceList.size() ); - // - for (std::vector::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) { LLFace* facep = *i; @@ -939,26 +866,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) //if (!facep->isState(LLFace::PARTICLE)) { //set the indices of this face - - // Can we use a index from our preallocated list? - // S32 idx = LLVOPartGroup::findAvailableVBSlot(); - S32 idx(-1); - if( bValidRange ) - { - if( idxStart < idxEnd ) - idx = idxStart++; - } - else - idx = LLVOPartGroup::findAvailableVBSlot(); - // - + S32 idx = LLVOPartGroup::findAvailableVBSlot(); if (idx >= 0) { - // Face needs to release the index when it gets destroyed. - // facep->setGeomIndex(idx*4); - facep->setGeomIndex(idx*4, LLVOPartGroup::getFsvopartgroup()->getIndexGeneration()); - // - + facep->setGeomIndex(idx*4); facep->setIndicesIndex(idx*6); facep->setVertexBuffer(LLVOPartGroup::sVB); facep->setPoolType(LLDrawPool::POOL_ALPHA); diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index eb98902444..2ef8b1c848 100755 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -36,8 +36,6 @@ class LLViewerPartGroup; -class FSVOPartGroup; // Fixing up/classifying Nicky D's fsvopartgroup code - class LLVOPartGroup : public LLAlphaObject { public: @@ -50,9 +48,7 @@ public: static void restoreGL(); static void destroyGL(); static S32 findAvailableVBSlot(); - - // static void freeVBSlot(S32 idx); - static void freeVBSlot(S32 idx, U32 generation); + static void freeVBSlot(S32 idx); enum { @@ -108,8 +104,6 @@ public: void setViewerPartGroup(LLViewerPartGroup *part_groupp) { mViewerPartGroupp = part_groupp; } LLViewerPartGroup* getViewerPartGroup() { return mViewerPartGroupp; } - static FSVOPartGroup* getFsvopartgroup() {return fsvopartgroup;}// Fixing up/classifying Nicky D's fsvopartgroup code - protected: ~LLVOPartGroup(); @@ -117,11 +111,6 @@ protected: virtual LLVector3 getCameraPosition() const; -// Fixing up/classifying Nicky D's fsvopartgroup code -private: - static FSVOPartGroup* fsvopartgroup; -// - };