diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llrender.cpp | 16 | ||||
| -rw-r--r-- | indra/llrender/llrender.h | 1 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 6 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.h | 1 | ||||
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 11 | ||||
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl | 4 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 182 | ||||
| -rw-r--r-- | indra/newview/lldrawpoolavatar.h | 1 | ||||
| -rwxr-xr-x | indra/newview/llface.cpp | 7 | ||||
| -rwxr-xr-x | indra/newview/llmeshrepository.cpp | 3 | ||||
| -rwxr-xr-x | indra/newview/llvoavatar.cpp | 258 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.h | 3 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 45 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 41 | 
15 files changed, 343 insertions, 242 deletions
| diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 4597d06260..a12e9caf4c 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -2282,6 +2282,22 @@ void LLRender::diffuseColor4ubv(const U8* c)  	}  } +void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a) +{ +	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +	llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + +	if (shader) +	{ +		shader->uniform4f(LLShaderMgr::DIFFUSE_COLOR, r/255.f, g/255.f, b/255.f, a/255.f); +	} +	else +	{ +		glColor4ub(r,g,b,a); +	} +} + +  void LLRender::debugTexUnits(void)  {  	LL_INFOS("TextureUnit") << "Active TexUnit: " << mCurrTextureUnitIndex << LL_ENDL; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 78a310e525..90b1ec2f57 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -388,6 +388,7 @@ public:  	void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);  	void diffuseColor4fv(const F32* c);  	void diffuseColor4ubv(const U8* c); +	void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);  	void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);  	void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count); diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index e35feda2d5..e501d0495b 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -458,6 +458,12 @@ U32 LLRenderTarget::getTexture(U32 attachment) const  	return mTex[attachment];  } +U32 LLRenderTarget::getNumTextures() const +{ +	return mTex.size(); +} + +  void LLRenderTarget::bindTexture(U32 index, S32 channel)  {  	gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index)); diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index cf15f66d31..5cff0a0a21 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -113,6 +113,7 @@ public:  	LLTexUnit::eTextureType getUsage(void) const { return mUsage; }  	U32 getTexture(U32 attachment = 0) const; +	U32 getNumTextures() const;  	U32 getDepth(void) const { return mDepth; }  	bool hasStencil() const { return mStencil; } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b302f5c9b9..e06b4bbe13 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9169,6 +9169,17 @@      <key>Value</key>      <integer>0</integer>    </map> +  <key>RenderAutoMuteRenderCostLimit</key> +  <map> +    <key>Comment</key> +    <string>Maximum render cost before an avatar is automatically visually muted (0 for no limit).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <integer>0</integer> +  </map>    <key>RenderAutoMuteSurfaceAreaLimit</key>    <map>      <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index bfd9b9b3eb..29a6d842d2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -31,6 +31,8 @@ out vec4 frag_data[3];  uniform sampler2D diffuseMap; +uniform float minimum_alpha; +  VARYING vec3 vary_normal;  VARYING vec2 vary_texcoord0; @@ -38,7 +40,7 @@ void main()  {  	vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy); -	if (diff.a < 0.2) +	if (diff.a < minimum_alpha)  	{  		discard;  	} diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 38268b102b..03641140dc 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -59,6 +59,7 @@ LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;  BOOL	LLDrawPoolAvatar::sSkipOpaque = FALSE;  BOOL	LLDrawPoolAvatar::sSkipTransparent = FALSE;  S32 LLDrawPoolAvatar::sDiffuseChannel = 0; +F32 LLDrawPoolAvatar::sMinimumAlpha = 0.2f;  static bool is_deferred_render = false; @@ -272,7 +273,7 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()  	gPipeline.bindDeferredShader(*sVertexProgram); -	sVertexProgram->setMinimumAlpha(0.2f); +	sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);  	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  } @@ -620,7 +621,7 @@ void LLDrawPoolAvatar::beginRigid()  		if (sVertexProgram != NULL)  		{	//eyeballs render with the specular shader  			sVertexProgram->bind(); -			sVertexProgram->setMinimumAlpha(0.2f); +			sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);  		}  	}  	else @@ -671,7 +672,7 @@ void LLDrawPoolAvatar::beginDeferredRigid()  	sVertexProgram = &gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;  	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  	sVertexProgram->bind(); -	sVertexProgram->setMinimumAlpha(0.2f); +	sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);  }  void LLDrawPoolAvatar::endDeferredRigid() @@ -729,7 +730,7 @@ void LLDrawPoolAvatar::beginSkinned()  	if (LLGLSLShader::sNoFixedFunction)  	{ -		sVertexProgram->setMinimumAlpha(0.2f); +		sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);  	}  } @@ -1027,7 +1028,7 @@ void LLDrawPoolAvatar::beginDeferredSkinned()  	sRenderingSkinned = TRUE;  	sVertexProgram->bind(); -	sVertexProgram->setMinimumAlpha(0.2f); +	sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);  	sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);  	gGL.getTexUnit(0)->activate(); @@ -1138,7 +1139,10 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  		if (impostor)  		{ -			if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete())  +			if (LLPipeline::sRenderDeferred && //rendering a deferred impostor +				!LLPipeline::sReflectionRender &&  +				avatarp->mImpostor.isComplete() && //impostor has required data channels +				avatarp->mImpostor.getNumTextures() >= 3)   			{  				if (normal_channel > -1)  				{ @@ -1151,113 +1155,95 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  			}  			avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel);  		} -		return;  	} - -	llassert(LLPipeline::sImpostorRender || !avatarp->isVisuallyMuted()); - -	/*if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview,  3=morph view -	{ -		gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); -	}*/ -	 -	if (pass == 1) +	else if (pass == 1)  	{  		// render rigid meshes (eyeballs) first  		avatarp->renderRigid(); -		return;  	} - -	if (pass == 3) -	{ -		if (is_deferred_render) -		{ -			renderDeferredRiggedSimple(avatarp); -		} -		else -		{ -			renderRiggedSimple(avatarp); -		} -		return; -	} - -	if (pass == 4) -	{ -		if (is_deferred_render) -		{ -			renderDeferredRiggedBump(avatarp); -		} -		else +	else if (pass >= 3 && pass <= 9) +	{ //render rigged attachments +		if (!avatarp->isVisuallyMuted())  		{ -			renderRiggedFullbright(avatarp); +			if (pass == 3) +			{ +				if (is_deferred_render) +				{ +					renderDeferredRiggedSimple(avatarp); +				} +				else +				{ +					renderRiggedSimple(avatarp); +				} +			} +			else if (pass == 4) +			{ +				if (is_deferred_render) +				{ +					renderDeferredRiggedBump(avatarp); +				} +				else +				{ +					renderRiggedFullbright(avatarp); +				} +			} +			else if (pass == 5) +			{ +				renderRiggedShinySimple(avatarp); +			} +			else if (pass == 6) +			{ +				renderRiggedFullbrightShiny(avatarp); +			} +			else if (pass >= 7 && pass < 9) +			{ +				if (pass == 7) +				{ +					renderRiggedAlpha(avatarp); +				} +				else if (pass == 8) +				{ +					renderRiggedFullbrightAlpha(avatarp); +				} +			} +			else if (pass == 9) +			{ +				renderRiggedGlow(avatarp); +			}  		} - -		return;  	} - -	if (pass == 5) -	{ -		renderRiggedShinySimple(avatarp); -		return; -	} - -	if (pass == 6) -	{ -		renderRiggedFullbrightShiny(avatarp); -		return; -	} - -	if (pass >= 7 && pass < 9) +	else  	{ -		if (pass == 7) +		if ((sShaderLevel >= SHADER_LEVEL_CLOTH))  		{ -			renderRiggedAlpha(avatarp); -			return; +			LLMatrix4 rot_mat; +			LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); +			LLMatrix4 cfr(OGL_TO_CFR_ROTATION); +			rot_mat *= cfr; +		 +			LLVector4 wind; +			wind.setVec(avatarp->mWindVec); +			wind.mV[VW] = 0; +			wind = wind * rot_mat; +			wind.mV[VW] = avatarp->mWindVec.mV[VW]; + +			sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); +			F32 phase = -1.f * (avatarp->mRipplePhase); + +			F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); +			LLVector4 sin_params(freq, freq, freq, phase); +			sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); + +			LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); +			gravity = gravity * rot_mat; +			sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV);  		} -		if (pass == 8) +		if( !single_avatar || (avatarp == single_avatar) )  		{ -			renderRiggedFullbrightAlpha(avatarp); -			return; +			avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);  		}  	} - -	if (pass == 9) -	{ -		renderRiggedGlow(avatarp); -		 -		return; -	} -	 -	if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) -	{ -		LLMatrix4 rot_mat; -		LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); -		LLMatrix4 cfr(OGL_TO_CFR_ROTATION); -		rot_mat *= cfr; -		 -		LLVector4 wind; -		wind.setVec(avatarp->mWindVec); -		wind.mV[VW] = 0; -		wind = wind * rot_mat; -		wind.mV[VW] = avatarp->mWindVec.mV[VW]; - -		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); -		F32 phase = -1.f * (avatarp->mRipplePhase); - -		F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); -		LLVector4 sin_params(freq, freq, freq, phase); -		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); - -		LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); -		gravity = gravity * rot_mat; -		sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV); -	} - -	if( !single_avatar || (avatarp == single_avatar) ) -	{ -		avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); -	}  }  void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 5551d8f6d8..544969001d 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -209,6 +209,7 @@ public:  	static BOOL sSkipOpaque;  	static BOOL sSkipTransparent;  	static S32 sDiffuseChannel; +	static F32 sMinimumAlpha;  	static LLGLSLShader* sVertexProgram;  }; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 28e4b32793..a7e225843c 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -51,6 +51,7 @@  #include "llviewerregion.h"  #include "llviewerwindow.h"  #include "llviewershadermgr.h" +#include "llvoavatar.h"  #define LL_MAX_INDICES_COUNT 1000000 @@ -325,6 +326,12 @@ void LLFace::dirtyTexture()  		if (vobj)  		{  			vobj->mLODChanged = TRUE; + +			LLVOAvatar* avatar = vobj->getAvatar(); +			if (avatar) +			{ //avatar render cost may have changed +				avatar->updateVisualComplexity(); +			}  		}  		gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);  	}		 diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1223615079..5b65687090 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1200,8 +1200,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat  			LLMutexLock lock(mHeaderMutex);  			mMeshHeaderSize[mesh_id] = header_size;  			mMeshHeader[mesh_id] = header; -			} - +		}  		LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 62e93b7a53..4efd59685e 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -688,6 +688,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mFullyLoaded(FALSE),  	mPreviousFullyLoaded(FALSE),  	mFullyLoadedInitialized(FALSE), +	mVisualComplexity(0), +	mVisualComplexityStale(TRUE),  	mSupportsAlphaLayers(FALSE),  	mLoadedCallbacksPaused(FALSE),  	mHasPelvisOffset( FALSE ), @@ -3434,12 +3436,23 @@ void LLVOAvatar::slamPosition()  bool LLVOAvatar::isVisuallyMuted() const  { -	static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit"); -	static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); +	bool ret = false; + +	if (!isSelf()) +	{ +		static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit"); +		static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); +		static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderCostLimit"); -	return LLMuteList::getInstance()->isMuted(getID()) || +		U32 max_cost = (U32) (max_render_cost*(LLVOAvatar::sLODFactor+0.5)); + +		ret = LLMuteList::getInstance()->isMuted(getID()) ||  			(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || -			(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f); +			(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f) || +			(mVisualComplexity > max_cost && max_render_cost > 0); +	} + +	return ret;  }  //------------------------------------------------------------------------ @@ -4139,46 +4152,6 @@ bool LLVOAvatar::shouldAlphaMask()  } -U32 LLVOAvatar::renderSkinnedAttachments() -{ -	/*U32 num_indices = 0; -	 -	const U32 data_mask =	LLVertexBuffer::MAP_VERTEX |  -							LLVertexBuffer::MAP_NORMAL |  -							LLVertexBuffer::MAP_TEXCOORD0 | -							LLVertexBuffer::MAP_COLOR | -							LLVertexBuffer::MAP_WEIGHT4; - -	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();  -		 iter != 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) -		{ -			const LLViewerObject* attached_object = (*attachment_iter); -			if (attached_object && !attached_object->isHUDAttachment()) -			{ -				const LLDrawable* drawable = attached_object->mDrawable; -				if (drawable) -				{ -					for (S32 i = 0; i < drawable->getNumFaces(); ++i) -					{ -						LLFace* face = drawable->getFace(i); -						if (face->isState(LLFace::RIGGED)) -						{ -							 -				} -			} -		} -	} - -	return num_indices;*/ -	return 0; -} -  //-----------------------------------------------------------------------------  // renderSkinned()  //----------------------------------------------------------------------------- @@ -4336,21 +4309,23 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  		BOOL first_pass = TRUE;  		if (!LLDrawPoolAvatar::sSkipOpaque)  		{ +			bool muted = isVisuallyMuted(); +  			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)  			{ -				if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) +				if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy || muted)  				{  					num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea, TRUE, mIsDummy);  					first_pass = FALSE;  				}  			} -			if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) +			if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy || muted)  			{  				num_indices += mMeshLOD[MESH_ID_UPPER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);  				first_pass = FALSE;  			} -			if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) +			if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy || muted)  			{  				num_indices += mMeshLOD[MESH_ID_LOWER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);  				first_pass = FALSE; @@ -6090,6 +6065,8 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o  		return 0;  	} +	mVisualComplexityStale = TRUE; +  	if (viewer_object->isSelected())  	{  		LLSelectMgr::getInstance()->updateSelectionCenter(); @@ -6244,6 +6221,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)  		if (attachment->isObjectAttached(viewer_object))  		{ +			mVisualComplexityStale = TRUE;  			cleanupAttachedMesh( viewer_object );  			attachment->removeObject(viewer_object);  			lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl; @@ -8456,7 +8434,7 @@ void LLVOAvatar::updateImpostors()  BOOL LLVOAvatar::isImpostor() const  { -	return (isVisuallyMuted() || (sUseImpostors && mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE; +	return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;  } @@ -8501,6 +8479,8 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d  void LLVOAvatar::idleUpdateRenderCost()  { +	static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAutoMuteRenderCostLimit"); +  	static const U32 ARC_BODY_PART_COST = 200;  	static const U32 ARC_LIMIT = 20000; @@ -8511,123 +8491,147 @@ void LLVOAvatar::idleUpdateRenderCost()  		setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea));  	} -	if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) +	if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME) && max_render_cost == 0)  	{  		return;  	} -	U32 cost = 0; -	LLVOVolume::texture_cost_t textures; - -	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) +	if (mVisualComplexityStale)  	{ -		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); -		ETextureIndex tex_index = baked_dict->mTextureIndex; -		if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT))) +		mVisualComplexityStale = FALSE; +		U32 cost = 0; +		LLVOVolume::texture_cost_t textures; + +		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)  		{ -			if (isTextureVisible(tex_index)) +			const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index); +			ETextureIndex tex_index = baked_dict->mTextureIndex; +			if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))  			{ -				cost +=ARC_BODY_PART_COST; +				if (isTextureVisible(tex_index)) +				{ +					cost +=ARC_BODY_PART_COST; +				}  			}  		} -	} -	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();  -		 iter != 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) +		for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();  +			 iter != mAttachmentPoints.end(); +			 ++iter)  		{ -			const LLViewerObject* attached_object = (*attachment_iter); -			if (attached_object && !attached_object->isHUDAttachment()) +			LLViewerJointAttachment* attachment = iter->second; +			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); +				 attachment_iter != attachment->mAttachedObjects.end(); +				 ++attachment_iter)  			{ -				textures.clear(); -				const LLDrawable* drawable = attached_object->mDrawable; -				if (drawable) +				const LLViewerObject* attached_object = (*attachment_iter); +				if (attached_object && !attached_object->isHUDAttachment())  				{ -					const LLVOVolume* volume = drawable->getVOVolume(); -					if (volume) +					textures.clear(); +					const LLDrawable* drawable = attached_object->mDrawable; +					if (drawable)  					{ -						cost += volume->getRenderCost(textures); - -						const_child_list_t children = volume->getChildren(); -						for (const_child_list_t::const_iterator child_iter = children.begin(); -							  child_iter != children.end(); -							  ++child_iter) +						const LLVOVolume* volume = drawable->getVOVolume(); +						if (volume)  						{ -							LLViewerObject* child_obj = *child_iter; -							LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); -							if (child) +							cost += volume->getRenderCost(textures); + +							const_child_list_t children = volume->getChildren(); +							for (const_child_list_t::const_iterator child_iter = children.begin(); +								  child_iter != children.end(); +								  ++child_iter)  							{ -								cost += child->getRenderCost(textures); +								LLViewerObject* child_obj = *child_iter; +								LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); +								if (child) +								{ +									cost += child->getRenderCost(textures); +								}  							} -						} -						for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) -						{ -							// add the cost of each individual texture in the linkset -							cost += iter->second; +							for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) +							{ +								// add the cost of each individual texture in the linkset +								cost += iter->second; +							}  						}  					}  				}  			} -		} -	} +		} -	// Diagnostic output to identify all avatar-related textures. -	// Does not affect rendering cost calculation. -	// Could be wrapped in a debug option if output becomes problematic. -	if (isSelf()) -	{ -		// print any attachment textures we didn't already know about. -		for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) +		// Diagnostic output to identify all avatar-related textures. +		// Does not affect rendering cost calculation. +		// Could be wrapped in a debug option if output becomes problematic. +		if (isSelf())  		{ -			LLUUID image_id = it->first; -			if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) -				continue; -			if (all_textures.find(image_id) == all_textures.end()) +			// print any attachment textures we didn't already know about. +			for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) +			{ +				LLUUID image_id = it->first; +				if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) +					continue; +				if (all_textures.find(image_id) == all_textures.end()) +				{ +					// attachment texture not previously seen. +					llinfos << "attachment_texture: " << image_id.asString() << llendl; +					all_textures.insert(image_id); +				} +			} + +			// print any avatar textures we didn't already know about +			for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); +				 iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); +				 ++iter)  			{ -				// attachment texture not previously seen. -				llinfos << "attachment_texture: " << image_id.asString() << llendl; -				all_textures.insert(image_id); +				const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; +				// TODO: MULTI-WEARABLE: handle multiple textures for self +				const LLViewerTexture* te_image = getImage(iter->first,0); +				if (!te_image) +					continue; +				LLUUID image_id = te_image->getID(); +				if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) +					continue; +				if (all_textures.find(image_id) == all_textures.end()) +				{ +					llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl; +					all_textures.insert(image_id); +				}  			}  		} -		// print any avatar textures we didn't already know about -		for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin(); -			 iter != LLVOAvatarDictionary::getInstance()->getTextures().end(); -			 ++iter) -		{ -			const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second; -			// TODO: MULTI-WEARABLE: handle multiple textures for self -			const LLViewerTexture* te_image = getImage(iter->first,0); -			if (!te_image) -				continue; -			LLUUID image_id = te_image->getID(); -			if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) -				continue; -			if (all_textures.find(image_id) == all_textures.end()) +		if (isSelf() && max_render_cost > 0 && mVisualComplexity != cost) +		{ //pop up notification that you have exceeded a render cost limit +			if (cost > max_render_cost+max_render_cost/2) +			{ +				LLNotificationsUtil::add("ExceededHighDetailRenderCost"); +			} +			else if (cost > max_render_cost)  			{ -				llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl; -				all_textures.insert(image_id); +				LLNotificationsUtil::add("ExceededMidDetailRenderCost"); +			} +			else if (cost > max_render_cost/2) +			{ +				LLNotificationsUtil::add("ExceededLowDetailRenderCost");  			}  		} + +		mVisualComplexity = cost;  	} -	std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); -	setDebugText(llformat("%s %d", viz_string.c_str(), cost)); -	mVisualComplexity = cost; -	F32 green = 1.f-llclamp(((F32) cost-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); -	F32 red = llmin((F32) cost/(F32)ARC_LIMIT, 1.f); -	mText->setColor(LLColor4(red,green,0,1)); +	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME)) +	{ +		std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); +		setDebugText(llformat("%s %d", viz_string.c_str(), mVisualComplexity)); +		F32 green = 1.f-llclamp(((F32) mVisualComplexity-(F32)ARC_LIMIT)/(F32)ARC_LIMIT, 0.f, 1.f); +		F32 red = llmin((F32) mVisualComplexity/(F32)ARC_LIMIT, 1.f); +		mText->setColor(LLColor4(red,green,0,1)); +	}  }  // static diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 1adb680962..e6569c557c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -252,6 +252,7 @@ public:  	static void		invalidateNameTags();  	void			addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font);  	void 			idleUpdateRenderCost(); +	void			updateVisualComplexity() { mVisualComplexityStale = TRUE; }  	void 			idleUpdateBelowWater();  	//-------------------------------------------------------------------- @@ -314,6 +315,7 @@ private:  	BOOL			mFullyLoadedInitialized;  	S32				mFullyLoadedFrameCounter;  	S32				mVisualComplexity; +	BOOL			mVisualComplexityStale;  	LLFrameTimer	mFullyLoadedTimer;  	LLFrameTimer	mRuthTimer; @@ -437,7 +439,6 @@ public:  	U32 		renderRigid();  	U32 		renderSkinned(EAvatarRenderPass pass);  	F32			getLastSkinTime() { return mLastSkinTime; } -	U32			renderSkinnedAttachments();  	U32 		renderTransparent(BOOL first_pass);  	void 		renderCollisionVolumes();  	static void	deleteCachedImages(bool clearAll=true); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c0f80cf855..b853112f74 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1116,6 +1116,12 @@ void LLVOVolume::notifyMeshLoaded()  {   	mSculptChanged = TRUE;  	gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE); + +	LLVOAvatar* avatar = getAvatar(); +	if (avatar) +	{ +		avatar->updateVisualComplexity(); +	}  }  // sculpt replaces generate() for sculpted surfaces diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4306b3da12..45d6d23b51 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -10247,6 +10247,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		avatar->mImpostor.bindTarget();  	} +	F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha; + +	if (muted) +	{ //disable alpha masking for muted avatars (get whole skin silhouette) +		LLDrawPoolAvatar::sMinimumAlpha = 0.f; +	} +  	if (LLPipeline::sRenderDeferred)  	{  		avatar->mImpostor.clear(); @@ -10260,7 +10267,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		avatar->mImpostor.clear();  		renderGeom(camera);  	} -	 + +	LLDrawPoolAvatar::sMinimumAlpha = old_alpha; +		  	{ //create alpha mask based on depth buffer (grey out if muted)  		LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);  		if (LLPipeline::sRenderDeferred) @@ -10274,6 +10283,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		if (muted)  		{  			gGL.setColorMask(true, true); +  		}  		else  		{ @@ -10292,25 +10302,36 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		gGL.pushMatrix();  		gGL.loadIdentity(); -		static const F32 clip_plane = 0.99999f; +		static const F32 clip_plane = 0.999f;  		if (LLGLSLShader::sNoFixedFunction)  		{ -			gUIProgram.bind(); +			gDebugProgram.bind();  		} -		gGL.color4ub(64,64,64,255); -		gGL.begin(LLRender::QUADS); -		gGL.vertex3f(-1, -1, clip_plane); -		gGL.vertex3f(1, -1, clip_plane); -		gGL.vertex3f(1, 1, clip_plane); -		gGL.vertex3f(-1, 1, clip_plane); -		gGL.end(); -		gGL.flush(); + +		if (LLMuteList::getInstance()->isMuted(avatar->getID())) +		{ //grey muted avatar +			gGL.diffuseColor4ub(64,64,64,255); +		} +		else +		{ //blue visually muted avatar +			gGL.diffuseColor4ub(72,61,139,255); +		} + +		{ +			gGL.begin(LLRender::QUADS); +			gGL.vertex3f(-1, -1, clip_plane); +			gGL.vertex3f(1, -1, clip_plane); +			gGL.vertex3f(1, 1, clip_plane); +			gGL.vertex3f(-1, 1, clip_plane); +			gGL.end(); +			gGL.flush(); +		}  		if (LLGLSLShader::sNoFixedFunction)  		{ -			gUIProgram.unbind(); +			gDebugProgram.unbind();  		}  		gGL.popMatrix(); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 832e05a06f..fb530ef22d 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -203,6 +203,45 @@ Message Template [PATH] not found.    </notification>    <notification +   icon="notify.tga" +   name="ExceededHighDetailRenderCost" +   persist="false" +   type="alertmodal"> +    Your avatar has become too complex to be rendered by even high performance computers.  Almost all Residents will see a low detail stand in instead of your actual avatar. +    <unique/> +    <usetemplate +     ignoretext="Avatar exceeded high detail complexity." +     name="okignore" +     yestext="Close"/> +  </notification> + +  <notification +   icon="notify.tga" +   name="ExceededMidDetailRenderCost" +   persist="false" +   type="alertmodal"> +    Your avatar has become too complex to be rendered by most computers.  Many Residents will see a low detail stand in instead of your actual avatar. +  <unique/> +  <usetemplate +   ignoretext="Avatar exceeded mid detail complexity." +   name="okignore" +   yestext="Close"/> +</notification> + +  <notification + icon="notify.tga" + name="ExceededLowDetailRenderCost" + persist="false" + type="alertmodal"> +    Your avatar has become too complex to be rendered by some computers.  Some Residents will see a low detail stand in instead of your actual avatar. +  <unique/> +  <usetemplate +   ignoretext="Avatar exceeded low detail complexity." +   name="okignore" +   yestext="Close"/> +  </notification> + +  <notification     icon="alertmodal.tga"     name="WearableSave"     type="alertmodal"> @@ -9935,5 +9974,5 @@ An internal error prevented us from properly updating your viewer.  The L$ balan     <tag>fail</tag>  Cannot create large prims that intersect other players.  Please re-try when other players have moved.    </notification> - +    </notifications> | 
