davep avatar davep committed c03827e

reapply 448b02f5b56f: MAINT-1147 Fix for frame stall on region crossing.

Comments (0)

Files changed (21)

indra/llrender/llimagegl.cpp

 
 //----------------------------------------------------------------------------
 
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_STATS("Image Stats");
 // static
 void LLImageGL::updateStats(F32 current_time)
 {
+	LLFastTimer t(FTM_IMAGE_UPDATE_STATS);
 	sLastFrameTime = current_time;
 	sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
 	sCurBoundTextureMemory = 0;

indra/llrender/llrendertarget.cpp

 	release();
 }
 
+void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
+{ 
+	//for accounting, get the number of pixels added/subtracted
+	S32 pix_diff = (resx*resy)-(mResX*mResY);
+		
+	mResX = resx;
+	mResY = resy;
+
+	for (U32 i = 0; i < mTex.size(); ++i)
+	{ //resize color attachments
+		gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
+		LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
+		sBytesAllocated += pix_diff*4;
+	}
+
+	if (mDepth)
+	{ //resize depth attachment
+		if (mStencil)
+		{
+			//use render buffers where stencil buffers are in play
+			glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
+			glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);
+			glBindRenderbuffer(GL_RENDERBUFFER, 0);
+		}
+		else
+		{
+			gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
+			U32 internal_type = LLTexUnit::getInternalType(mUsage);
+			LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
+		}
+
+		sBytesAllocated += pix_diff*4;
+	}
+}
+	
+
 bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
 {
 	stop_glerror();

indra/llrender/llrendertarget.h

 
 */
 
-class LLMultisampleBuffer;
-
 class LLRenderTarget
 {
 public:
 	//multiple calls will release previously allocated resources
 	bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
 
+	//resize existing attachments to use new resolution and color format
+	// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
+	// DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
+	// DO use for render targets that resize often and aren't likely to ruin someone's day if they break
+	void resize(U32 resx, U32 resy, U32 color_fmt);
+
 	//add color buffer attachment
 	//limit of 4 color attachments per render target
 	bool addColorAttachment(U32 color_fmt);

indra/newview/lldrawable.cpp

 
 static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
 
+extern bool gShiftFrame;
+
 
 ////////////////////////
 //
 		return;
 	}
 
+	if (gShiftFrame)
+	{
+		return;
+	}
+
 	//switch LOD with the spatial group to avoid artifacts
 	//LLSpatialGroup* sg = getSpatialGroup();
 
 		mXform.setPosition(mVObjp->getPositionAgent());
 	}
 
-	mXform.setRotation(mVObjp->getRotation());
-	mXform.setScale(1,1,1);
 	mXform.updateMatrix();
 
 	if (isStatic())
 	{
 		LLVOVolume* volume = getVOVolume();
-		if (!volume)
+
+		bool rebuild = (!volume && 
+						getRenderType() != LLPipeline::RENDER_TYPE_TREE &&
+						getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN &&
+						getRenderType() != LLPipeline::RENDER_TYPE_SKY &&
+						getRenderType() != LLPipeline::RENDER_TYPE_GROUND);
+
+		if (rebuild)
 		{
 			gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
 		}
 				facep->mExtents[0].add(shift_vector);
 				facep->mExtents[1].add(shift_vector);
 			
-				if (!volume && facep->hasGeometry())
+				if (rebuild && facep->hasGeometry())
 				{
 					facep->clearVertexBuffer();
 				}
 		markDead();
 		return;
 	}
+	
+	if (gShiftFrame)
+	{
+		return;
+	}
 
 	if (mDrawable->getVObj())
 	{

indra/newview/lldrawpool.cpp

 {
 }
 
-// static
-S32 LLFacePool::drawLoop(face_array_t& face_list)
-{
-	S32 res = 0;
-	if (!face_list.empty())
-	{
-		for (std::vector<LLFace*>::iterator iter = face_list.begin();
-			 iter != face_list.end(); iter++)
-		{
-			LLFace *facep = *iter;
-			res += facep->renderIndexed();
-		}
-	}
-	return res;
-}
-
-// static
-S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
-{
-	S32 res = 0;
-	if (!face_list.empty())
-	{
-		for (std::vector<LLFace*>::iterator iter = face_list.begin();
-			 iter != face_list.end(); iter++)
-		{
-			LLFace *facep = *iter;
-			gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE) ;
-			gGL.getTexUnit(0)->activate();
-			res += facep->renderIndexed();
-		}
-	}
-	return res;
-}
-
-void LLFacePool::drawLoop()
-{
-	if (!mDrawFace.empty())
-	{
-		drawLoop(mDrawFace);
-	}
-}
-
 void LLFacePool::enqueue(LLFace* facep)
 {
 	mDrawFace.push_back(facep);

indra/newview/lldrawpool.h

 
 	void buildEdges();
 
-	static S32 drawLoop(face_array_t& face_list);
-	static S32 drawLoopSetTex(face_array_t& face_list, S32 stage);
-	void drawLoop();
-
 	void addFaceReference(LLFace *facep);
 	void removeFaceReference(LLFace *facep);
 

indra/newview/lldrawpoolterrain.cpp

 	//glCullFace(GL_BACK);
 }
 
+
+void LLDrawPoolTerrain::drawLoop()
+{
+	if (!mDrawFace.empty())
+	{
+		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+			 iter != mDrawFace.end(); iter++)
+		{
+			LLFace *facep = *iter;
+
+			LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix);
+
+			if (model_matrix != gGLLastMatrix)
+			{
+				gGLLastMatrix = model_matrix;
+				gGL.loadMatrix(gGLModelView);
+				if (model_matrix)
+				{
+					gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
+				}
+				gPipeline.mMatrixOpCount++;
+			}
+
+			facep->renderIndexed();
+		}
+	}
+}
+
 void LLDrawPoolTerrain::renderFullShader()
 {
 	// Hack! Get the region that this draw pool is rendering from!

indra/newview/lldrawpoolterrain.h

 	void renderFull2TU();
 	void renderFull4TU();
 	void renderFullShader();
+	void drawLoop();
 };
 
 #endif // LL_LLDRAWPOOLSIMPLE_H

indra/newview/lldrawpooltree.cpp

 #include "llviewershadermgr.h"
 #include "llrender.h"
 #include "llviewercontrol.h"
+#include "llviewerregion.h"
 
 S32 LLDrawPoolTree::sDiffTex = 0;
 static LLGLSLShader* shader = NULL;
 	{
 		LLFace *face = *iter;
 		LLVertexBuffer* buff = face->getVertexBuffer();
+
 		if(buff)
 		{
+			LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix);
+
+			if (model_matrix != gGLLastMatrix)
+			{
+				gGLLastMatrix = model_matrix;
+				gGL.loadMatrix(gGLModelView);
+				if (model_matrix)
+				{
+					gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
+				}
+				gPipeline.mMatrixOpCount++;
+			}
+
 			buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
 			buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); 
 			gPipeline.addTrianglesDrawn(buff->getNumIndices());

indra/newview/llspatialpartition.cpp

 #define assert_states_valid(x)
 #endif
 
+extern bool gShiftFrame;
 
 static U32 sZombieGroups = 0;
 U32 LLSpatialGroup::sNodeCount = 0;
 	mObjectExtents[0].add(offset);
 	mObjectExtents[1].add(offset);
 
-	if (!mSpatialPartition->mRenderByGroup)
+	if (!mSpatialPartition->mRenderByGroup && 
+		mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE &&
+		mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
+		mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE)
 	{
 		setState(GEOM_DIRTY);
 		gPipeline.markRebuild(this, TRUE);
 		return;
 	}
 
+	if (gShiftFrame)
+	{
+		return;
+	}
+
 #if !LL_RELEASE_FOR_DOWNLOAD
 	if (isState(LLSpatialGroup::OBJECT_DIRTY))
 	{

indra/newview/llsurface.cpp

 #include "lldrawable.h"
 
 extern LLPipeline gPipeline;
+extern bool gShiftFrame;
 
 LLColor4U MAX_WATER_COLOR(0, 48, 96, 240);
 
 
 void LLSurface::updatePatchVisibilities(LLAgent &agent) 
 {
+	if (gShiftFrame)
+	{
+		return;
+	}
+
 	LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());
 
 	LLSurfacePatch *patchp;

indra/newview/llsurfacepatch.cpp

 #include "lldrawpool.h"
 #include "noise.h"
 
+extern bool gShiftFrame;
 extern U64 gFrameTime;
 extern LLPipeline gPipeline;
 
 	pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid();
 	pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid();
 	pos_agent.mV[VZ]  = *(mDataZ + point_offset);
-	*vertex     = pos_agent;
+	*vertex     = pos_agent-mVObjp->getRegion()->getOriginAgent();
 
 	LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent();
 	LLVector3 tex_pos = rel_pos * (1.f/surface_stride);
 {
 	if (LLPipeline::sDynamicLOD)
 	{
-		LLVector3 dv = pos_region;
-		dv -= mCenterRegion;
-		mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
-			llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
+		if (!gShiftFrame)
+		{
+			LLVector3 dv = pos_region;
+			dv -= mCenterRegion;
+			mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
+				llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
+		}
 	}
 	else
 	{

indra/newview/llviewerdisplay.cpp

 #include "llpostprocess.h"
 
 extern LLPointer<LLViewerTexture> gStartTexture;
+extern bool gShiftFrame;
 
 LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;
 
 	glClear(GL_DEPTH_BUFFER_BIT);
 }
 
+static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Update Camera");
+
 void display_update_camera()
 {
+	LLFastTimer t(FTM_UPDATE_CAMERA);
 	LLMemType mt_uc(LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA);
 	// TODO: cut draw distance down if customizing avatar?
 	// TODO: cut draw distance on per-parcel basis?
 static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Bump");
 static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List");
 static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete");
+static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window");
+static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update");
+static LLFastTimer::DeclareTimer FTM_DISPLAY_UPDATE_GEOM("Update Geom");
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UNBIND("Texture Unbind");
+static LLFastTimer::DeclareTimer FTM_TELEPORT_DISPLAY("Teleport Display");
 
 // Paint the display!
 void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 	if (gWindowResized)
 	{ //skip render on frames where window has been resized
+		LLFastTimer t(FTM_RESIZE_WINDOW);
 		gGL.flush();
 		glClear(GL_COLOR_BUFFER_BIT);
 		gViewerWindow->getWindow()->swapBuffers();
 
 	if (gTeleportDisplay)
 	{
+		LLFastTimer t(FTM_TELEPORT_DISPLAY);
 		LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
 		const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
 
 				
 		// *TODO: merge these two methods
 		{
+			LLFastTimer t(FTM_HUD_UPDATE);
 			LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD);
 			LLHUDManager::getInstance()->updateEffects();
 			LLHUDObject::updateAll();
 		}
 
 		{
+			LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM);
 			LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM);
 			const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
 			gPipeline.createObjects(max_geom_update_time);
 		}
 
 		gPipeline.updateGL();
+		
 		stop_glerror();
 
 		S32 water_clip = 0;
 			stop_glerror();
 		}
 
-		for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
-		{ //dummy cleanup of any currently bound textures
-			if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
-			{
-				gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
-				gGL.getTexUnit(i)->disable();
+		{
+			LLFastTimer t(FTM_TEXTURE_UNBIND);
+			for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
+			{ //dummy cleanup of any currently bound textures
+				if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
+				{
+					gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
+					gGL.getTexUnit(i)->disable();
+				}
 			}
 		}
+
 		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		
 		
 		if (to_texture)
 	display_stats();
 				
 	LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
+
+	gShiftFrame = false;
 }
 
 void render_hud_attachments()

indra/newview/llviewermessage.cpp

 static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL	= 10.0f; // seconds
 
 extern BOOL gDebugClicks;
+extern bool gShiftFrame;
 
 // function prototypes
 bool check_offer_throttle(const std::string& from_name, bool check_only);
 
 void process_agent_movement_complete(LLMessageSystem* msg, void**)
 {
+	gShiftFrame = true;
 	gAgentMovementCompleted = true;
 
 	LLUUID agent_id;

indra/newview/llviewerobjectlist.cpp

 		if (active)
 		{
 			//llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl;
-			llassert(objectp->getListIndex() == -1);
+			S32 idx = objectp->getListIndex();
+			if (idx <= -1)
+			{
+				mActiveObjects.push_back(objectp);
+				objectp->setListIndex(mActiveObjects.size()-1);
+				objectp->setOnActiveList(TRUE);
+			}
+			else
+			{
+				llassert(idx < mActiveObjects.size());
+				llassert(mActiveObjects[idx] == objectp);
 
-			mActiveObjects.push_back(objectp);
-			objectp->setListIndex(mActiveObjects.size()-1);
-
-			objectp->setOnActiveList(TRUE);
+				if (idx >= mActiveObjects.size() ||
+					mActiveObjects[idx] != objectp)
+				{
+					llwarns << "Invalid object list index detected!" << llendl;
+				}
+			}
 		}
 		else
 		{
 	mPendingPhysicsFlags.erase(object_id);
 }
 
+static LLFastTimer::DeclareTimer FTM_SHIFT_OBJECTS("Shift Objects");
+static LLFastTimer::DeclareTimer FTM_PIPELINE_SHIFT("Pipeline Shift");
+static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift");
+
 void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
 {
 	// This is called when we shift our origin when we cross region boundaries...
 		return;
 	}
 
+	LLFastTimer t(FTM_SHIFT_OBJECTS);
+
 	LLViewerObject *objectp;
 	for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
 	{
 		}
 	}
 
-	gPipeline.shiftObjects(offset);
-	LLWorld::getInstance()->shiftRegions(offset);
+	{
+		LLFastTimer t(FTM_PIPELINE_SHIFT);
+		gPipeline.shiftObjects(offset);
+	}
+
+	{
+		LLFastTimer t(FTM_REGION_SHIFT);
+		LLWorld::getInstance()->shiftRegions(offset);
+	}
 }
 
 void LLViewerObjectList::repartitionObjects()

indra/newview/llviewerregion.cpp

 		// all of our terrain stuff, by
 		if (compp->getParamsReady())
 		{
-			getLand().dirtyAllPatches();
+			//this line creates frame stalls on region crossing and removing it appears to have no effect
+			//getLand().dirtyAllPatches();
 		}
 		else
 		{

indra/newview/llviewerwindow.cpp

 	mResDirty = true;
 }
 
+static LLFastTimer::DeclareTimer FTM_WINDOW_CHECK_SETTINGS("Window Settings");
+
 void LLViewerWindow::checkSettings()
 {
+	LLFastTimer t(FTM_WINDOW_CHECK_SETTINGS);
 	if (mStatesDirty)
 	{
 		gGL.refreshState();

indra/newview/llvoavatar.cpp

 	const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector);
 	mLastAnimExtents[0] += shift;
 	mLastAnimExtents[1] += shift;
-	mNeedsImpostorUpdate = TRUE;
-	mNeedsAnimUpdate = TRUE;
 }
 
 void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
 
 	LLJoint* jointp = NULL;
 
-	if (iter == mJointMap.end())
+	if (iter == mJointMap.end() || iter->second == NULL)
 	{ //search for joint and cache found joint in lookup table
-		LLJoint* jointp = mRoot.findJoint(name);
+		jointp = mRoot.findJoint(name);
 		mJointMap[name] = jointp;
 	}
 	else

indra/newview/llvotree.cpp

 		// *TODO: I don't know what's so special about trees
 		// that they don't get REBUILD_POSITION automatically
 		// at a higher level.
-		const LLVector3 &this_position = getPositionAgent();
+		const LLVector3 &this_position = getPositionRegion();
 		if (this_position != mLastPosition)
 		{
 			gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
 	LLMatrix4 matrix;
 	
 	// Translate to tree base  HACK - adjustment in Z plants tree underground
-	const LLVector3 &pos_agent = getPositionAgent();
+	const LLVector3 &pos_region = getPositionRegion();
 	//gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
 	LLMatrix4 trans_mat;
-	trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
+	trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f);
 	trans_mat *= matrix;
 	
 	// Rotate to tree position and bend for current trunk/wind

indra/newview/llworld.cpp

 		if (did_one && max_time <= 0.f)
 			break;
 		max_time = llmin(max_time, max_update_time*.1f);
-		did_one |= regionp->idleUpdate(max_update_time);
+		if (regionp->idleUpdate(max_update_time))
+		{
+			did_one = TRUE;
+		}
 	}
 }
 

indra/newview/pipeline.cpp

 //#define DEBUG_INDICES
 #endif
 
+bool gShiftFrame = false;
+
 //cached settings
 BOOL LLPipeline::RenderAvatarVP;
 BOOL LLPipeline::VertexShaderEnable;
 LLPipeline gPipeline;
 const LLMatrix4* gGLLastMatrix = NULL;
 
-LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry");
+LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Render Geometry");
 LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass");
 LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible");
 LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion");
 LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
 LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
 LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
+LLFastTimer::DeclareTimer FTM_PIPELINE_CREATE("Pipeline Create");
 LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool");
 LLFastTimer::DeclareTimer FTM_POOLS("Pools");
+LLFastTimer::DeclareTimer FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)");
+LLFastTimer::DeclareTimer FTM_DEFERRED_POOLS("Pools (Deferred)");
+LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)");
+LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLS("Pools (Post)");
 LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO");
 LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State");
 LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline");
 
 void LLPipeline::createObjects(F32 max_dtime)
 {
-	LLFastTimer ftm(FTM_GEO_UPDATE);
+	LLFastTimer ftm(FTM_PIPELINE_CREATE);
 	LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS);
 
 	LLTimer update_timer;
 
 static LLFastTimer::DeclareTimer FTM_SEED_VBO_POOLS("Seed VBO Pool");
 
+static LLFastTimer::DeclareTimer FTM_UPDATE_GL("Update GL");
+
 void LLPipeline::updateGL()
 {
-	while (!LLGLUpdate::sGLQ.empty())
-	{
-		LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
-		glu->updateGL();
-		glu->mInQ = FALSE;
-		LLGLUpdate::sGLQ.pop_front();
+	{
+		LLFastTimer t(FTM_UPDATE_GL);
+		while (!LLGLUpdate::sGLQ.empty())
+		{
+			LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
+			glu->updateGL();
+			glu->mInQ = FALSE;
+			LLGLUpdate::sGLQ.pop_front();
+		}
 	}
 
 	{ //seed VBO Pools
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups");
+
 void LLPipeline::rebuildPriorityGroups()
 {
+	LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS);
 	LLTimer update_timer;
 	LLMemType mt(LLMemType::MTYPE_PIPELINE);
-	
 	assertInitialized();
 
 	gMeshRepo.notifyLoadedMeshes();
 	mGroupQ1Locked = false;
 
 }
-		
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_GROUPS("Rebuild Groups");
+
 void LLPipeline::rebuildGroups()
 {
 	if (mGroupQ2.empty())
 		return;
 	}
 
+	LLFastTimer t(FTM_REBUILD_GROUPS);
 	mGroupQ2Locked = true;
 	// Iterate through some drawables on the non-priority build queue
 	S32 size = (S32) mGroupQ2.size();
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_SHIFT_DRAWABLE("Shift Drawable");
+static LLFastTimer::DeclareTimer FTM_SHIFT_OCTREE("Shift Octree");
+static LLFastTimer::DeclareTimer FTM_SHIFT_HUD("Shift HUD");
+
 void LLPipeline::shiftObjects(const LLVector3 &offset)
 {
 	LLMemType mt(LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS);
 	LLVector4a offseta;
 	offseta.load3(offset.mV);
 
-	for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
-		 iter != mShiftList.end(); iter++)
-	{
-		LLDrawable *drawablep = *iter;
-		if (drawablep->isDead())
-		{
-			continue;
-		}	
-		drawablep->shiftPos(offseta);	
-		drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
-	}
-	mShiftList.resize(0);
-
-	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
-			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
-	{
-		LLViewerRegion* region = *iter;
-		for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
-		{
-			LLSpatialPartition* part = region->getSpatialPartition(i);
-			if (part)
-			{
-				part->shift(offseta);
-			}
-		}
-	}
-
-	LLHUDText::shiftAll(offset);
-	LLHUDNameTag::shiftAll(offset);
+	{
+		LLFastTimer t(FTM_SHIFT_DRAWABLE);
+
+		for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
+			 iter != mShiftList.end(); iter++)
+		{
+			LLDrawable *drawablep = *iter;
+			if (drawablep->isDead())
+			{
+				continue;
+			}	
+			drawablep->shiftPos(offseta);	
+			drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
+		}
+		mShiftList.resize(0);
+	}
+
+	
+	{
+		LLFastTimer t(FTM_SHIFT_OCTREE);
+		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
+				iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+		{
+			LLViewerRegion* region = *iter;
+			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+			{
+				LLSpatialPartition* part = region->getSpatialPartition(i);
+				if (part)
+				{
+					part->shift(offseta);
+				}
+			}
+		}
+	}
+
+	{
+		LLFastTimer t(FTM_SHIFT_HUD);
+		LLHUDText::shiftAll(offset);
+		LLHUDNameTag::shiftAll(offset);
+	}
 	display_update_camera();
 }
 
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_PROCESS_PARTITIONQ("PartitionQ");
 void LLPipeline::processPartitionQ()
 {
+	LLFastTimer t(FTM_PROCESS_PARTITIONQ);
 	for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter)
 	{
 		LLDrawable* drawable = *iter;
 	LLMemType mt_rgd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED);
 	LLFastTimer t(FTM_RENDER_GEOMETRY);
 
-	LLFastTimer t2(FTM_POOLS);
+	LLFastTimer t2(FTM_DEFERRED_POOLS);
 
 	LLGLEnable cull(GL_CULL_FACE);
 
 		pool_set_t::iterator iter2 = iter1;
 		if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
 		{
-			LLFastTimer t(FTM_POOLRENDER);
+			LLFastTimer t(FTM_DEFERRED_POOLRENDER);
 
 			gGLLastMatrix = NULL;
 			gGL.loadMatrix(gGLModelView);
 void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
 {
 	LLMemType mt_rgpd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF);
-	LLFastTimer t(FTM_POOLS);
+	LLFastTimer t(FTM_POST_DEFERRED_POOLS);
 	U32 cur_type = 0;
 
 	LLGLEnable cull(GL_CULL_FACE);
 		pool_set_t::iterator iter2 = iter1;
 		if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
 		{
-			LLFastTimer t(FTM_POOLRENDER);
+			LLFastTimer t(FTM_POST_DEFERRED_POOLRENDER);
 
 			gGLLastMatrix = NULL;
 			gGL.loadMatrix(gGLModelView);
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools");
+
 void LLPipeline::rebuildPools()
 {
+	LLFastTimer t(FTM_REBUILD_POOLS);
 	LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS);
 
 	assertInitialized();
 	mResetVertexBuffers = true;
 }
 
+static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB");
+
 void LLPipeline::doResetVertexBuffers()
 {
 	if (!mResetVertexBuffers)
 	{
 		return;
 	}
-	
+
+	LLFastTimer t(FTM_RESET_VB);
 	mResetVertexBuffers = false;
 
 	mCubeVB = NULL;
 }
 
 
+static LLFastTimer::DeclareTimer FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
+
 void LLPipeline::generateSunShadow(LLCamera& camera)
 {
 	if (!sRenderDeferred || RenderShadowDetail <= 0)
 		return;
 	}
 
+	LLFastTimer t(FTM_GEN_SUN_SHADOW);
+
 	BOOL skip_avatar_update = FALSE;
 	if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
 	{
 	}
 }
 
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_SETUP("Impostor Setup");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_BACKGROUND("Impostor Background");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_ALLOCATE("Impostor Allocate");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_RESIZE("Impostor Resize");
+
 void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 {
 	LLMemType mt_gi(LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR);
 	sImpostorRender = TRUE;
 
 	LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
-	markVisible(avatar->mDrawable, *viewer_camera);
-	LLVOAvatar::sUseImpostors = FALSE;
-
-	LLVOAvatar::attachment_map_t::iterator iter;
-	for (iter = avatar->mAttachmentPoints.begin();
-		iter != avatar->mAttachmentPoints.end();
-		++iter)
-	{
-		LLViewerJointAttachment *attachment = iter->second;
-		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-			 attachment_iter != attachment->mAttachedObjects.end();
-			 ++attachment_iter)
-		{
-			if (LLViewerObject* attached_object = (*attachment_iter))
-			{
-				markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+
+	{
+		LLFastTimer t(FTM_IMPOSTOR_MARK_VISIBLE);
+		markVisible(avatar->mDrawable, *viewer_camera);
+		LLVOAvatar::sUseImpostors = FALSE;
+
+		LLVOAvatar::attachment_map_t::iterator iter;
+		for (iter = avatar->mAttachmentPoints.begin();
+			iter != avatar->mAttachmentPoints.end();
+			++iter)
+		{
+			LLViewerJointAttachment *attachment = iter->second;
+			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+				 attachment_iter != attachment->mAttachedObjects.end();
+				 ++attachment_iter)
+			{
+				if (LLViewerObject* attached_object = (*attachment_iter))
+				{
+					markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+				}
 			}
 		}
 	}
 
 	stateSort(*LLViewerCamera::getInstance(), result);
 	
-	const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
-	LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
-
 	LLCamera camera = *viewer_camera;
-
-	camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
-	
 	LLVector2 tdim;
-
-
-	LLVector4a half_height;
-	half_height.setSub(ext[1], ext[0]);
-	half_height.mul(0.5f);
-
-	LLVector4a left;
-	left.load3(camera.getLeftAxis().mV);
-	left.mul(left);
-	left.normalize3fast();
-
-	LLVector4a up;
-	up.load3(camera.getUpAxis().mV);
-	up.mul(up);
-	up.normalize3fast();
-
-	tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
-	tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
-
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.pushMatrix();
-	
-	F32 distance = (pos-camera.getOrigin()).length();
-	F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
-	F32 aspect = tdim.mV[0]/tdim.mV[1];
-	glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
-	glh_set_current_projection(persp);
-	gGL.loadMatrix(persp.m);
-
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.pushMatrix();
-	glh::matrix4f mat;
-	camera.getOpenGLTransform(mat.m);
-
-	mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
-
-	gGL.loadMatrix(mat.m);
-	glh_set_current_modelview(mat);
-
-	glClearColor(0.0f,0.0f,0.0f,0.0f);
-	gGL.setColorMask(true, true);
-	
-	// get the number of pixels per angle
-	F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
-
-	//get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
-	U32 resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
-	U32 resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
-
-	if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() ||
-		resY != avatar->mImpostor.getHeight())
-	{
-		avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
-		
-		if (LLPipeline::sRenderDeferred)
-		{
-			addDeferredAttachments(avatar->mImpostor);
-		}
-		
-		gGL.getTexUnit(0)->bind(&avatar->mImpostor);
-		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	}
-
-	avatar->mImpostor.bindTarget();
+	U32 resY = 0;
+	U32 resX = 0;
+
+	{
+		LLFastTimer t(FTM_IMPOSTOR_SETUP);
+		const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
+		LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
+
+		camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
+	
+		LLVector4a half_height;
+		half_height.setSub(ext[1], ext[0]);
+		half_height.mul(0.5f);
+
+		LLVector4a left;
+		left.load3(camera.getLeftAxis().mV);
+		left.mul(left);
+		left.normalize3fast();
+
+		LLVector4a up;
+		up.load3(camera.getUpAxis().mV);
+		up.mul(up);
+		up.normalize3fast();
+
+		tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
+		tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
+
+		gGL.matrixMode(LLRender::MM_PROJECTION);
+		gGL.pushMatrix();
+	
+		F32 distance = (pos-camera.getOrigin()).length();
+		F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
+		F32 aspect = tdim.mV[0]/tdim.mV[1];
+		glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
+		glh_set_current_projection(persp);
+		gGL.loadMatrix(persp.m);
+
+		gGL.matrixMode(LLRender::MM_MODELVIEW);
+		gGL.pushMatrix();
+		glh::matrix4f mat;
+		camera.getOpenGLTransform(mat.m);
+
+		mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
+
+		gGL.loadMatrix(mat.m);
+		glh_set_current_modelview(mat);
+
+		glClearColor(0.0f,0.0f,0.0f,0.0f);
+		gGL.setColorMask(true, true);
+	
+		// get the number of pixels per angle
+		F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
+
+		//get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
+		resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
+		resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
+
+		if (!avatar->mImpostor.isComplete())
+		{
+			LLFastTimer t(FTM_IMPOSTOR_ALLOCATE);
+			avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+
+			if (LLPipeline::sRenderDeferred)
+			{
+				addDeferredAttachments(avatar->mImpostor);
+			}
+		
+			gGL.getTexUnit(0)->bind(&avatar->mImpostor);
+			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		}
+		else if(resX != avatar->mImpostor.getWidth() ||
+			resY != avatar->mImpostor.getHeight())
+		{
+			LLFastTimer t(FTM_IMPOSTOR_RESIZE);
+			avatar->mImpostor.resize(resX,resY,GL_RGBA);
+		}
+
+		avatar->mImpostor.bindTarget();
+	}
 
 	if (LLPipeline::sRenderDeferred)
 	{
 	}
 	
 	{ //create alpha mask based on depth buffer (grey out if muted)
+		LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
 		if (LLPipeline::sRenderDeferred)
 		{
 			GLuint buff = GL_COLOR_ATTACHMENT0;
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.