davep avatar davep committed d4c44c3

reapply fde2ac0276e2: MAINT-646 Get rid of a hotspot in LLViewerObjectList::update, fix for error in llpolymorph

Comments (0)

Files changed (5)

indra/newview/llpolymorph.cpp

 					LLVector4a* clothing_weight = &clothing_weights[out_vert];
 					LLVector4a t;
 					t.setSub(*clothing_weight, clothing_offset);
-					clothing_weight->setSelectWithMask(clothing_mask, clothing_offset, *clothing_weight);
+					clothing_weight->setSelectWithMask(clothing_mask, t, *clothing_weight);
 				}
 			}
 		}

indra/newview/llviewerobject.cpp

 	mID(id),
 	mLocalID(0),
 	mTotalCRC(0),
+	mListIndex(-1),
 	mTEImages(NULL),
 	mGLName(0),
 	mbCanSelect(TRUE),
 // virtual
 void LLViewerObject::updateDrawable(BOOL force_damped)
 {
-	if (mDrawable.notNull() && 
-		!mDrawable->isState(LLDrawable::ON_MOVE_LIST) &&
-		isChanged(MOVED))
+	if (!isChanged(MOVED))
+	{ //most common case, having an empty if case here makes for better branch prediction
+	}
+	else if (mDrawable.notNull() && 
+		!mDrawable->isState(LLDrawable::ON_MOVE_LIST))
 	{
 		BOOL damped_motion = 
 			!isChanged(SHIFTED) &&										// not shifted between regions this frame and...

indra/newview/llviewerobject.h

 	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; }
 	// Last total CRC received from sim, used for caching
 	U32				mTotalCRC;
 
+	// index into LLViewerObjectList::mActiveObjects or -1 if not in list
+	S32				mListIndex;
+
 	LLPointer<LLViewerTexture> *mTEImages;
 
 	// Selection, picking and rendering variables

indra/newview/llviewerobjectlist.cpp

 	LLViewerObject *objectp = NULL;	
 	
 	// Make a copy of the list in case something in idleUpdate() messes with it
-	std::vector<LLViewerObject*> idle_list;
-	
+	static std::vector<LLViewerObject*> 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<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
+		
+ 		for (std::vector<LLPointer<LLViewerObject> >::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
 		}
 	}
 
+	std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count;
+
 	if (gSavedSettings.getBOOL("FreezeTime"))
 	{
+		
 		for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin();
-			iter != idle_list.end(); iter++)
+			iter != idle_end; iter++)
 		{
 			objectp = *iter;
 			if (objectp->isAvatar())
 	else
 	{
 		for (std::vector<LLViewerObject*>::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))
+			{
+				num_active_objects++;				
+			}
+			else
 			{
 				//  If Idle Update returns false, kill object!
 				kill_list.push_back(objectp);
 			}
-			else
-			{
-				num_active_objects++;
-			}
 		}
 		for (std::vector<LLViewerObject*>::iterator kill_iter = kill_list.begin();
 			kill_iter != kill_list.end(); kill_iter++)
 	{
 		//llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl;
 		objectp->setOnActiveList(FALSE);
-		mActiveObjects.erase(objectp);
+		removeFromActiveList(objectp);
 	}
 
 	if (objectp->isOnMap())
 	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);
 		if (active)
 		{
 			//llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl;
-			mActiveObjects.insert(objectp);
+			llassert(objectp->getListIndex() == -1);
+
+			mActiveObjects.push_back(objectp);
+			objectp->setListIndex(mActiveObjects.size()-1);
+
 			objectp->setOnActiveList(TRUE);
 		}
 		else
 		{
 			//llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl;
-			mActiveObjects.erase(objectp);
+			removeFromActiveList(objectp);
 			objectp->setOnActiveList(FALSE);
 		}
 	}

indra/newview/llviewerobjectlist.h

 
 	void dirtyAllObjectInventory();
 
+	void removeFromActiveList(LLViewerObject* objectp);
 	void updateActive(LLViewerObject *objectp);
+	
 	void updateAvatarVisibility();
 
 	// Selection related stuff
 	typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;
 
 	vobj_list_t mObjects;
-	std::set<LLPointer<LLViewerObject> > mActiveObjects;
+	std::vector<LLPointer<LLViewerObject> > mActiveObjects;
 
 	vobj_list_t mMapObjects;
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.