diff options
Diffstat (limited to 'indra/newview')
29 files changed, 449 insertions, 174 deletions
| diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 28ba9fd704..7df92e5276 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9057,6 +9057,28 @@        <key>Value</key>        <integer>1</integer>      </map> +  <key>RenderAutoMuteByteLimit</key> +  <map> +    <key>Comment</key> +    <string>Maximum bytes of attachments 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> +    <string>Maximum surface area of attachments before an avatar is automatically visually muted (0 for no limit).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <integer>0</integer> +  </map>      <key>RenderUseShaderLOD</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl index 0170ad4b55..40b0cf47ac 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl @@ -61,17 +61,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  	vec3 lv = lp.xyz-v;  	//get distance -	float d = length(lv); +	float d = dot(lv,lv);  	float da = 0.0;  	if (d > 0.0 && la > 0.0 && fa > 0.0)  	{  		//normalize light vector -		lv *= 1.0/d; +		lv = normalize(lv);  		//distance attenuation -		float dist2 = d*d/(la*la); +		float dist2 = d/la;  		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);  		// spotlight coefficient. @@ -79,7 +79,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= spot*spot; // GL_SPOT_EXPONENT=2  		//angular attenuation -		da *= calcDirectionalLight(n, lv); +		da *= max(dot(n, lv), 0.0);		  	}  	return da;	 diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 93b1a114db..8c96d55342 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -70,17 +70,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  	vec3 lv = lp.xyz-v;  	//get distance -	float d = length(lv); +	float d = dot(lv,lv);  	float da = 0.0;  	if (d > 0.0 && la > 0.0 && fa > 0.0)  	{  		//normalize light vector -		lv *= 1.0/d; +		lv = normalize(lv);  		//distance attenuation -		float dist2 = d*d/(la*la); +		float dist2 = d/la;  		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);  		// spotlight coefficient. @@ -88,7 +88,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= spot*spot; // GL_SPOT_EXPONENT=2  		//angular attenuation -		da *= calcDirectionalLight(n, lv); +		da *= max(dot(n, lv), 0.0);		  	}  	return da;	 @@ -123,7 +123,6 @@ void main()  	col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);  	vary_pointlight_col = col.rgb*diffuse_color.rgb; -  	col.rgb = vec3(0,0,0);  	// Add windlight lights diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index d7b90978ba..c0edddc40a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -65,17 +65,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  	vec3 lv = lp.xyz-v;  	//get distance -	float d = length(lv); +	float d = dot(lv,lv);  	float da = 0.0;  	if (d > 0.0 && la > 0.0 && fa > 0.0)  	{  		//normalize light vector -		lv *= 1.0/d; +		lv = normalize(lv);  		//distance attenuation -		float dist2 = d*d/(la*la); +		float dist2 = d/la;  		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);  		// spotlight coefficient. @@ -83,7 +83,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= spot*spot; // GL_SPOT_EXPONENT=2  		//angular attenuation -		da *= calcDirectionalLight(n, lv); +		da *= max(dot(n, lv), 0.0);		  	}  	return da;	 diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl index 5a3955ef00..83815b1786 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -63,21 +63,21 @@ uniform vec3 light_diffuse[8];  float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight)  { -	//get light vector +//get light vector  	vec3 lv = lp.xyz-v;  	//get distance -	float d = length(lv); +	float d = dot(lv,lv);  	float da = 0.0;  	if (d > 0.0 && la > 0.0 && fa > 0.0)  	{  		//normalize light vector -		lv *= 1.0/d; +		lv = normalize(lv);  		//distance attenuation -		float dist2 = d*d/(la*la); +		float dist2 = d/la;  		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);  		// spotlight coefficient. @@ -85,7 +85,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= spot*spot; // GL_SPOT_EXPONENT=2  		//angular attenuation -		da *= calcDirectionalLight(n, lv); +		da *= max(dot(n, lv), 0.0);		  	}  	return da;	 diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index 9540ddd2e8..1660f9687e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -69,17 +69,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  	vec3 lv = lp.xyz-v;  	//get distance -	float d = length(lv); +	float d = dot(lv,lv);  	float da = 0.0;  	if (d > 0.0 && la > 0.0 && fa > 0.0)  	{  		//normalize light vector -		lv *= 1.0/d; +		lv = normalize(lv);  		//distance attenuation -		float dist2 = d*d/(la*la); +		float dist2 = d/la;  		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);  		// spotlight coefficient. @@ -87,7 +87,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= spot*spot; // GL_SPOT_EXPONENT=2  		//angular attenuation -		da *= calcDirectionalLight(n, lv); +		da *= max(dot(n, lv), 0.0);		  	}  	return da;	 diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl index 9c7a332417..84c27edb26 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -66,17 +66,17 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  	vec3 lv = lp.xyz-v;  	//get distance -	float d = length(lv); +	float d = dot(lv,lv);  	float da = 0.0;  	if (d > 0.0 && la > 0.0 && fa > 0.0)  	{  		//normalize light vector -		lv *= 1.0/d; +		lv = normalize(lv);  		//distance attenuation -		float dist2 = d*d/(la*la); +		float dist2 = d/la;  		da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);  		// spotlight coefficient. @@ -84,7 +84,7 @@ float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, floa  		da *= spot*spot; // GL_SPOT_EXPONENT=2  		//angular attenuation -		da *= calcDirectionalLight(n, lv); +		da *= max(dot(n, lv), 0.0);		  	}  	return da;	 diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp index 1edc96e165..4097ff707c 100644 --- a/indra/newview/llagentwearablesfetch.cpp +++ b/indra/newview/llagentwearablesfetch.cpp @@ -111,6 +111,12 @@ void LLInitialWearablesFetch::add(InitialWearableData &data)  void LLInitialWearablesFetch::processContents()  { +	if(!gAgentAvatarp) //no need to process wearables if the agent avatar is deleted. +	{ +		delete this; +		return ; +	} +  	// Fetch the wearable items from the Current Outfit Folder  	LLInventoryModel::cat_array_t cat_array;  	LLInventoryModel::item_array_t wearable_array; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index debac9dcbf..21b21c152a 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1077,6 +1077,7 @@ BOOL LLDrawable::isVisible() const  LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)  : LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)  { +	mBridge = this;  	mDrawable = root;  	root->setSpatialBridge(this); @@ -1105,6 +1106,15 @@ LLSpatialBridge::~LLSpatialBridge()  	{  		group->mSpatialPartition->remove(this, group);  	} + +	//delete octree here so listeners will still be able to access bridge specific state +	destroyTree(); +} + +void LLSpatialBridge::destroyTree() +{ +	delete mOctree; +	mOctree = NULL;  }  void LLSpatialBridge::updateSpatialExtents() diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 55b314fbb1..b002c11af5 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1285,7 +1285,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  		face->setGeomIndex(0);  		face->setIndicesIndex(0); -		if (buffer.isNull() || buffer->getTypeMask() != data_mask) +		if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())  		{ //make a new buffer  			if (sShaderLevel > 0)  			{ @@ -1319,7 +1319,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*  		LLMatrix3 mat_normal(mat3);				  		//let getGeometryVolume know if alpha should override shiny -		if (face->getFaceColor().mV[3] < 1.f) +		U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture()); + +		if (type == LLDrawPool::POOL_ALPHA)  		{  			face->setPoolType(LLDrawPool::POOL_ALPHA);  		} diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 6dbeae6677..cd33a19a2a 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -693,6 +693,49 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of  	tex_coord.mV[1] = t;  } +// Transform the texture coordinates for this face. +static void xform4a(LLVector4a &tex_coord, const LLVector4a& trans, const LLVector4Logical& mask, const LLVector4a& rot0, const LLVector4a& rot1, const LLVector4a& offset, const LLVector4a& scale)  +{ +	//tex coord is two coords, <s0, t0, s1, t1> +	LLVector4a st; + +	// Texture transforms are done about the center of the face. +	st.setAdd(tex_coord, trans); +	 +	// Handle rotation +	LLVector4a rot_st; +		 +	// <s0 * cosAng, s0*-sinAng, s1*cosAng, s1*-sinAng> +	LLVector4a s0; +	s0.splat(st, 0); +	LLVector4a s1; +	s1.splat(st, 2); +	LLVector4a ss; +	ss.setSelectWithMask(mask, s1, s0); + +	LLVector4a a;  +	a.setMul(rot0, ss); +	 +	// <t0*sinAng, t0*cosAng, t1*sinAng, t1*cosAng> +	LLVector4a t0; +	t0.splat(st, 1); +	LLVector4a t1; +	t1.splat(st, 3); +	LLVector4a tt; +	tt.setSelectWithMask(mask, t1, t0); + +	LLVector4a b; +	b.setMul(rot1, tt); +		 +	st.setAdd(a,b); + +	// Then scale +	st.mul(scale); + +	// Then offset +	tex_coord.setAdd(st, offset); +} +  bool less_than_max_mag(const LLVector4a& vec)  { @@ -1060,6 +1103,16 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_EMISSIVE("Emissive");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_WEIGHTS("Weights");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_BINORMAL("Binormal");  static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX("Index"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_INDEX_TAIL("Tail"); +static LLFastTimer::DeclareTimer FTM_FACE_POSITION_STORE("Pos"); +static LLFastTimer::DeclareTimer FTM_FACE_TEXTURE_INDEX_STORE("TexIdx"); +static LLFastTimer::DeclareTimer FTM_FACE_POSITION_PAD("Pad"); +static LLFastTimer::DeclareTimer FTM_FACE_TEX_DEFAULT("Default"); +static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK("Quick"); +static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_NO_XFORM("No Xform"); +static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_XFORM("Xform"); + +static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_PLANAR("Quick Planar");  BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							   const S32 &f, @@ -1078,7 +1131,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		updateRebuildFlags();  	} -	bool map_range = gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; + +	//don't use map range (generates many redundant unmap calls) +	bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;  	if (mVertexBuffer.notNull())  	{ @@ -1104,16 +1159,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	}  	LLStrider<LLVector3> vert; -	LLVector4a* vertices = NULL;  	LLStrider<LLVector2> tex_coords;  	LLStrider<LLVector2> tex_coords2; -	LLVector4a* normals = NULL;  	LLStrider<LLVector3> norm;  	LLStrider<LLColor4U> colors; -	LLVector4a* binormals = NULL;  	LLStrider<LLVector3> binorm;  	LLStrider<U16> indicesp; -	LLVector4a* weights = NULL;  	LLStrider<LLVector4> wght;  	BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME); @@ -1202,7 +1253,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		LLFastTimer t(FTM_FACE_GEOM_INDEX);  		mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range); -		__m128i* dst = (__m128i*) indicesp.get(); +		volatile __m128i* dst = (__m128i*) indicesp.get();  		__m128i* src = (__m128i*) vf.mIndices;  		__m128i offset = _mm_set1_epi16(index_offset); @@ -1211,12 +1262,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		for (S32 i = 0; i < end; i++)  		{  			__m128i res = _mm_add_epi16(src[i], offset); -			_mm_storeu_si128(dst+i, res); +			_mm_storeu_si128((__m128i*) dst++, res);  		} -		for (S32 i = end*8; i < num_indices; ++i)  		{ -			indicesp[i] = vf.mIndices[i]+index_offset; +			LLFastTimer t(FTM_FACE_GEOM_INDEX_TAIL); +			U16* idx = (U16*) dst; + +			for (S32 i = end*8; i < num_indices; ++i) +			{ +				*idx++ = vf.mIndices[i]+index_offset; +			}  		}  		if (map_range) @@ -1373,19 +1429,48 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			if (texgen != LLTextureEntry::TEX_GEN_PLANAR)  			{ +				LLFastTimer t(FTM_FACE_TEX_QUICK);  				if (!do_tex_mat)  				{  					if (!do_xform)  					{ +						LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);  						LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));  					}  					else  					{ -						for (S32 i = 0; i < num_vertices; i++) +						LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM); +						F32* dst = (F32*) tex_coords.get(); +						LLVector4a* src = (LLVector4a*) vf.mTexCoords; + +						LLVector4a trans; +						trans.splat(-0.5f); + +						LLVector4a rot0; +						rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang); + +						LLVector4a rot1; +						rot1.set(sin_ang, cos_ang, sin_ang, cos_ang); + +						LLVector4a scale; +						scale.set(ms, mt, ms, mt); + +						LLVector4a offset; +						offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f); + +						LLVector4Logical mask; +						mask.clear(); +						mask.setElement<2>(); +						mask.setElement<3>(); + +						U32 count = num_vertices/2 + num_vertices%2; + +						for (S32 i = 0; i < count; i++)  						{	 -							LLVector2 tc(vf.mTexCoords[i]); -							xform(tc, cos_ang, sin_ang, os, ot, ms, mt); -							*tex_coords++ = tc;	 +							LLVector4a res = *src++; +							xform4a(res, trans, mask, rot0, rot1, offset, scale); +							res.store4a(dst); +							dst += 4;  						}  					}  				} @@ -1407,6 +1492,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			}  			else  			{ //no bump, no atlas, tex gen planar +				LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);  				if (do_tex_mat)  				{  					for (S32 i = 0; i < num_vertices; i++) @@ -1451,6 +1537,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		}  		else  		{ //either bump mapped or in atlas, just do the whole expensive loop +			LLFastTimer t(FTM_FACE_TEX_DEFAULT);  			mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);  			std::vector<LLVector2> bump_tc; @@ -1642,44 +1729,55 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		llassert(num_vertices > 0);  		mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); -		vertices = (LLVector4a*) vert.get(); -	 +			 +  		LLMatrix4a mat_vert;  		mat_vert.loadu(mat_vert_in);  		LLVector4a* src = vf.mPositions; -		LLVector4a* dst = vertices; +		volatile F32* dst = (volatile F32*) vert.get(); -		LLVector4a* end = dst+num_vertices; -		do -		{	 -			mat_vert.affineTransform(*src++, *dst++); -		} -		while(dst < end); +		volatile F32* end = dst+num_vertices*4; +		LLVector4a res; -		F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0); +		LLVector4a texIdx; +		F32 index = (F32) (mTextureIndex < 255 ? mTextureIndex : 0);  		llassert(index <= LLGLSLShader::sIndexedTextureChannels-1); -		F32 *index_dst = (F32*) vertices; -		F32 *index_end = (F32*) end; -		index_dst += 3; -		index_end += 3; -		do +		LLVector4Logical mask; +		mask.clear(); +		mask.setElement<3>(); +		 +		texIdx.set(0,0,0,index); +  		{ -			*index_dst = index; -			index_dst += 4; +			LLFastTimer t(FTM_FACE_POSITION_STORE); +			LLVector4a tmp; + +			do +			{	 +				mat_vert.affineTransform(*src++, res); +				tmp.setSelectWithMask(mask, texIdx, res); +				tmp.store4a((F32*) dst); +				dst += 4; +			} +			while(dst < end);  		} -		while (index_dst < index_end); -		 -		S32 aligned_pad_vertices = mGeomCount - num_vertices; -		LLVector4a* last_vec = end - 1; -		while (aligned_pad_vertices > 0) +  		{ -			--aligned_pad_vertices; -			*dst++ = *last_vec; +			LLFastTimer t(FTM_FACE_POSITION_PAD); +			S32 aligned_pad_vertices = mGeomCount - num_vertices; +			res.set(res[0], res[1], res[2], 0.f); + +			while (aligned_pad_vertices > 0) +			{ +				--aligned_pad_vertices; +				res.store4a((F32*) dst); +				dst += 4; +			}  		} -		 +  		if (map_range)  		{  			mVertexBuffer->flush(); @@ -1690,14 +1788,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	{  		LLFastTimer t(FTM_FACE_GEOM_NORMAL);  		mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); -		normals = (LLVector4a*) norm.get(); +		F32* normals = (F32*) norm.get();  		for (S32 i = 0; i < num_vertices; i++)  		{	  			LLVector4a normal;  			mat_normal.rotate(vf.mNormals[i], normal);  			normal.normalize3fast(); -			normals[i] = normal; +			normal.store4a(normals); +			normals += 4;  		}  		if (map_range) @@ -1710,14 +1809,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	{  		LLFastTimer t(FTM_FACE_GEOM_BINORMAL);  		mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range); -		binormals = (LLVector4a*) binorm.get(); +		F32* binormals = (F32*) binorm.get();  		for (S32 i = 0; i < num_vertices; i++)  		{	  			LLVector4a binormal;  			mat_normal.rotate(vf.mBinormals[i], binormal);  			binormal.normalize3fast(); -			binormals[i] = binormal; +			binormal.store4a(binormals); +			binormals += 4;  		}  		if (map_range) @@ -1730,8 +1830,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	{  		LLFastTimer t(FTM_FACE_GEOM_WEIGHTS);  		mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range); -		weights = (LLVector4a*) wght.get(); -		LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); +		F32* weights = (F32*) wght.get(); +		LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));  		if (map_range)  		{  			mVertexBuffer->flush(); @@ -1750,7 +1850,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		src.loadua((F32*) vec); -		LLVector4a* dst = (LLVector4a*) colors.get(); +		F32* dst = (F32*) colors.get();  		S32 num_vecs = num_vertices/4;  		if (num_vertices%4 > 0)  		{ @@ -1759,7 +1859,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		for (S32 i = 0; i < num_vecs; i++)  		{	 -			dst[i] = src; +			src.store4a(dst); +			dst += 4;  		}  		if (map_range) @@ -1789,7 +1890,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		src.loadua((F32*) vec); -		LLVector4a* dst = (LLVector4a*) emissive.get(); +		F32* dst = (F32*) emissive.get();  		S32 num_vecs = num_vertices/4;  		if (num_vertices%4 > 0)  		{ @@ -1798,7 +1899,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		for (S32 i = 0; i < num_vecs; i++)  		{	 -			dst[i] = src; +			src.store4a(dst); +			dst += 4;  		}  		if (map_range) @@ -1821,6 +1923,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		mTexExtents[1][1] *= et ;  	} +  	mLastVertexBuffer = mVertexBuffer;  	mLastGeomCount = mGeomCount;  	mLastGeomIndex = mGeomIndex; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 64bdcccd9f..9122e5a8f5 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3969,7 +3969,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  				U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices();  				if (num_indices > 2)  				{ -					glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f); +					glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, (U8*) mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f);  				}  				tri_count += num_indices/3;  				stop_gloderror(); @@ -4083,14 +4083,14 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  				{  					buff->allocateBuffer(sizes[i*2+1], sizes[i*2], true);  					buff->setBuffer(type_mask); -					glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, buff->getIndicesPointer()); +					glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, (U8*) buff->getIndicesPointer());  					stop_gloderror();  				}  				else  				{ //this face was eliminated, create a dummy triangle (one vertex, 3 indices, all 0)  					buff->allocateBuffer(1, 3, true); -					memset(buff->getMappedData(), 0, buff->getSize()); -					memset(buff->getIndicesPointer(), 0, buff->getIndicesSize()); +					memset((U8*) buff->getMappedData(), 0, buff->getSize()); +					memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize());  				}  				buff->validateRange(0, buff->getNumVerts()-1, buff->getNumIndices(), 0); @@ -4880,8 +4880,8 @@ void LLModelPreview::addEmptyFace( LLModel* pTarget )  	LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);  	buff->allocateBuffer(1, 3, true); -	memset( buff->getMappedData(), 0, buff->getSize() ); -	memset( buff->getIndicesPointer(), 0, buff->getIndicesSize() ); +	memset( (U8*) buff->getMappedData(), 0, buff->getSize() ); +	memset( (U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize() );  	buff->validateRange( 0, buff->getNumVerts()-1, buff->getNumIndices(), 0 ); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a97e256c89..1d0c262190 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -88,6 +88,9 @@ const S32 MAX_MESH_VERSION = 999;  U32 LLMeshRepository::sBytesReceived = 0;  U32 LLMeshRepository::sHTTPRequestCount = 0;  U32 LLMeshRepository::sHTTPRetryCount = 0; +U32 LLMeshRepository::sLODProcessing = 0; +U32 LLMeshRepository::sLODPending = 0; +  U32 LLMeshRepository::sCacheBytesRead = 0;  U32 LLMeshRepository::sCacheBytesWritten = 0;  U32 LLMeshRepository::sPeakKbps = 0; @@ -497,6 +500,7 @@ void LLMeshRepoThread::run()  					mMutex->lock();  					LODRequest req = mLODReqQ.front();  					mLODReqQ.pop(); +					LLMeshRepository::sLODProcessing--;  					mMutex->unlock();  					if (fetchMeshLOD(req.mMeshParams, req.mLOD))  					{ @@ -603,6 +607,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  		{  			LLMutexLock lock(mMutex);  			mLODReqQ.push(req); +			LLMeshRepository::sLODProcessing++;  		}  	}  	else @@ -1045,6 +1050,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat  			{  				LODRequest req(mesh_params, iter->second[i]);  				mLODReqQ.push(req); +				LLMeshRepository::sLODProcessing++;  			}  		}  		mPendingLOD.erase(iter); @@ -2147,6 +2153,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para  			//first request for this mesh  			mLoadingMeshes[detail][mesh_params].insert(vobj->getID());  			mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); +			LLMeshRepository::sLODPending++;  		}  	} @@ -2359,6 +2366,7 @@ void LLMeshRepository::notifyLoadedMeshes()  			LLMeshRepoThread::LODRequest& request = mPendingRequests.front();  			mThread->loadMeshLOD(request.mMeshParams, request.mLOD);  			mPendingRequests.erase(mPendingRequests.begin()); +			LLMeshRepository::sLODPending--;  			push_count--;  		}  	} diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 31b84ea0d9..1bdbc2856b 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -441,6 +441,8 @@ public:  	static U32 sBytesReceived;  	static U32 sHTTPRequestCount;  	static U32 sHTTPRetryCount; +	static U32 sLODPending; +	static U32 sLODProcessing;  	static U32 sCacheBytesRead;  	static U32 sCacheBytesWritten;  	static U32 sPeakKbps; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 5d0d1ef9a3..6111255a66 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5556,38 +5556,37 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power)  //helper function for pushing relevant vertices from drawable to GL  void pushWireframe(LLDrawable* drawable)  { -	if (drawable->isState(LLDrawable::RIGGED)) -	{ //render straight from rigged volume if this is a rigged attachment -		LLVOVolume* vobj = drawable->getVOVolume(); -		if (vobj) -		{ -			vobj->updateRiggedVolume(); -			LLRiggedVolume* rigged_volume = vobj->getRiggedVolume(); -			if (rigged_volume) -			{ -				LLVertexBuffer::unbind(); -				gGL.pushMatrix(); -				gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); -				for (S32 i = 0; i < rigged_volume->getNumVolumeFaces(); ++i) -				{ -					const LLVolumeFace& face = rigged_volume->getVolumeFace(i); -					LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices); -				} -				gGL.popMatrix(); -			} -		} -	} -	else +	LLVOVolume* vobj = drawable->getVOVolume(); +	if (vobj)  	{ -		for (S32 i = 0; i < drawable->getNumFaces(); ++i) +		LLVertexBuffer::unbind(); +		gGL.pushMatrix(); +		gGL.multMatrix((F32*) vobj->getRelativeXform().mMatrix); + +		LLVolume* volume = NULL; + +		if (drawable->isState(LLDrawable::RIGGED)) +		{ +				vobj->updateRiggedVolume(); +				volume = vobj->getRiggedVolume(); +		} +		else +		{ +			volume = vobj->getVolume(); +		} + +		if (volume)  		{ -			LLFace* face = drawable->getFace(i); -			if (face->verify()) +			for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)  			{ -				pushVerts(face, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); +				const LLVolumeFace& face = volume->getVolumeFace(i); +				LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);  			}  		} + +		gGL.popMatrix();  	} +	  }  void LLSelectNode::renderOneWireframe(const LLColor4& color) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 900f126049..5d196a465f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -264,7 +264,7 @@ static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");  void LLSpatialGroup::buildOcclusion()  { -	if (mOcclusionVerts.isNull()) +	//if (mOcclusionVerts.isNull())  	{  		mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,   			LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling. @@ -726,7 +726,9 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)  	if (vertex_count > 0 && index_count > 0)  	{ //create vertex buffer containing volume geometry for this node  		group->mBuilt = 1.f; -		if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs)) +		if (group->mVertexBuffer.isNull() || +			!group->mVertexBuffer->isWriteable() || +			(group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))  		{  			group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);  			group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true); @@ -1185,6 +1187,8 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode)  LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :  	mState(0), +	mGeometryBytes(0), +	mSurfaceArea(0.f),  	mBuilt(0.f),  	mOctreeNode(node),  	mSpatialPartition(part), @@ -1410,6 +1414,17 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)  		}  	} +	//clean up avatar attachment stats +	LLSpatialBridge* bridge = mSpatialPartition->asBridge(); +	if (bridge) +	{ +		if (bridge->mAvatar.notNull()) +		{ +			bridge->mAvatar->mAttachmentGeometryBytes -= mGeometryBytes; +			bridge->mAvatar->mAttachmentSurfaceArea -= mSurfaceArea; +		} +	} +  	clearDrawMap();  	mVertexBuffer = NULL;  	mBufferMap.clear(); @@ -1765,7 +1780,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)  //==============================================  LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) -: mRenderByGroup(render_by_group) +: mRenderByGroup(render_by_group), mBridge(NULL)  {  	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);  	mOcclusionEnabled = TRUE; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 899547ae4d..6c14ecf452 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -405,6 +405,9 @@ public:  	bridge_list_t mBridgeList;  	buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers +	U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node +	F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node +  	F32 mBuilt;  	OctreeNode* mOctreeNode;  	LLSpatialPartition* mSpatialPartition; @@ -474,8 +477,8 @@ public:  	BOOL isVisible(const LLVector3& v);  	bool isHUDPartition() ; -	virtual LLSpatialBridge* asBridge() { return NULL; } -	virtual BOOL isBridge() { return asBridge() != NULL; } +	LLSpatialBridge* asBridge() { return mBridge; } +	BOOL isBridge() { return asBridge() != NULL; }  	void renderPhysicsShapes();  	void renderDebug(); @@ -487,6 +490,9 @@ public:  public:  	LLSpatialGroup::OctreeNode* mOctree; +	LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this +							// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe +							// to call asBridge() from the destructor  	BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed  	BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane  	U32 mBufferUsage; @@ -511,8 +517,9 @@ public:  	LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); -	virtual BOOL isSpatialBridge() const		{ return TRUE; } +	void destroyTree(); +	virtual BOOL isSpatialBridge() const		{ return TRUE; }  	virtual void updateSpatialExtents();  	virtual void updateBinRadius();  	virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE); @@ -523,11 +530,12 @@ public:  	virtual void shiftPos(const LLVector4a& vec);  	virtual void cleanupReferences();  	virtual LLSpatialPartition* asPartition()		{ return this; } -	virtual LLSpatialBridge* asBridge()				{ return this; } -	 +		  	virtual LLCamera transformCamera(LLCamera& camera);  	LLDrawable* mDrawable; +	LLPointer<LLVOAvatar> mAvatar; +  };  class LLCullResult  diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 67f6150dbe..99540ccce9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -947,6 +947,10 @@ U32 info_display_from_string(std::string info_display)  	{  		return LLPipeline::RENDER_DEBUG_COMPOSITION;  	} +	else if ("attachment bytes" == info_display) +	{ +		return LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES; +	}  	else if ("glow" == info_display)  	{  		return LLPipeline::RENDER_DEBUG_GLOW; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b8772971aa..37fb77a10a 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5520,11 +5520,12 @@ void LLViewerObject::dirtyMesh()  {  	if (mDrawable)  	{ -		LLSpatialGroup* group = mDrawable->getSpatialGroup(); +		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL); +		/*LLSpatialGroup* group = mDrawable->getSpatialGroup();  		if (group)  		{  			group->dirtyMesh(); -		} +		}*/  	}  } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 4499955dec..5f64dba100 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -613,7 +613,9 @@ public:  				addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,  					LLMeshRepository::sHTTPRetryCount)); -				 +				ypos += y_inc; + +				addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));  				ypos += y_inc;  				addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f))); @@ -1966,7 +1968,7 @@ void LLViewerWindow::shutdownViews()  	{  		gMorphView->setVisible(FALSE);  	} - +	  	// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open  	// will crump with LL_ERRS.  	LLModalDialog::shutdownModals(); @@ -1977,15 +1979,15 @@ void LLViewerWindow::shutdownViews()  	{  		delete LLNavigationBar::getInstance();  	} - +	  	// destroy menus after instantiating navbar above, as it needs  	// access to gMenuHolder  	cleanup_menus(); - +	  	// Delete all child views.  	delete mRootView;  	mRootView = NULL; - +	  	// Automatically deleted as children of mRootView.  Fix the globals.  	gStatusBar = NULL;  	gIMMgr = NULL; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 68637a7ed9..bc7f5a9744 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -651,6 +651,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	LLViewerObject(id, pcode, regionp),  	mIsDummy(FALSE),  	mSpecialRenderMode(0), +	mAttachmentGeometryBytes(0), +	mAttachmentSurfaceArea(0.f),  	mTurning(FALSE),  	mPelvisToFoot(0.f),  	mLastSkeletonSerialNum( 0 ), @@ -3363,6 +3365,16 @@ void LLVOAvatar::slamPosition()  	mRoot.updateWorldMatrixChildren();  } +bool LLVOAvatar::isVisuallyMuted() +{ +	static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit"); +	static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit"); +	 +	return LLMuteList::getInstance()->isMuted(getID()) || +			(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || +			(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f); +} +  //------------------------------------------------------------------------  // updateCharacter()  // called on both your avatar and other avatars @@ -3429,8 +3441,9 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  		size.setSub(ext[1],ext[0]);  		F32 mag = size.getLength3().getF32()*0.5f; +		  		F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); -		if (LLMuteList::getInstance()->isMuted(getID())) +		if (isVisuallyMuted())  		{ // muted avatars update at 16 hz  			mUpdatePeriod = 16;  		} @@ -8333,6 +8346,11 @@ void LLVOAvatar::idleUpdateRenderCost()  	static std::set<LLUUID> all_textures; +	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_ATTACHMENT_BYTES)) +	{ //set debug text to attachment geometry bytes here so render cost will override +		setDebugText(llformat("%.1f KB, %.2f m^2", mAttachmentGeometryBytes/1024.f, mAttachmentSurfaceArea)); +	} +  	if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))  	{  		return; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 59796370ae..4cd61cecf9 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -380,6 +380,8 @@ private:  public:  	U32 		renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); +	bool		isVisuallyMuted(); +  	U32 		renderRigid();  	U32 		renderSkinned(EAvatarRenderPass pass);  	F32			getLastSkinTime() { return mLastSkinTime; } @@ -391,6 +393,9 @@ public:  	static void	restoreGL();  	BOOL 		mIsDummy; // for special views  	S32			mSpecialRenderMode; // special lighting +	U32			mAttachmentGeometryBytes; //number of bytes in attached geometry +	F32			mAttachmentSurfaceArea; //estimated surface area of attachments +  private:  	bool		shouldAlphaMask(); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index c3a2e6a712..bf6158eeaf 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -65,7 +65,7 @@ public:  			return;  		} -		U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; +		volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;  		//assume tex coords 2 and 3 are present  		U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 20f8674655..7492a06784 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4097,6 +4097,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB); +	LLVOAvatar* pAvatarVO = NULL; + +	LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); +	if (bridge) +	{ +		if (bridge->mAvatar.isNull()) +		{ +			LLViewerObject* vobj = bridge->mDrawable->getVObj(); +			if (vobj) +			{ +				bridge->mAvatar = vobj->getAvatar(); +			} +		} + +		pAvatarVO = bridge->mAvatar; +	} + +	if (pAvatarVO) +	{ +		pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes; +		pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea; +	} + +	group->mGeometryBytes = 0; +	group->mSurfaceArea = 0; +	  	group->clearDrawMap();  	mFaceList.clear(); @@ -4133,12 +4159,24 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		LLVOVolume* vobj = drawablep->getVOVolume(); +		if (!vobj) +		{ +			continue; +		} +  		if (vobj->isMesh() &&  			(vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))  		{  			continue;  		} +		LLVolume* volume = vobj->getVolume(); +		if (volume) +		{ +			const LLVector3& scale = vobj->getScale(); +			group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]); +		} +  		llassert_always(vobj);  		vobj->updateTextureVirtualSize(true);  		vobj->preRebuild(); @@ -4183,7 +4221,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				//Determine if we've received skininfo that contains an  				//alternate bind matrix - if it does then apply the translational component  				//to the joints of the avatar. -				LLVOAvatar* pAvatarVO = vobj->getAvatar();  				bool pelvisGotSet = false;  				if ( pAvatarVO ) @@ -4253,13 +4290,16 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					if (type == LLDrawPool::POOL_ALPHA)  					{ -						if (te->getFullbright()) +						if (te->getColor().mV[3] > 0.f)  						{ -							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); -						} -						else -						{ -							pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); +							if (te->getFullbright()) +							{ +								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); +							} +							else +							{ +								pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); +							}  						}  					}  					else if (te->getShiny()) @@ -4392,8 +4432,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  					}  					else  					{ -						drawablep->setState(LLDrawable::HAS_ALPHA); -						alpha_faces.push_back(facep); +						if (te->getColor().mV[3] > 0.f) +						{ +							drawablep->setState(LLDrawable::HAS_ALPHA); +							alpha_faces.push_back(facep); +						}  					}  				}  				else @@ -4510,6 +4553,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	}  	mFaceList.clear(); + +	if (pAvatarVO) +	{ +		pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes; +		pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea; +	}  }  static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry"); @@ -4806,17 +4855,20 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		//create/delete/resize vertex buffer if needed  		LLVertexBuffer* buffer = NULL; -		LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter); + +		{ //try to find a buffer to reuse +			LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter); -		if (found_iter != group->mBufferMap[mask].end()) -		{ -			if ((U32) buffer_index < found_iter->second.size()) +			if (found_iter != group->mBufferMap[mask].end())  			{ -				buffer = found_iter->second[buffer_index]; +				if ((U32) buffer_index < found_iter->second.size()) +				{ +					buffer = found_iter->second[buffer_index]; +				}  			}  		} -		if (!buffer) +		if (!buffer || !buffer->isWriteable())  		{ //create new buffer if needed  			buffer = createVertexBuffer(mask, buffer_usage);  			buffer->allocateBuffer(geom_count, index_count, TRUE); @@ -4835,6 +4887,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			}  		} +		group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); + +  		buffer_map[mask][*face_iter].push_back(buffer);  		//add face geometry diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 7df50ec815..315616e8a5 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -167,7 +167,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)  				  indices_per_quad * num_quads);  	LLVertexBuffer* buff = face->getVertexBuffer(); -	if (!buff) +	if (!buff || !buff->isWriteable())  	{  		buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);  		buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index f1c5499d84..afd902201b 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -774,7 +774,7 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)  	LLStrider<LLColor4U> colorsp;  	LLStrider<LLVector2> texcoordsp; -	if (mStarsVerts.isNull()) +	if (mStarsVerts.isNull() || !mStarsVerts->isWriteable())  	{  		mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);  		mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 8449e74fb6..c523a78b22 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1217,10 +1217,12 @@ void LLPipeline::restoreGL()  BOOL LLPipeline::canUseVertexShaders()  { +	static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable"; +  	if (sDisableShaders ||  		!gGLManager.mHasVertexShader ||  		!gGLManager.mHasFragmentShader || -		!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") || +		!LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) ||  		(assertInitialized() && mVertexShadersLoaded != 1) )  	{  		return FALSE; @@ -3765,6 +3767,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)  	LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO");  	// Initialize lots of GL state to "safe" values +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);  	gGL.matrixMode(LLRender::MM_TEXTURE);  	gGL.loadIdentity();  	gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -5296,7 +5299,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			light_state->setConstantAttenuation(0.f);  			if (sRenderDeferred)  			{ -				light_state->setLinearAttenuation(light_radius*1.5f); +				F32 size = light_radius*1.5f; +				light_state->setLinearAttenuation(size*size);  				light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f);  			}  			else @@ -5318,7 +5322,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  				light_state->setSpotCutoff(90.f);  				light_state->setSpotExponent(2.f); -				light_state->setSpecular(LLColor4::black); +				const LLColor4 specular(0.f, 0.f, 0.f, 0.f); +				light_state->setSpecular(specular);  			}  			else // omnidirectional (point) light  			{ @@ -9419,7 +9424,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	assertInitialized(); -	BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID()); +	bool muted = avatar->isVisuallyMuted();		  	pushRenderTypeMask(); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 2815d736e4..9c78048c46 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -432,34 +432,35 @@ public:  	enum LLRenderDebugMask  	{ -		RENDER_DEBUG_COMPOSITION		= 0x0000001, -		RENDER_DEBUG_VERIFY				= 0x0000002, -		RENDER_DEBUG_BBOXES				= 0x0000004, -		RENDER_DEBUG_OCTREE				= 0x0000008, -		RENDER_DEBUG_WIND_VECTORS		= 0x0000010, -		RENDER_DEBUG_OCCLUSION			= 0x0000020, -		RENDER_DEBUG_POINTS				= 0x0000040, -		RENDER_DEBUG_TEXTURE_PRIORITY	= 0x0000080, -		RENDER_DEBUG_TEXTURE_AREA		= 0x0000100, -		RENDER_DEBUG_FACE_AREA			= 0x0000200, -		RENDER_DEBUG_PARTICLES			= 0x0000400, -		RENDER_DEBUG_GLOW				= 0x0000800, -		RENDER_DEBUG_TEXTURE_ANIM		= 0x0001000, -		RENDER_DEBUG_LIGHTS				= 0x0002000, -		RENDER_DEBUG_BATCH_SIZE			= 0x0004000, -		RENDER_DEBUG_ALPHA_BINS			= 0x0008000, -		RENDER_DEBUG_RAYCAST            = 0x0010000, -		RENDER_DEBUG_SHAME				= 0x0020000, -		RENDER_DEBUG_SHADOW_FRUSTA		= 0x0040000, -		RENDER_DEBUG_SCULPTED           = 0x0080000, -		RENDER_DEBUG_AVATAR_VOLUME      = 0x0100000, -		RENDER_DEBUG_BUILD_QUEUE		= 0x0200000, -		RENDER_DEBUG_AGENT_TARGET       = 0x0400000, -		RENDER_DEBUG_UPDATE_TYPE		= 0x0800000, -		RENDER_DEBUG_PHYSICS_SHAPES     = 0x1000000, -		RENDER_DEBUG_NORMALS	        = 0x2000000, -		RENDER_DEBUG_LOD_INFO	        = 0x4000000, -		RENDER_DEBUG_RENDER_COMPLEXITY  = 0x8000000 +		RENDER_DEBUG_COMPOSITION		= 0x00000001, +		RENDER_DEBUG_VERIFY				= 0x00000002, +		RENDER_DEBUG_BBOXES				= 0x00000004, +		RENDER_DEBUG_OCTREE				= 0x00000008, +		RENDER_DEBUG_WIND_VECTORS		= 0x00000010, +		RENDER_DEBUG_OCCLUSION			= 0x00000020, +		RENDER_DEBUG_POINTS				= 0x00000040, +		RENDER_DEBUG_TEXTURE_PRIORITY	= 0x00000080, +		RENDER_DEBUG_TEXTURE_AREA		= 0x00000100, +		RENDER_DEBUG_FACE_AREA			= 0x00000200, +		RENDER_DEBUG_PARTICLES			= 0x00000400, +		RENDER_DEBUG_GLOW				= 0x00000800, +		RENDER_DEBUG_TEXTURE_ANIM		= 0x00001000, +		RENDER_DEBUG_LIGHTS				= 0x00002000, +		RENDER_DEBUG_BATCH_SIZE			= 0x00004000, +		RENDER_DEBUG_ALPHA_BINS			= 0x00008000, +		RENDER_DEBUG_RAYCAST            = 0x00010000, +		RENDER_DEBUG_SHAME				= 0x00020000, +		RENDER_DEBUG_SHADOW_FRUSTA		= 0x00040000, +		RENDER_DEBUG_SCULPTED           = 0x00080000, +		RENDER_DEBUG_AVATAR_VOLUME      = 0x00100000, +		RENDER_DEBUG_BUILD_QUEUE		= 0x00200000, +		RENDER_DEBUG_AGENT_TARGET       = 0x00400000, +		RENDER_DEBUG_UPDATE_TYPE		= 0x00800000, +		RENDER_DEBUG_PHYSICS_SHAPES     = 0x01000000, +		RENDER_DEBUG_NORMALS	        = 0x02000000, +		RENDER_DEBUG_LOD_INFO	        = 0x04000000, +		RENDER_DEBUG_RENDER_COMPLEXITY  = 0x08000000, +		RENDER_DEBUG_ATTACHMENT_BYTES	= 0x10000000,  	};  public: diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 1f72984166..1d11abcf73 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2419,6 +2419,16 @@             function="Advanced.ToggleInfoDisplay"             parameter="rendercomplexity" />          </menu_item_check> +        <menu_item_check +         label="Attachment Bytes" +         name="attachment bytes"> +          <menu_item_check.on_check +           function="Advanced.CheckInfoDisplay" +           parameter="attachment bytes" /> +          <menu_item_check.on_click +           function="Advanced.ToggleInfoDisplay" +           parameter="attachment bytes" /> +        </menu_item_check>  		<menu_item_check           label="Sculpt"           name="Sculpt"> | 
