diff options
| author | simon@Simon-PC.lindenlab.com <simon@Simon-PC.lindenlab.com> | 2012-06-14 15:11:59 -0700 | 
|---|---|---|
| committer | simon@Simon-PC.lindenlab.com <simon@Simon-PC.lindenlab.com> | 2012-06-14 15:11:59 -0700 | 
| commit | ce13a12d2d0e2fee349155a3218595b624867c4c (patch) | |
| tree | c7d4c16486edf893bda4d180bbd31400d7285db7 /indra | |
| parent | b0caa632cc479c6736efea995741e8334b9e766a (diff) | |
| parent | 93fcff2b24328560508bec2fbdea81761722eab6 (diff) | |
merge
Diffstat (limited to 'indra')
24 files changed, 422 insertions, 194 deletions
| diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 793fd4be31..fb03b3f956 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -285,9 +285,11 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)  //---------------------------------------------------------------------------- +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; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 99f0da330c..cc5c232380 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -69,6 +69,42 @@ LLRenderTarget::~LLRenderTarget()  	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(); diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 8360458840..e1a51304f1 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -57,8 +57,6 @@  */ -class LLMultisampleBuffer; -  class LLRenderTarget  {  public: @@ -74,6 +72,12 @@ 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); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index a42f4fcaa1..563b9b9cab 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -57,6 +57,8 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;  static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); +extern bool gShiftFrame; +  ////////////////////////  // @@ -716,6 +718,11 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)  		return;  	} +	if (gShiftFrame) +	{ +		return; +	} +  	//switch LOD with the spatial group to avoid artifacts  	//LLSpatialGroup* sg = getSpatialGroup(); @@ -825,14 +832,19 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)  		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);  		} @@ -846,7 +858,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)  				facep->mExtents[0].add(shift_vector);  				facep->mExtents[1].add(shift_vector); -				if (!volume && facep->hasGeometry()) +				if (rebuild && facep->hasGeometry())  				{  					facep->clearVertexBuffer();  				} @@ -957,6 +969,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)) @@ -979,6 +997,8 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)  	}  	mSpatialGroupp = groupp; + +	llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);  }  LLSpatialPartition* LLDrawable::getSpatialPartition() @@ -1406,6 +1426,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)  		markDead();  		return;  	} +	 +	if (gShiftFrame) +	{ +		return; +	}  	if (mDrawable->getVObj())  	{ @@ -1484,7 +1509,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(); @@ -1495,7 +1526,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 c01a8c3c29..bc4b301ebb 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -197,7 +197,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 diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 7c01a63b86..6c0be0a5c2 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -253,48 +253,6 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures  {  } -// 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); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 64774d06df..e0f2da41d7 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -186,10 +186,6 @@ public:  	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); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index b95d8296fa..7fc78fb382 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -294,6 +294,34 @@ void LLDrawPoolTerrain::renderShadow(S32 pass)  	//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! diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 283ed87f1a..2163d087e1 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -83,6 +83,7 @@ protected:  	void renderFull2TU();  	void renderFull4TU();  	void renderFullShader(); +	void drawLoop();  };  #endif // LL_LLDRAWPOOLSIMPLE_H diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 3165a3516c..83f04e45a8 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -37,6 +37,7 @@  #include "llviewershadermgr.h"  #include "llrender.h"  #include "llviewercontrol.h" +#include "llviewerregion.h"  S32 LLDrawPoolTree::sDiffTex = 0;  static LLGLSLShader* shader = NULL; @@ -104,8 +105,22 @@ void LLDrawPoolTree::render(S32 pass)  	{  		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()); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index c1c68040cd..9acdee702b 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1189,19 +1189,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 d995a1a5eb..d82b62dc19 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -68,6 +68,7 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f;  #define assert_states_valid(x)  #endif +extern bool gShiftFrame;  static U32 sZombieGroups = 0;  U32 LLSpatialGroup::sNodeCount = 0; @@ -923,7 +924,10 @@ void LLSpatialGroup::shift(const LLVector4a &offset)  	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); @@ -1238,6 +1242,11 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)  		return;  	} +	if (gShiftFrame) +	{ +		return; +	} +  #if !LL_RELEASE_FOR_DOWNLOAD  	if (isState(LLSpatialGroup::OBJECT_DIRTY))  	{ @@ -1838,12 +1847,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); diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 54a259f725..230e871b49 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -56,6 +56,7 @@  #include "lldrawable.h"  extern LLPipeline gPipeline; +extern bool gShiftFrame;  LLColor4U MAX_WATER_COLOR(0, 48, 96, 240); @@ -608,6 +609,11 @@ void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta)  void LLSurface::updatePatchVisibilities(LLAgent &agent)   { +	if (gShiftFrame) +	{ +		return; +	} +  	LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());  	LLSurfacePatch *patchp; diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 5077c2c7e1..a9ba2bce9c 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -43,6 +43,7 @@  #include "lldrawpool.h"  #include "noise.h" +extern bool gShiftFrame;  extern U64 gFrameTime;  extern LLPipeline gPipeline; @@ -218,7 +219,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3  	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); @@ -366,10 +367,13 @@ void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region)  {  	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  	{ diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 000e7404e8..0ad2a6eb9b 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -79,6 +79,7 @@  #include "llpostprocess.h"  extern LLPointer<LLViewerTexture> gStartTexture; +extern bool gShiftFrame;  LLPointer<LLViewerTexture> gDisconnectedImagep = NULL; @@ -162,8 +163,11 @@ void display_startup()  	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? @@ -217,6 +221,11 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");  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) @@ -226,6 +235,7 @@ 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(); @@ -362,6 +372,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	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. @@ -581,6 +592,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		// *TODO: merge these two methods  		{ +			LLFastTimer t(FTM_HUD_UPDATE);  			LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD);  			LLHUDManager::getInstance()->updateEffects();  			LLHUDObject::updateAll(); @@ -588,6 +600,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		}  		{ +			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); @@ -597,6 +610,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		}  		gPipeline.updateGL(); +		  		stop_glerror();  		S32 water_clip = 0; @@ -928,14 +942,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			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) @@ -1001,6 +1019,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	display_stats();  	LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); + +	gShiftFrame = false;  }  void render_hud_attachments() diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d72f6cfb59..bc15d90520 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -132,6 +132,7 @@ static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT	= 5;     // requests  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); @@ -3736,6 +3737,7 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)  void process_agent_movement_complete(LLMessageSystem* msg, void**)  { +	gShiftFrame = true;  	gAgentMovementCompleted = true;  	LLUUID agent_id; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 4a06685994..383d4a7955 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1438,12 +1438,24 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)  		if (active)  		{  			//llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl; -			llassert(objectp->getListIndex() == -1); - -			mActiveObjects.push_back(objectp); -			objectp->setListIndex(mActiveObjects.size()-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); -			objectp->setOnActiveList(TRUE); +				if (idx >= mActiveObjects.size() || +					mActiveObjects[idx] != objectp) +				{ +					llwarns << "Invalid object list index detected!" << llendl; +				} +			}  		}  		else  		{ @@ -1522,6 +1534,10 @@ void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id)  	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... @@ -1533,6 +1549,8 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)  		return;  	} +	LLFastTimer t(FTM_SHIFT_OBJECTS); +  	LLViewerObject *objectp;  	for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)  	{ @@ -1549,8 +1567,15 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)  		}  	} -	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() diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e3cb985ddb..e4108e2cd1 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1461,7 +1461,8 @@ void LLViewerRegion::unpackRegionHandshake()  		// 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  		{ diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ca5523dfbd..c5cbc307ed 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4757,8 +4757,11 @@ void LLViewerWindow::requestResolutionUpdate()  	mResDirty = true;  } +static LLFastTimer::DeclareTimer FTM_WINDOW_CHECK_SETTINGS("Window Settings"); +  void LLViewerWindow::checkSettings()  { +	LLFastTimer t(FTM_WINDOW_CHECK_SETTINGS);  	if (mStatesDirty)  	{  		gGL.refreshState(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 414ddc0c24..73c57adedd 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1370,8 +1370,6 @@ void LLVOAvatar::onShift(const LLVector4a& shift_vector)  	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) @@ -5066,9 +5064,9 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )  	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 diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 3556bde9a8..337ddfb24d 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -374,7 +374,7 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  		// *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); @@ -843,10 +843,10 @@ void LLVOTree::updateMesh()  	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 diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d66c47787e..082818b112 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4702,8 +4702,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())  							{ @@ -5037,8 +5043,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))  					{ diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 14867db182..03fef07c11 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -657,7 +657,10 @@ void LLWorld::updateRegions(F32 max_update_time)  		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; +		}  	}  } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0a4cf63205..7ff9a88d6e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -117,6 +117,8 @@  //#define DEBUG_INDICES  #endif +bool gShiftFrame = false; +  //cached settings  BOOL LLPipeline::RenderAvatarVP;  BOOL LLPipeline::VertexShaderEnable; @@ -214,7 +216,7 @@ BOOL	gDebugPipeline = FALSE;  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"); @@ -231,8 +233,13 @@ LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");  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"); @@ -1651,7 +1658,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)  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; @@ -2484,14 +2491,19 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)  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 @@ -2500,11 +2512,13 @@ void LLPipeline::updateGL()  	}  } +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(); @@ -2523,7 +2537,9 @@ void LLPipeline::rebuildPriorityGroups()  	mGroupQ1Locked = false;  } -		 + +static LLFastTimer::DeclareTimer FTM_REBUILD_GROUPS("Rebuild Groups"); +  void LLPipeline::rebuildGroups()  {  	if (mGroupQ2.empty()) @@ -2531,6 +2547,7 @@ void LLPipeline::rebuildGroups()  		return;  	} +	LLFastTimer t(FTM_REBUILD_GROUPS);  	mGroupQ2Locked = true;  	// Iterate through some drawables on the non-priority build queue  	S32 size = (S32) mGroupQ2.size(); @@ -2772,6 +2789,10 @@ void LLPipeline::markShift(LLDrawable *drawablep)  	}  } +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); @@ -2784,35 +2805,46 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)  	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()) +		LLFastTimer t(FTM_SHIFT_DRAWABLE); + +		for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); +			 iter != mShiftList.end(); iter++)  		{ -			continue; -		}	 -		drawablep->shiftPos(offseta);	 -		drawablep->clearState(LLDrawable::ON_SHIFT_LIST); +			LLDrawable *drawablep = *iter; +			if (drawablep->isDead()) +			{ +				continue; +			}	 +			drawablep->shiftPos(offseta);	 +			drawablep->clearState(LLDrawable::ON_SHIFT_LIST); +		} +		mShiftList.resize(0);  	} -	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++) +		LLFastTimer t(FTM_SHIFT_OCTREE); +		for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();  +				iter != LLWorld::getInstance()->getRegionList().end(); ++iter)  		{ -			LLSpatialPartition* part = region->getSpatialPartition(i); -			if (part) +			LLViewerRegion* region = *iter; +			for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)  			{ -				part->shift(offseta); +				LLSpatialPartition* part = region->getSpatialPartition(i); +				if (part) +				{ +					part->shift(offseta); +				}  			}  		}  	} -	LLHUDText::shiftAll(offset); -	LLHUDNameTag::shiftAll(offset); +	{ +		LLFastTimer t(FTM_SHIFT_HUD); +		LLHUDText::shiftAll(offset); +		LLHUDNameTag::shiftAll(offset); +	}  	display_update_camera();  } @@ -2845,8 +2877,10 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable)  	}  } +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; @@ -4106,7 +4140,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  	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); @@ -4148,7 +4182,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  		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); @@ -4201,7 +4235,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  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); @@ -4235,7 +4269,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)  		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); @@ -4772,8 +4806,11 @@ void LLPipeline::renderDebug()  	}  } +static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools"); +  void LLPipeline::rebuildPools()  { +	LLFastTimer t(FTM_REBUILD_POOLS);  	LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS);  	assertInitialized(); @@ -6332,13 +6369,16 @@ void LLPipeline::resetVertexBuffers()  	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; @@ -8757,6 +8797,8 @@ void LLPipeline::generateHighlight(LLCamera& camera)  } +static LLFastTimer::DeclareTimer FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); +  void LLPipeline::generateSunShadow(LLCamera& camera)  {  	if (!sRenderDeferred || RenderShadowDetail <= 0) @@ -8764,6 +8806,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		return;  	} +	LLFastTimer t(FTM_GEN_SUN_SHADOW); +  	BOOL skip_avatar_update = FALSE;  	if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)  	{ @@ -9522,6 +9566,12 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu  	}  } +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); @@ -9577,101 +9627,114 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	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) +		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)  		{ -			if (LLViewerObject* attached_object = (*attachment_iter)) +			LLViewerJointAttachment *attachment = iter->second; +			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +				 attachment_iter != attachment->mAttachedObjects.end(); +				 ++attachment_iter)  			{ -				markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); +				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; +	U32 resY = 0; +	U32 resX = 0; +	{ +		LLFastTimer t(FTM_IMPOSTOR_SETUP); +		const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); +		LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); -	LLVector4a half_height; -	half_height.setSub(ext[1], ext[0]); -	half_height.mul(0.5f); +		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 left; +		left.load3(camera.getLeftAxis().mV); +		left.mul(left); +		left.normalize3fast(); -	LLVector4a up; -	up.load3(camera.getUpAxis().mV); -	up.mul(up); -	up.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()); +		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(); +		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); +		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); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +		gGL.pushMatrix(); +		glh::matrix4f mat; +		camera.getOpenGLTransform(mat.m); -	mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; +		mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; -	gGL.loadMatrix(mat.m); -	glh_set_current_modelview(mat); +		gGL.loadMatrix(mat.m); +		glh_set_current_modelview(mat); -	glClearColor(0.0f,0.0f,0.0f,0.0f); -	gGL.setColorMask(true, true); +		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 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); +		//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() || resX != avatar->mImpostor.getWidth() || -		resY != avatar->mImpostor.getHeight()) -	{ -		avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); +		if (!avatar->mImpostor.isComplete()) +		{ +			LLFastTimer t(FTM_IMPOSTOR_ALLOCATE); +			avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); + +			if (LLPipeline::sRenderDeferred) +			{ +				addDeferredAttachments(avatar->mImpostor); +			} -		if (LLPipeline::sRenderDeferred) +			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())  		{ -			addDeferredAttachments(avatar->mImpostor); +			LLFastTimer t(FTM_IMPOSTOR_RESIZE); +			avatar->mImpostor.resize(resX,resY,GL_RGBA);  		} -		 -		gGL.getTexUnit(0)->bind(&avatar->mImpostor); -		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	} -	avatar->mImpostor.bindTarget(); +		avatar->mImpostor.bindTarget(); +	}  	if (LLPipeline::sRenderDeferred)  	{ @@ -9688,6 +9751,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	}  	{ //create alpha mask based on depth buffer (grey out if muted) +		LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);  		if (LLPipeline::sRenderDeferred)  		{  			GLuint buff = GL_COLOR_ATTACHMENT0; | 
