diff options
| author | graham linden <graham@lindenlab.com> | 2013-03-05 13:42:57 -0800 | 
|---|---|---|
| committer | graham linden <graham@lindenlab.com> | 2013-03-05 13:42:57 -0800 | 
| commit | 046014aa10e535bfa18e3d7b4c2da70284a615ae (patch) | |
| tree | a2ddc78c2da49f22ae6c11195b0fbc5c27e32e5b /indra | |
| parent | b19eeabd54afcfb56e864899c166b64db1ac6790 (diff) | |
| parent | a65c275865f1cc9bf53237e4b8c99a7bee3731ee (diff) | |
Merged lindenlab/viewer-cat into default
Diffstat (limited to 'indra')
37 files changed, 1623 insertions, 1557 deletions
| diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index e725bdd9fa..46cabfadcd 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -38,17 +38,28 @@ class LLMutex ;  inline void* ll_aligned_malloc( size_t size, int align )  { +#if defined(LL_WINDOWS) +	return _aligned_malloc(size, align); +#else  	void* mem = malloc( size + (align - 1) + sizeof(void*) );  	char* aligned = ((char*)mem) + sizeof(void*);  	aligned += align - ((uintptr_t)aligned & (align - 1));  	((void**)aligned)[-1] = mem;  	return aligned; +#endif  }  inline void ll_aligned_free( void* ptr )  { -	free( ((void**)ptr)[-1] ); +#if defined(LL_WINDOWS) +	_aligned_free(ptr); +#else +	if (ptr) +	{ +		free( ((void**)ptr)[-1] ); +	} +#endif  }  #if !LL_USE_TCMALLOC diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 02c8d2b86f..f989e8ed17 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5180,6 +5180,7 @@ LLVolumeFace::LLVolumeFace() :  	mNumS(0),  	mNumT(0),  	mNumVertices(0), +	mNumAllocatedVertices(0),  	mNumIndices(0),  	mPositions(NULL),  	mNormals(NULL), @@ -5187,7 +5188,8 @@ LLVolumeFace::LLVolumeFace() :  	mTexCoords(NULL),  	mIndices(NULL),  	mWeights(NULL), -	mOctree(NULL) +	mOctree(NULL), +	mOptimized(FALSE)  {  	mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);  	mExtents[0].splat(-0.5f); @@ -5203,6 +5205,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)  	mNumS(0),  	mNumT(0),  	mNumVertices(0), +	mNumAllocatedVertices(0),  	mNumIndices(0),  	mPositions(NULL),  	mNormals(NULL), @@ -5257,12 +5260,6 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		{  			LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) src.mTexCoords, tc_size);  		} -		else -		{ -			ll_aligned_free_16(mTexCoords) ; -			mTexCoords = NULL ; -		} -  		if (src.mBinormals)  		{ @@ -5294,6 +5291,8 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  		LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size);  	} +	mOptimized = src.mOptimized; +  	//delete   	return *this;  } @@ -5310,10 +5309,11 @@ void LLVolumeFace::freeData()  {  	ll_aligned_free_16(mPositions);  	mPositions = NULL; -	ll_aligned_free_16( mNormals); + +	//normals and texture coordinates are part of the same buffer as mPositions, do not free them separately  	mNormals = NULL; -	ll_aligned_free_16(mTexCoords);  	mTexCoords = NULL; +  	ll_aligned_free_16(mIndices);  	mIndices = NULL;  	ll_aligned_free_16(mBinormals); @@ -5495,18 +5495,6 @@ void LLVolumeFace::optimize(F32 angle_cutoff)  	llassert(new_face.mNumIndices == mNumIndices);  	llassert(new_face.mNumVertices <= mNumVertices); -	if (angle_cutoff > 1.f && !mNormals) -	{ -		ll_aligned_free_16(new_face.mNormals); -		new_face.mNormals = NULL; -	} - -	if (!mTexCoords) -	{ -		ll_aligned_free_16(new_face.mTexCoords); -		new_face.mTexCoords = NULL; -	} -  	swapData(new_face);  } @@ -5517,14 +5505,14 @@ class LLVCacheVertexData  public:  	S32 mIdx;  	S32 mCacheTag; -	F32 mScore; +	F64 mScore;  	U32 mActiveTriangles;  	std::vector<LLVCacheTriangleData*> mTriangles;  	LLVCacheVertexData()  	{  		mCacheTag = -1; -		mScore = 0.f; +		mScore = 0.0;  		mActiveTriangles = 0;  		mIdx = -1;  	} @@ -5534,13 +5522,13 @@ class LLVCacheTriangleData  {  public:  	bool mActive; -	F32 mScore; +	F64 mScore;  	LLVCacheVertexData* mVertex[3];  	LLVCacheTriangleData()  	{  		mActive = true; -		mScore = 0.f; +		mScore = 0.0;  		mVertex[0] = mVertex[1] = mVertex[2] = NULL;  	} @@ -5551,7 +5539,7 @@ public:  		{  			if (mVertex[i])  			{ -				llassert_always(mVertex[i]->mActiveTriangles > 0); +				llassert(mVertex[i]->mActiveTriangles > 0);  				mVertex[i]->mActiveTriangles--;  			}  		} @@ -5563,44 +5551,44 @@ public:  	}  }; -const F32 FindVertexScore_CacheDecayPower = 1.5f; -const F32 FindVertexScore_LastTriScore = 0.75f; -const F32 FindVertexScore_ValenceBoostScale = 2.0f; -const F32 FindVertexScore_ValenceBoostPower = 0.5f; +const F64 FindVertexScore_CacheDecayPower = 1.5; +const F64 FindVertexScore_LastTriScore = 0.75; +const F64 FindVertexScore_ValenceBoostScale = 2.0; +const F64 FindVertexScore_ValenceBoostPower = 0.5;  const U32 MaxSizeVertexCache = 32; +const F64 FindVertexScore_Scaler = 1.0/(MaxSizeVertexCache-3); -F32 find_vertex_score(LLVCacheVertexData& data) +F64 find_vertex_score(LLVCacheVertexData& data)  { -	if (data.mActiveTriangles == 0) -	{ //no triangle references this vertex -		return -1.f; -	} +	F64 score = -1.0; -	F32 score = 0.f; - -	S32 cache_idx = data.mCacheTag; +	if (data.mActiveTriangles >= 0) +	{  +		score = 0.0; +		 +		S32 cache_idx = data.mCacheTag; -	if (cache_idx < 0) -	{ -		//not in cache -	} -	else -	{ -		if (cache_idx < 3) -		{ //vertex was in the last triangle -			score = FindVertexScore_LastTriScore; +		if (cache_idx < 0) +		{ +			//not in cache  		}  		else -		{ //more points for being higher in the cache -			F32 scaler = 1.f/(MaxSizeVertexCache-3); -			score = 1.f-((cache_idx-3)*scaler); -			score = powf(score, FindVertexScore_CacheDecayPower); +		{ +			if (cache_idx < 3) +			{ //vertex was in the last triangle +				score = FindVertexScore_LastTriScore; +			} +			else +			{ //more points for being higher in the cache +				score = 1.0-((cache_idx-3)*FindVertexScore_Scaler); +				score = pow(score, FindVertexScore_CacheDecayPower); +			}  		} -	} -	//bonus points for having low valence -	F32 valence_boost = powf((F32)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower); -	score += FindVertexScore_ValenceBoostScale * valence_boost; +		//bonus points for having low valence +		F64 valence_boost = pow((F64)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower); +		score += FindVertexScore_ValenceBoostScale * valence_boost; +	}  	return score;  } @@ -5707,32 +5695,44 @@ public:  	void updateScores()  	{ -		for (U32 i = MaxSizeVertexCache; i < MaxSizeVertexCache+3; ++i) -		{ //trailing 3 vertices aren't actually in the cache for scoring purposes -			if (mCache[i]) +		LLVCacheVertexData** data_iter = mCache+MaxSizeVertexCache; +		LLVCacheVertexData** end_data = mCache+MaxSizeVertexCache+3; + +		while(data_iter != end_data) +		{ +			LLVCacheVertexData* data = *data_iter++; +			//trailing 3 vertices aren't actually in the cache for scoring purposes +			if (data)  			{ -				mCache[i]->mCacheTag = -1; +				data->mCacheTag = -1;  			}  		} -		for (U32 i = 0; i < MaxSizeVertexCache; ++i) +		data_iter = mCache; +		end_data = mCache+MaxSizeVertexCache; + +		while (data_iter != end_data)  		{ //update scores of vertices in cache -			if (mCache[i]) +			LLVCacheVertexData* data = *data_iter++; +			if (data)  			{ -				mCache[i]->mScore = find_vertex_score(*(mCache[i])); -				llassert_always(mCache[i]->mCacheTag == i); +				data->mScore = find_vertex_score(*data);  			}  		}  		mBestTriangle = NULL;  		//update triangle scores -		for (U32 i = 0; i < MaxSizeVertexCache+3; ++i) +		data_iter = mCache; +		end_data = mCache+MaxSizeVertexCache+3; + +		while (data_iter != end_data)  		{ -			if (mCache[i]) +			LLVCacheVertexData* data = *data_iter++; +			if (data)  			{ -				for (U32 j = 0; j < mCache[i]->mTriangles.size(); ++j) +				for (std::vector<LLVCacheTriangleData*>::iterator iter = data->mTriangles.begin(), end_iter = data->mTriangles.end(); iter != end_iter; ++iter)  				{ -					LLVCacheTriangleData* tri = mCache[i]->mTriangles[j]; +					LLVCacheTriangleData* tri = *iter;  					if (tri->mActive)  					{  						tri->mScore = tri->mVertex[0]->mScore; @@ -5749,13 +5749,17 @@ public:  		}  		//knock trailing 3 vertices off the cache -		for (U32 i = MaxSizeVertexCache; i < MaxSizeVertexCache+3; ++i) +		data_iter = mCache+MaxSizeVertexCache; +		end_data = mCache+MaxSizeVertexCache+3; +		while (data_iter != end_data)  		{ -			if (mCache[i]) +			LLVCacheVertexData* data = *data_iter; +			if (data)  			{ -				llassert_always(mCache[i]->mCacheTag == -1); -				mCache[i] = NULL; +				llassert(data->mCacheTag == -1); +				*data_iter = NULL;  			} +			++data_iter;  		}  	}  }; @@ -5765,6 +5769,9 @@ void LLVolumeFace::cacheOptimize()  { //optimize for vertex cache according to Forsyth method:     // http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html +	llassert(!mOptimized); +	mOptimized = TRUE; +  	LLVCacheLRU cache;  	if (mNumVertices < 3) @@ -5810,12 +5817,14 @@ void LLVolumeFace::cacheOptimize()  	for (U32 i = 0; i < mNumVertices; i++)  	{ //initialize score values (no cache -- might try a fifo cache here) -		vertex_data[i].mScore = find_vertex_score(vertex_data[i]); -		vertex_data[i].mActiveTriangles = vertex_data[i].mTriangles.size(); +		LLVCacheVertexData& data = vertex_data[i]; -		for (U32 j = 0; j < vertex_data[i].mTriangles.size(); ++j) +		data.mScore = find_vertex_score(data); +		data.mActiveTriangles = data.mTriangles.size(); + +		for (U32 j = 0; j < data.mActiveTriangles; ++j)  		{ -			vertex_data[i].mTriangles[j]->mScore += vertex_data[i].mScore; +			data.mTriangles[j]->mScore += data.mScore;  		}  	} @@ -5885,10 +5894,10 @@ void LLVolumeFace::cacheOptimize()  	//allocate space for new buffer  	S32 num_verts = mNumVertices; -	LLVector4a* pos = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); -	LLVector4a* norm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);  	S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; -	LLVector2* tc = (LLVector2*) ll_aligned_malloc_16(size); +	LLVector4a* pos = (LLVector4a*) ll_aligned_malloc(sizeof(LLVector4a)*2*num_verts+size, 64); +	LLVector4a* norm = pos + num_verts; +	LLVector2* tc = (LLVector2*) (norm + num_verts);  	LLVector4a* wght = NULL;  	if (mWeights) @@ -5936,9 +5945,8 @@ void LLVolumeFace::cacheOptimize()  		mIndices[i] = new_idx[mIndices[i]];  	} -	ll_aligned_free_16(mPositions); -	ll_aligned_free_16(mNormals); -	ll_aligned_free_16(mTexCoords); +	ll_aligned_free(mPositions); +	// DO NOT free mNormals and mTexCoords as they are part of mPositions buffer  	ll_aligned_free_16(mWeights);  	ll_aligned_free_16(mBinormals); @@ -6655,24 +6663,22 @@ void LLVolumeFace::createBinormals()  void LLVolumeFace::resizeVertices(S32 num_verts)  { -	ll_aligned_free_16(mPositions); -	ll_aligned_free_16(mNormals); +	ll_aligned_free(mPositions); +	//DO NOT free mNormals and mTexCoords as they are part of mPositions buffer  	ll_aligned_free_16(mBinormals); -	ll_aligned_free_16(mTexCoords); - +	  	mBinormals = NULL;  	if (num_verts)  	{ -		mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); -		ll_assert_aligned(mPositions, 16); -		mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); -		ll_assert_aligned(mNormals, 16); -  		//pad texture coordinate block end to allow for QWORD reads  		S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; -		mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); -		ll_assert_aligned(mTexCoords, 16); + +		mPositions = (LLVector4a*) ll_aligned_malloc(sizeof(LLVector4a)*2*num_verts+size, 64); +		mNormals = mPositions+num_verts; +		mTexCoords = (LLVector2*) (mNormals+num_verts); + +		ll_assert_aligned(mPositions, 64);  	}  	else  	{ @@ -6682,6 +6688,7 @@ void LLVolumeFace::resizeVertices(S32 num_verts)  	}  	mNumVertices = num_verts; +	mNumAllocatedVertices = num_verts;  }  void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv) @@ -6692,27 +6699,43 @@ void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv)  void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, const LLVector2& tc)  {  	S32 new_verts = mNumVertices+1; -	S32 new_size = new_verts*16; -	S32 old_size = mNumVertices*16; -	//positions -	mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size, old_size); -	ll_assert_aligned(mPositions,16); +	if (new_verts > mNumAllocatedVertices) +	{  +		//double buffer size on expansion +		new_verts *= 2; + +		S32 new_tc_size = ((new_verts*8)+0xF) & ~0xF; +		S32 old_tc_size = ((mNumVertices*8)+0xF) & ~0xF; + +		S32 old_vsize = mNumVertices*16; +		 +		S32 new_size = new_verts*16*2+new_tc_size; + +		LLVector4a* old_buf = mPositions; + +		mPositions = (LLVector4a*) ll_aligned_malloc(new_size, 64); +		mNormals = mPositions+new_verts; +		mTexCoords = (LLVector2*) (mNormals+new_verts); + +		//positions +		LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize); +		 +		//normals +		LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize); -	//normals -	mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size, old_size); -	ll_assert_aligned(mNormals,16); - -	//tex coords -	new_size = ((new_verts*8)+0xF) & ~0xF; -	old_size = ((mNumVertices*8)+0xF) & ~0xF; -	mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size, old_size); -	ll_assert_aligned(mTexCoords,16); +		//tex coords +		LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tc_size); +		//just clear binormals +		ll_aligned_free_16(mBinormals); -	//just clear binormals -	ll_aligned_free_16(mBinormals); -	mBinormals = NULL; +		ll_aligned_free(old_buf); + +		mNumAllocatedVertices = new_verts; + +		mBinormals = NULL; +	}  	mPositions[mNumVertices] = pos;  	mNormals[mNumVertices] = norm; @@ -6801,13 +6824,23 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat  		llerrs << "Cannot append empty face." << llendl;  	} +	U32 old_vsize = mNumVertices*16; +	U32 new_vsize = new_count * 16; +	U32 old_tcsize = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF; +	U32 new_tcsize = (new_count*sizeof(LLVector2)+0xF) & ~0xF; +	U32 new_size = new_vsize * 2 + new_tcsize; +  	//allocate new buffer space -	mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a)); -	ll_assert_aligned(mPositions, 16); -	mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a)); -	ll_assert_aligned(mNormals, 16); -	mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF, (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF); -	ll_assert_aligned(mTexCoords, 16); +	LLVector4a* old_buf = mPositions; +	mPositions = (LLVector4a*) ll_aligned_malloc(new_size, 64); +	mNormals = mPositions + new_count; +	mTexCoords = (LLVector2*) (mNormals+new_count); + +	mNumAllocatedVertices = new_count; + +	LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize); +	LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize); +	LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tcsize);  	mNumVertices = new_count; @@ -6903,12 +6936,15 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	LLVector4a* pos = (LLVector4a*) mPositions;  	LLVector4a* norm = (LLVector4a*) mNormals;  	LLVector2* tc = (LLVector2*) mTexCoords; -	S32 begin_stex = llfloor( profile[mBeginS].mV[2] ); +	F32 begin_stex = floorf(profile[mBeginS].mV[2]);  	S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS;  	S32 cur_vertex = 0; +	S32 end_t = mBeginT+mNumT; +	bool test = (mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2; +  	// Copy the vertices into the array -	for (t = mBeginT; t < mBeginT + mNumT; t++) +	for (t = mBeginT; t < end_t; t++)  	{  		tt = path_data[t].mTexT;  		for (s = 0; s < num_s; s++) @@ -6959,9 +6995,8 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  			norm[cur_vertex].clear();  			cur_vertex++; -			if ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2 && s > 0) +			if (test && s > 0)  			{ -  				pos[cur_vertex].load3(mesh[i].mPos.mV);  				tc[cur_vertex] = LLVector2(ss,tt); @@ -7076,30 +7111,38 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	}  	//generate normals  -	for (U32 i = 0; i < mNumIndices/3; i++) //for each triangle +	U32 count = mNumIndices/3; + +	for (U32 i = 0; i < count; i++) //for each triangle  	{  		const U16* idx = &(mIndices[i*3]); - -		LLVector4a* v[] =  -		{	pos+idx[0], pos+idx[1], pos+idx[2] }; +		LLVector4a& v0 = *(pos+idx[0]); +		LLVector4a& v1 = *(pos+idx[1]); +		LLVector4a& v2 = *(pos+idx[2]); -		LLVector4a* n[] =  -		{	norm+idx[0], norm+idx[1], norm+idx[2] }; +		LLVector4a& n0 = *(norm+idx[0]); +		LLVector4a& n1 = *(norm+idx[1]); +		LLVector4a& n2 = *(norm+idx[2]);  		//calculate triangle normal  		LLVector4a a, b, c; -		a.setSub(*v[0], *v[1]); -		b.setSub(*v[0], *v[2]); +		a.setSub(v0, v1); +		b.setSub(v0, v2);  		c.setCross3(a,b); -		n[0]->add(c); -		n[1]->add(c); -		n[2]->add(c); +		n0.add(c); +		n1.add(c); +		n2.add(c);  		//even out quad contributions -		n[i%2+1]->add(c); +		switch (i%2+1) +		{ +			case 0: n0.add(c); break; +			case 1: n1.add(c); break; +			case 2: n2.add(c); break; +		};  	}  	// adjust normals based on wrapping and stitching diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c845556557..1d3b0fe52f 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -912,6 +912,7 @@ public:  	LLVector2   mTexCoordExtents[2]; //minimum and maximum of texture coordinates of the face.  	S32 mNumVertices; +	S32 mNumAllocatedVertices;  	S32 mNumIndices;  	LLVector4a* mPositions; @@ -933,6 +934,9 @@ public:  	LLOctreeNode<LLVolumeTriangle>* mOctree; +	//whether or not face has been cache optimized +	BOOL mOptimized; +  private:  	BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);  	BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 9d06dd6904..58bd346c15 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -59,6 +59,7 @@ BOOL gDebugGL = FALSE;  BOOL gClothRipple = FALSE;  BOOL gHeadlessClient = FALSE;  BOOL gGLActive = FALSE; +BOOL gGLDebugLoggingEnabled = TRUE;  static const std::string HEADLESS_VENDOR_STRING("Linden Lab");  static const std::string HEADLESS_RENDERER_STRING("Headless"); @@ -72,6 +73,7 @@ std::ofstream gFailLog;  #define APIENTRY  #endif +  void APIENTRY gl_debug_callback(GLenum source,                                  GLenum type,                                  GLuint id, @@ -80,22 +82,25 @@ void APIENTRY gl_debug_callback(GLenum source,                                  const GLchar* message,                                  GLvoid* userParam)  { -	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) -	{ -		llwarns << "----- GL ERROR --------" << llendl; -	} -	else +	if (gGLDebugLoggingEnabled)  	{ -		llwarns << "----- GL WARNING -------" << llendl; -	} -	llwarns << "Type: " << std::hex << type << llendl; -	llwarns << "ID: " << std::hex << id << llendl; -	llwarns << "Severity: " << std::hex << severity << llendl; -	llwarns << "Message: " << message << llendl; -	llwarns << "-----------------------" << llendl; -	if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) -	{ -		llerrs << "Halting on GL Error" << llendl; +		if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) +		{ +			llwarns << "----- GL ERROR --------" << llendl; +		} +		else +		{ +			llwarns << "----- GL WARNING -------" << llendl; +		} +		llwarns << "Type: " << std::hex << type << llendl; +		llwarns << "ID: " << std::hex << id << llendl; +		llwarns << "Severity: " << std::hex << severity << llendl; +		llwarns << "Message: " << message << llendl; +		llwarns << "-----------------------" << llendl; +		if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) +		{ +			llerrs << "Halting on GL Error" << llendl; +		}  	}  }  #endif @@ -253,6 +258,7 @@ PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL;  PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL;  PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL;  PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL; +PFNGLBINDBUFFERBASEPROC glBindBufferBase = NULL;  //GL_ARB_debug_output  PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL; @@ -735,7 +741,7 @@ bool LLGLManager::initGL()  #if LL_WINDOWS  	if (mHasDebugOutput && gDebugGL)  	{ //setup debug output callback -		//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE); +		glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);  		glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);  		glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);  	} @@ -1224,6 +1230,7 @@ void LLGLManager::initExtensions()  		glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");  		glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");  		glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange"); +		glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferBase");  	}  	if (mHasDebugOutput)  	{ @@ -1471,7 +1478,7 @@ void do_assert_glerror()  void assert_glerror()  { -	if (!gGLActive) +/*	if (!gGLActive)  	{  		//llwarns << "GL used while not active!" << llendl; @@ -1480,8 +1487,13 @@ void assert_glerror()  			//ll_fail("GL used while not active");  		}  	} +*/ -	if (gDebugGL)  +	if (!gDebugGL)  +	{ +		//funny looking if for branch prediction -- gDebugGL is almost always false and assert_glerror is called often +	} +	else  	{  		do_assert_glerror();  	} diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 509de51f4d..a92ed428da 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -533,6 +533,7 @@ extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;  extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;  extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;  extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; +extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;  #elif LL_WINDOWS @@ -771,6 +772,7 @@ extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;  extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;  extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;  extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; +extern PFNGLBINDBUFFERBASEPROC glBindBufferBase;  //GL_ARB_debug_output  extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index a4d7872ec2..ef2648ae98 100755 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -709,9 +709,12 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  					mMipLevels = wpo2(llmax(w, h)); -					//use legacy mipmap generation mode -					glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); -					 +					if (!gGLManager.mHasFramebufferObject) +					{ +						//use legacy mipmap generation mode +						glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE); +					} +										  					LLImageGL::setManualImage(mTarget, 0, mFormatInternal,  								 w, h,   								 mFormatPrimary, mFormatType, @@ -726,6 +729,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  						glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);  						stop_glerror();  					} + +					if (gGLManager.mHasFramebufferObject) +					{ +						glGenerateMipmap(mTarget); +					}  				}  			}  			else @@ -1057,6 +1065,16 @@ void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 n  {  	bool empty = true; +	if (LLRender::sGLCoreProfile) +	{ +		switch (format) +		{ +			case GL_LUMINANCE8: format = GL_RGB8; break; +			case GL_LUMINANCE8_ALPHA8: +			case GL_ALPHA8: format = GL_RGBA8; break; +		} +	} +  	dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);  	if (iter != sDeadTextureList[type].end()) @@ -1084,6 +1102,16 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip  {  	if (gGLManager.mInited)  	{ +		if (LLRender::sGLCoreProfile) +		{ +			switch (format) +			{ +				case GL_LUMINANCE8: format = GL_RGB8; break; +				case GL_LUMINANCE8_ALPHA8: +				case GL_ALPHA8: format = GL_RGBA8; break; +			} +		} +  		if (format == 0 ||  type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)  		{ //unknown internal format or unknown number of mip levels, not safe to reuse  			glDeleteTextures(numTextures, textures); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index a12e9caf4c..14962fe58e 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -225,26 +225,15 @@ void LLTexUnit::disable(void)  bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)  {  	stop_glerror(); -	if (mIndex < 0) return false; - +	if (mIndex >= 0) +	{  	gGL.flush();  	LLImageGL* gl_tex = NULL ; -	if (texture == NULL || !(gl_tex = texture->getGLTexture())) +		if (texture != NULL && (gl_tex = texture->getGLTexture()))  	{ -		llwarns << "NULL LLTexUnit::bind texture" << llendl; -		return false; -	} - -	if (!gl_tex->getTexName()) //if texture does not exist +			if (gl_tex->getTexName()) //if texture exists  	{ -		//if deleted, will re-generate it immediately -		texture->forceImmediateUpdate() ; - -		gl_tex->forceUpdateBindStats() ; -		return texture->bindDefaultImage(mIndex); -	} -  	//in audit, replace the selected texture by the default one.  	if ((mCurrTexture != gl_tex->getTexName()) || forceBind)  	{ @@ -265,6 +254,27 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)  			setTextureFilteringOption(gl_tex->mFilterOption);  		}  	} +			} +			else +			{ +				//if deleted, will re-generate it immediately +				texture->forceImmediateUpdate() ; + +				gl_tex->forceUpdateBindStats() ; +				return texture->bindDefaultImage(mIndex); +			} +		} +		else +		{ +			llwarns << "NULL LLTexUnit::bind texture" << llendl; +			return false; +		} +	} +	else +	{ // mIndex < 0 +		return false; +	} +  	return true;  } @@ -1060,6 +1070,16 @@ LLRender::~LLRender()  void LLRender::init()  { +	if (sGLCoreProfile && !LLVertexBuffer::sUseVAO) +	{ //bind a dummy vertex array object so we're core profile compliant +#ifdef GL_ARB_vertex_array_object +		U32 ret; +		glGenVertexArrays(1, &ret); +		glBindVertexArray(ret); +#endif +	} + +  	llassert_always(mBuffer.isNull()) ;  	stop_glerror();  	mBuffer = new LLVertexBuffer(immediate_mask, 0); diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b6a9a6b653..825f80a6dc 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -974,7 +974,9 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("texture_matrix1");  	mReservedUniforms.push_back("texture_matrix2");  	mReservedUniforms.push_back("texture_matrix3"); -	llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1); +	mReservedUniforms.push_back("object_plane_s"); +	mReservedUniforms.push_back("object_plane_t"); +	llassert(mReservedUniforms.size() == LLShaderMgr::OBJECT_PLANE_T+1);  	mReservedUniforms.push_back("viewport"); @@ -1116,6 +1118,48 @@ void LLShaderMgr::initAttribsAndUniforms()  	mReservedUniforms.push_back("bloomMap");  	mReservedUniforms.push_back("projectionMap"); +	mReservedUniforms.push_back("matrixPalette"); +	 +	 +	mReservedUniforms.reserve(12); +	mReservedUniforms.push_back("screenTex"); +	mReservedUniforms.push_back("screenDepth"); +	mReservedUniforms.push_back("refTex"); +	mReservedUniforms.push_back("eyeVec"); +	mReservedUniforms.push_back("time"); +	mReservedUniforms.push_back("d1"); +	mReservedUniforms.push_back("d2"); +	mReservedUniforms.push_back("lightDir"); +	mReservedUniforms.push_back("specular"); +	mReservedUniforms.push_back("lightExp"); +	mReservedUniforms.push_back("waterFogColor"); +	mReservedUniforms.push_back("waterFogDensity"); +	mReservedUniforms.push_back("waterFogKS"); +	mReservedUniforms.push_back("refScale"); +	mReservedUniforms.push_back("waterHeight"); +	mReservedUniforms.push_back("waterPlane"); +	mReservedUniforms.push_back("normScale"); +	mReservedUniforms.push_back("fresnelScale"); +	mReservedUniforms.push_back("fresnelOffset"); +	mReservedUniforms.push_back("blurMultiplier"); +	mReservedUniforms.push_back("sunAngle"); +	mReservedUniforms.push_back("scaledAngle"); +	mReservedUniforms.push_back("sunAngle2"); +	 +	mReservedUniforms.push_back("camPosLocal"); + +	mReservedUniforms.push_back("gWindDir"); +	mReservedUniforms.push_back("gSinWaveParams"); +	mReservedUniforms.push_back("gGravity"); + +	mReservedUniforms.push_back("detail_0"); +	mReservedUniforms.push_back("detail_1"); +	mReservedUniforms.push_back("detail_2"); +	mReservedUniforms.push_back("detail_3"); +	mReservedUniforms.push_back("alpha_ramp"); + +	mReservedUniforms.push_back("origin"); +  	llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);  	std::set<std::string> dupe_check; diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 7a16b7c20f..77e90372e0 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -47,6 +47,8 @@ public:  		TEXTURE_MATRIX1,  		TEXTURE_MATRIX2,  		TEXTURE_MATRIX3, +		OBJECT_PLANE_S, +		OBJECT_PLANE_T,  		VIEWPORT,  		LIGHT_POSITION,  		LIGHT_DIRECTION, @@ -164,7 +166,49 @@ public:  		DEFERRED_LIGHT,  		DEFERRED_BLOOM,  		DEFERRED_PROJECTION, +		 +		AVATAR_MATRIX, + +		WATER_SCREENTEX, +		WATER_SCREENDEPTH, +		WATER_REFTEX, +		WATER_EYEVEC, +		WATER_TIME, +		WATER_WAVE_DIR1, +		WATER_WAVE_DIR2, +		WATER_LIGHT_DIR, +		WATER_SPECULAR, +		WATER_SPECULAR_EXP, +		WATER_FOGCOLOR, +		WATER_FOGDENSITY, +		WATER_FOGKS, +		WATER_REFSCALE, +		WATER_WATERHEIGHT, +		WATER_WATERPLANE, +		WATER_NORM_SCALE, +		WATER_FRESNEL_SCALE, +		WATER_FRESNEL_OFFSET, +		WATER_BLUR_MULTIPLIER, +		WATER_SUN_ANGLE, +		WATER_SCALED_ANGLE, +		WATER_SUN_ANGLE2, +		 +		WL_CAMPOSLOCAL, + +		AVATAR_WIND, +		AVATAR_SINWAVE, +		AVATAR_GRAVITY, + +		TERRAIN_DETAIL0, +		TERRAIN_DETAIL1, +		TERRAIN_DETAIL2, +		TERRAIN_DETAIL3, +		TERRAIN_ALPHARAMP, +		 +		SHINY_ORIGIN, +  		END_RESERVED_UNIFORMS +  	} eGLSLReservedUniforms;  	// singleton pattern implementation diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index dfbd8cd4ee..1d257d8415 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -85,6 +85,7 @@ const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);  //static  LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB);  LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB); +LLVBOPool LLVertexBuffer::sDynamicCopyVBOPool(GL_DYNAMIC_COPY_ARB, GL_ARRAY_BUFFER_ARB);  LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);  LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB); @@ -199,7 +200,10 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)  		if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)  		{  			glBufferDataARB(mType, size, 0, mUsage); -			ret = (U8*) ll_aligned_malloc_16(size); +			if (mUsage != GL_DYNAMIC_COPY_ARB) +			{ //data will be provided by application +				ret = (U8*) ll_aligned_malloc(size, 64); +			}  		}  		else  		{ //always use a true hint of static draw when allocating non-client-backed buffers @@ -252,7 +256,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)  	llassert(vbo_block_size(size) == size);  	deleteBuffer(name); -	ll_aligned_free_16((U8*) buffer); +	ll_aligned_free((U8*) buffer);  	if (mType == GL_ARRAY_BUFFER_ARB)  	{ @@ -393,6 +397,7 @@ void LLVertexBuffer::seedPools()  {  	sStreamVBOPool.seedPool();  	sDynamicVBOPool.seedPool(); +	sDynamicCopyVBOPool.seedPool();  	sStreamIBOPool.seedPool();  	sDynamicIBOPool.seedPool();  } @@ -875,6 +880,7 @@ void LLVertexBuffer::cleanupClass()  	sDynamicIBOPool.cleanup();  	sStreamVBOPool.cleanup();  	sDynamicVBOPool.cleanup(); +	sDynamicCopyVBOPool.cleanup();  	if(sPrivatePoolp)  	{ @@ -911,13 +917,16 @@ S32 LLVertexBuffer::determineUsage(S32 usage)  	if (ret_usage && ret_usage != GL_STREAM_DRAW_ARB)  	{ //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default -		if (sDisableVBOMapping) -		{ //always use stream draw if VBO mapping is disabled -			ret_usage = GL_STREAM_DRAW_ARB; -		} -		else +		if (ret_usage != GL_DYNAMIC_COPY_ARB)  		{ -			ret_usage = GL_DYNAMIC_DRAW_ARB; +			if (sDisableVBOMapping) +			{ //always use stream draw if VBO mapping is disabled +				ret_usage = GL_STREAM_DRAW_ARB; +			} +			else +			{ +				ret_usage = GL_DYNAMIC_DRAW_ARB; +			}  		}  	} @@ -1067,10 +1076,15 @@ void LLVertexBuffer::genBuffer(U32 size)  	{  		mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize);  	} -	else +	else if (mUsage == GL_DYNAMIC_DRAW_ARB)  	{  		mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize);  	} +	else +	{ +		mMappedData = sDynamicCopyVBOPool.allocate(mGLBuffer, mSize); +	} +  	sGLCount++;  } @@ -1284,7 +1298,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)  		//actually allocate space for the vertex buffer if using VBO mapping  		flush(); -		if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO)) +		if (gGLManager.mHasVertexArrayObject && useVBOs() && (sUseVAO))  		{  #if GL_ARB_vertex_array_object  			mGLArray = getVAOName(); @@ -1440,21 +1454,18 @@ bool LLVertexBuffer::useVBOs() const  //---------------------------------------------------------------------------- -bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count) +bool expand_region(LLVertexBuffer::MappedRegion& region, S32 start, S32 end)  { -	S32 end = index+count; -	S32 region_end = region.mIndex+region.mCount; -	  	if (end < region.mIndex || -		index > region_end) +		start > region.mEnd)  	{ //gap exists, do not merge  		return false;  	} -	S32 new_end = llmax(end, region_end); -	S32 new_index = llmin(index, region.mIndex); -	region.mIndex = new_index; -	region.mCount = new_end-new_index; +	region.mEnd = llmax(end, region.mEnd); +	region.mIndex = llmin(start, region.mIndex); +	region.mCount = region.mEnd-region.mIndex; +  	return true;  } @@ -1464,7 +1475,6 @@ static LLFastTimer::DeclareTimer FTM_VBO_MAP_BUFFER("VBO Map");  // Map for data access  volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range)  { -	bindGLBuffer(true);  	if (mFinal)  	{  		llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl; @@ -1485,23 +1495,23 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo  			bool mapped = false;  			//see if range is already mapped -			for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) +			S32 start_index = mOffsets[type]+index*sTypeSize[type]; +			S32 end_index = start_index+count*sTypeSize[type]; + +			for (std::vector<MappedRegion>::iterator iter = mMappedVertexRegions.begin(), end = mMappedVertexRegions.end(); iter != end; ++iter)  			{ -				MappedRegion& region = mMappedVertexRegions[i]; -				if (region.mType == type) +				MappedRegion& region = *iter; +				if (expand_region(region, index, end_index))  				{ -					if (expand_region(region, index, count)) -					{ -						mapped = true; -						break; -					} +					mapped = true; +					break;  				}  			}  			if (!mapped)  			{  				//not already mapped, map new region -				MappedRegion region(type, mMappable && map_range ? -1 : index, count); +				MappedRegion region(mMappable && map_range ? -1 : start_index, end_index-start_index);  				mMappedVertexRegions.push_back(region);  			}  		} @@ -1525,6 +1535,7 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo  			{  				volatile U8* src = NULL;  				waitFence(); +				bindGLBuffer();  				if (gGLManager.mHasMapBufferRange)  				{  					if (map_range) @@ -1643,7 +1654,6 @@ static LLFastTimer::DeclareTimer FTM_VBO_MAP_INDEX("IBO Map");  volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range)  { -	bindGLIndices(true);  	if (mFinal)  	{  		llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl; @@ -1662,12 +1672,14 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range  				count = mNumIndices-index;  			} +			S32 end = index+count; +  			bool mapped = false;  			//see if range is already mapped  			for (U32 i = 0; i < mMappedIndexRegions.size(); ++i)  			{  				MappedRegion& region = mMappedIndexRegions[i]; -				if (expand_region(region, index, count)) +				if (expand_region(region, index, end))  				{  					mapped = true;  					break; @@ -1677,7 +1689,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range  			if (!mapped)  			{  				//not already mapped, map new region -				MappedRegion region(TYPE_INDEX, mMappable && map_range ? -1 : index, count); +				MappedRegion region(mMappable && map_range ? -1 : index, count);  				mMappedIndexRegions.push_back(region);  			}  		} @@ -1693,23 +1705,23 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range  			sMappedCount++;  			stop_glerror();	 -			if (gDebugGL && useVBOs()) -			{ -				GLint elem = 0; -				glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); - -				if (elem != mGLIndices) -				{ -					llerrs << "Wrong index buffer bound!" << llendl; -				} -			} -  			if(!mMappable)  			{  				map_range = false;  			}  			else  			{ +				bindGLIndices(); +				if (gDebugGL && useVBOs()) +				{ +					GLint elem = 0; +					glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + +					if (elem != mGLIndices) +					{ +						llerrs << "Wrong index buffer bound!" << llendl; +					} +				}  				volatile U8* src = NULL;  				waitFence();  				if (gGLManager.mHasMapBufferRange) @@ -1820,8 +1832,10 @@ void LLVertexBuffer::unmapBuffer()  	if (mMappedData && mVertexLocked)  	{ +		llassert(mUsage != GL_DYNAMIC_COPY_ARB); +		  		LLFastTimer t(FTM_VBO_UNMAP); -		bindGLBuffer(true); +		bindGLBuffer();  		updated_all = mIndexLocked; //both vertex and index buffers done updating  		if(!mMappable) @@ -1832,8 +1846,8 @@ void LLVertexBuffer::unmapBuffer()  				for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)  				{  					const MappedRegion& region = mMappedVertexRegions[i]; -					S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; -					S32 length = sTypeSize[region.mType]*region.mCount; +					S32 offset = region.mIndex; +					S32 length = region.mCount;  					glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, (U8*) mMappedData+offset);  					stop_glerror();  				} @@ -1857,8 +1871,8 @@ void LLVertexBuffer::unmapBuffer()  					for (U32 i = 0; i < mMappedVertexRegions.size(); ++i)  					{  						const MappedRegion& region = mMappedVertexRegions[i]; -						S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; -						S32 length = sTypeSize[region.mType]*region.mCount; +						S32 offset = region.mIndex; +						S32 length = region.mCount;  						if (gGLManager.mHasMapBufferRange)  						{  							LLFastTimer t(FTM_VBO_FLUSH_RANGE); @@ -2067,7 +2081,6 @@ bool LLVertexBuffer::bindGLArray()  	if (mGLArray && sGLRenderArray != mGLArray)  	{  		{ -			LLFastTimer t(FTM_BIND_GL_ARRAY);  #if GL_ARB_vertex_array_object  			glBindVertexArray(mGLArray);  #endif @@ -2094,22 +2107,15 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind)  	if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))))  	{ -		LLFastTimer t(FTM_BIND_GL_BUFFER); -		/*if (sMapped) -		{ -			llerrs << "VBO bound while another VBO mapped!" << llendl; -		}*/ +		//LLFastTimer t(FTM_BIND_GL_BUFFER); <-- this timer is showing up as a hotspot (irony) +		  		glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer);  		sGLRenderBuffer = mGLBuffer;  		sBindCount++;  		sVBOActive = true; -		if (mGLArray) -		{ -			llassert(sGLRenderArray == mGLArray); -			//mCachedRenderBuffer = mGLBuffer; -		} - +		llassert(!mGLArray || sGLRenderArray == mGLArray); +		  		ret = true;  	} @@ -2444,11 +2450,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)  	llglassertok();  } -LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count) -: mType(type), mIndex(index), mCount(count) +LLVertexBuffer::MappedRegion::MappedRegion(S32 index, S32 count) +: mIndex(index), mCount(count)  {  -	llassert(mType == LLVertexBuffer::TYPE_INDEX ||  -			mType < LLVertexBuffer::TYPE_TEXTURE_INDEX); +	mEnd = mIndex+mCount;	  }	 diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 11fa4ab6a0..52559d3505 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -104,11 +104,11 @@ public:  	class MappedRegion  	{  	public: -		S32 mType;  		S32 mIndex;  		S32 mCount; +		S32 mEnd; -		MappedRegion(S32 type, S32 index, S32 count); +		MappedRegion(S32 index, S32 count);  	};  	LLVertexBuffer(const LLVertexBuffer& rhs) @@ -125,9 +125,10 @@ public:  	static LLVBOPool sStreamVBOPool;  	static LLVBOPool sDynamicVBOPool; +	static LLVBOPool sDynamicCopyVBOPool;  	static LLVBOPool sStreamIBOPool;  	static LLVBOPool sDynamicIBOPool; - +	  	static std::list<U32> sAvailableVAOName;  	static U32 sCurVAOName; diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl deleted file mode 100644 index da1b234240..0000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ /dev/null @@ -1,190 +0,0 @@ -/**  - * @file giF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, Linden Research, Inc. - *  - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - *  - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - *  - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA - * $/LicenseInfo$ - */ -  -#extension GL_ARB_texture_rectangle : enable - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2D noiseMap; - -uniform sampler2D		diffuseGIMap; -uniform sampler2D		normalGIMap; -uniform sampler2D		depthGIMap; - -uniform sampler2D		lightFunc; - -// Inputs -VARYING vec2 vary_fragcoord; - -uniform vec2 screen_res; - -uniform mat4 inv_proj; -uniform mat4 gi_mat;  //gPipeline.mGIMatrix - eye space to sun space -uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space -uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix -uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space -uniform float gi_radius; -uniform float gi_intensity; -uniform int gi_samples; -uniform vec2 gi_kern[25]; -uniform vec2 gi_scale; -uniform vec3 gi_quad; -uniform vec3 gi_spec; -uniform float gi_direction_weight; -uniform float gi_light_offset; - -vec4 getPosition(vec2 pos_screen) -{ -	float depth = texture2DRect(depthMap, pos_screen.xy).a; -	vec2 sc = pos_screen.xy*2.0; -	sc /= screen_res; -	sc -= vec2(1.0,1.0); -	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); -	vec4 pos = inv_proj * ndc; -	pos /= pos.w; -	pos.w = 1.0; -	return pos; -} - -vec4 getGIPosition(vec2 gi_tc) -{ -	float depth = texture2D(depthGIMap, gi_tc).a; -	vec2 sc = gi_tc*2.0; -	sc -= vec2(1.0, 1.0); -	vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); -	vec4 pos = gi_inv_proj*ndc; -	pos.xyz /= pos.w; -	pos.w = 1.0; -	return pos; -} - -vec3 giAmbient(vec3 pos, vec3 norm) -{ -	vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); -	gi_c.xyz /= gi_c.w; - -	vec4 gi_pos = gi_mat*vec4(pos,1.0); -	vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; -	gi_norm = normalize(gi_norm); -	 -	vec2 tcx = gi_norm.xy; -	vec2 tcy = gi_norm.yx; -	 -	vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); -	 -	vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w); -	 -	//vec3 eye_dir = vec3(0,0,-1); -	//eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; -	//eye_dir = normalize(eye_dir); -	 -	//float round_x = gi_scale.x; -	//float round_y = gi_scale.y; -	 -	vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5; -	debug.xz = vec2(0.0,0.0); -	//debug = fract(debug); -	 -	float round_x = 1.0/64.0; -	float round_y = 1.0/64.0; -	 -	//gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; -	//gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; -	 -	float fda = 0.0; -	vec3 fdiff = vec3(0,0,0); -	 -	vec3 rcol = vec3(0,0,0); -	 -	float fsa = 0.0; -	 -	for (int i = -1; i < 2; i+=2 ) -	{ -		for (int j = -1; j < 2; j+=2) -		{ -			vec2 tc = vec2(i, j)*0.75; -			vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; -			//tc += gi_norm.xy*nz.z; -			tc += nz.xy*2.0; -			tc /= gi_samples; -			tc += gi_c.xy; -			 -			vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); -			vec3 lpos = getGIPosition(tc.xy).xyz; -							 -			vec3 at = lpos-gi_pos.xyz; -			float dist = dot(at,at); -			float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); -			 -			if (da > 0.0) -			{ -				//add angular attenuation -				vec3 ldir = at; -				float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0); -			 -				float ld = -dot(ldir, lnorm); -				 -				if (ang_atten > 0.0 && ld < 0.0) -				{ -					vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz; -					da = da*ang_atten; -					fda += da; -					fdiff += diff*da; -				} -			} -		} -	} - -	fdiff /= max(gi_spec.y*fda, gi_quad.z); -	fdiff = clamp(fdiff, vec3(0), vec3(1)); -	 -	vec3 ret = fda*fdiff; -	//ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z;			 - -	//fda *= nz.z; -	 -	//rcol.rgb *= gi_intensity; -	//return rcol.rgb+vary_AmblitColor.rgb*0.25; -	//return vec4(debug, 0.0); -	//return vec4(fda*fdiff, 0.0); -	return clamp(ret,vec3(0.0), vec3(1.0)); -	//return debug.xyz; -} - -void main()  -{ -	vec2 pos_screen = vary_fragcoord.xy; -	vec4 pos = getPosition(pos_screen); -	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; -	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm -	 -	frag_color.xyz = giAmbient(pos, norm); -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 3427d6db57..1149aec30b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -53,13 +53,11 @@ uniform vec3 specular;  uniform float lightExp;  uniform float refScale;  uniform float kd; -uniform vec2 screenRes;  uniform vec3 normScale;  uniform float fresnelScale;  uniform float fresnelOffset;  uniform float blurMultiplier; -uniform vec2 screen_res; -uniform mat4 norm_mat; //region space to screen space +uniform mat3 normal_matrix;  //bigWave is (refCoord.w, view.w);  VARYING vec4 refCoord; @@ -157,7 +155,7 @@ void main()  	//wavef.z *= 0.1f;  	//wavef = normalize(wavef); -	vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; +	vec3 screenspacewavef = normal_matrix*wavef;  	frag_data[0] = vec4(color.rgb, 0.5); // diffuse  	frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl index 0d8dab0a41..485e48537c 100644 --- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -43,13 +43,11 @@ uniform vec2 fbScale;  uniform float refScale;  uniform float znear;  uniform float zfar; -uniform float kd;  uniform vec4 waterPlane;  uniform vec3 eyeVec;  uniform vec4 waterFogColor;  uniform float waterFogDensity;  uniform float waterFogKS; -uniform vec2 screenRes;  //bigWave is (refCoord.w, view.w);  VARYING vec4 refCoord; diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index 79bffab745..1fd7bdaa5c 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -42,8 +42,6 @@ uniform vec3 lightDir;  uniform vec3 specular;  uniform float lightExp;  uniform float refScale; -uniform float kd; -uniform vec2 screenRes;  uniform vec3 normScale;  uniform float fresnelScale;  uniform float fresnelOffset; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index b6fd7bc9c2..f0eee24fef 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3062,6 +3062,30 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)  	sendReliableMessage();  } +// Send a message to the region to stop the NULL animation state +// This will reset animation state overrides for the agent. +void LLAgent::sendAnimationStateReset() +{ +	if (gAgentID.isNull() || !mRegionp) +	{ +		return; +	} + +	LLMessageSystem* msg = gMessageSystem; +	msg->newMessageFast(_PREHASH_AgentAnimation); +	msg->nextBlockFast(_PREHASH_AgentData); +	msg->addUUIDFast(_PREHASH_AgentID, getID()); +	msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + +	msg->nextBlockFast(_PREHASH_AnimationList); +	msg->addUUIDFast(_PREHASH_AnimID, LLUUID::null ); +	msg->addBOOLFast(_PREHASH_StartAnim, FALSE); + +	msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList); +	msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0); +	sendReliableMessage(); +} +  void LLAgent::sendWalkRun(bool running)  {  	LLMessageSystem* msgsys = gMessageSystem; @@ -4140,6 +4164,8 @@ void LLAgent::stopCurrentAnimations()  	// avatar, propagating this change back to the server.  	if (isAgentAvatarValid())  	{ +		LLDynamicArray<LLUUID> anim_ids; +  		for ( LLVOAvatar::AnimIterator anim_it =  			      gAgentAvatarp->mPlayingAnimations.begin();  		      anim_it != gAgentAvatarp->mPlayingAnimations.end(); @@ -4157,10 +4183,15 @@ void LLAgent::stopCurrentAnimations()  				// stop this animation locally  				gAgentAvatarp->stopMotion(anim_it->first, TRUE);  				// ...and tell the server to tell everyone. -				sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP); +				anim_ids.push_back(anim_it->first);  			}  		} +		sendAnimationRequests(anim_ids, ANIM_REQUEST_STOP); + +		// Tell the region to clear any animation state overrides. +		sendAnimationStateReset(); +  		// re-assert at least the default standing animation, because  		// viewers get confused by avs with no associated anims.  		sendAnimationRequest(ANIM_AGENT_STAND, diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 99904e118c..bec9352f5f 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -431,6 +431,8 @@ public:  	void			onAnimStop(const LLUUID& id);  	void			sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request);  	void			sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request); +	void			sendAnimationStateReset(); +  	void			endAnimationUpdateUI();  	void			unpauseAnimation() { mPauseRequest = NULL; }  	BOOL			getCustomAnim() const { return mCustomAnim; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7331b93810..9bbaede68d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -537,7 +537,7 @@ static void settings_to_globals()  	LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));  	LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile"); - +	LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");  	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic");  	LLImageGL::sCompressTextures		= gSavedSettings.getBOOL("RenderCompressTextures");  	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor"); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 119b8d24d0..d29181a3ce 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -254,7 +254,7 @@ S32 LLDrawable::findReferences(LLDrawable *drawablep)  	return count;  } -static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face", true); +static LLFastTimer::DeclareTimer FTM_ALLOCATE_FACE("Allocate Face");  LLFace*	LLDrawable::addFace(LLFacePool *poolp, LLViewerTexture *texturep)  { diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 94dd927d26..d8f293cc62 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -472,6 +472,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba  		{  			params.mGroup->rebuildMesh();  		} +		  		params.mVertexBuffer->setBuffer(mask);  		params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 3cf96a9054..d5afa25c9c 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1505,8 +1505,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				stop_glerror(); -				static LLStaticHashedString sMatPalette("matrixPalette"); -				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv(sMatPalette,  +				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv(LLViewerShaderMgr::AVATAR_MATRIX,   					skin->mJointNames.size(),  					FALSE,  					(GLfloat*) mat[0].mMatrix); @@ -1548,6 +1547,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)  				buff->setBuffer(data_mask);  				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);		  			} + +			gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);  		}  	}  } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 4137084ebe..7e95046479 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -461,6 +461,8 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&  				}  			}  		} +        // Moved below shader->disableTexture call to avoid false alarms from auto-re-enable of textures on stage 0 +        // MAINT-755  		cube_map->disable();  		cube_map->restoreMatrix();  	} diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 3805348b6b..cac862a107 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -49,9 +49,6 @@  #include "llviewershadermgr.h"  #include "llrender.h" -static LLStaticHashedString sObjectPlaneS("object_plane_s"); -static LLStaticHashedString sObjectPlaneT("object_plane_t"); -  const F32 DETAIL_SCALE = 1.f/16.f;  int DebugDetailMap = 0; @@ -355,8 +352,8 @@ void LLDrawPoolTerrain::renderFullShader()  	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;  	llassert(shader); -	shader->uniform4fv(sObjectPlaneS, 1, tp0.mV); -	shader->uniform4fv(sObjectPlaneT, 1, tp1.mV); +	shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); +	shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);  	gGL.matrixMode(LLRender::MM_TEXTURE);  	gGL.loadIdentity(); @@ -865,8 +862,8 @@ void LLDrawPoolTerrain::renderSimple()  	if (LLGLSLShader::sNoFixedFunction)  	{ -		sShader->uniform4fv(sObjectPlaneS, 1, tp0.mV); -		sShader->uniform4fv(sObjectPlaneT, 1, tp1.mV); +		sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0.mV); +		sShader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1.mV);  	}  	else  	{ diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index ffe438eb27..b6a4b0194c 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -1,736 +1,719 @@ -/** 
 - * @file lldrawpoolwater.cpp
 - * @brief LLDrawPoolWater class implementation
 - *
 - * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 - * Second Life Viewer Source Code
 - * Copyright (C) 2010, Linden Research, Inc.
 - * 
 - * This library is free software; you can redistribute it and/or
 - * modify it under the terms of the GNU Lesser General Public
 - * License as published by the Free Software Foundation;
 - * version 2.1 of the License only.
 - * 
 - * This library is distributed in the hope that it will be useful,
 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 - * Lesser General Public License for more details.
 - * 
 - * You should have received a copy of the GNU Lesser General Public
 - * License along with this library; if not, write to the Free Software
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 - * 
 - * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 - * $/LicenseInfo$
 - */
 -
 -#include "llviewerprecompiledheaders.h"
 -#include "llfeaturemanager.h"
 -#include "lldrawpoolwater.h"
 -
 -#include "llviewercontrol.h"
 -#include "lldir.h"
 -#include "llerror.h"
 -#include "m3math.h"
 -#include "llrender.h"
 -
 -#include "llagent.h"		// for gAgent for getRegion for getWaterHeight
 -#include "llcubemap.h"
 -#include "lldrawable.h"
 -#include "llface.h"
 -#include "llsky.h"
 -#include "llviewertexturelist.h"
 -#include "llviewerregion.h"
 -#include "llvosky.h"
 -#include "llvowater.h"
 -#include "llworld.h"
 -#include "pipeline.h"
 -#include "llviewershadermgr.h"
 -#include "llwaterparammanager.h"
 -
 -const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
 -const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
 -
 -static LLStaticHashedString sObjectPlaneS("object_plane_s");
 -static LLStaticHashedString sObjectPlaneT("object_plane_t");
 -static LLStaticHashedString sScreenRes("screenRes");
 -static LLStaticHashedString sNormScale("normScale");
 -static LLStaticHashedString sFresnelScale("fresnelScale");
 -static LLStaticHashedString sFresnelOffset("fresnelOffset");
 -static LLStaticHashedString sBlurMultiplier("blurMultiplier");
 -static LLStaticHashedString sSunAngle("sunAngle");
 -static LLStaticHashedString sScaledAngle("scaledAngle");
 -static LLStaticHashedString sSunAngle2("sunAngle2");
 -
 -static float sTime;
 -
 -BOOL deferred_render = FALSE;
 -
 -BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
 -BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
 -BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
 -LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
 -F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
 -
 -LLVector3 LLDrawPoolWater::sLightDir;
 -
 -LLDrawPoolWater::LLDrawPoolWater() :
 -	LLFacePool(POOL_WATER)
 -{
 -	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
 -	gGL.getTexUnit(0)->bind(mHBTex[0]) ;
 -	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
 -
 -	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
 -	gGL.getTexUnit(0)->bind(mHBTex[1]);
 -	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
 -
 -
 -	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
 -	llassert(mWaterImagep);
 -	mWaterImagep->setNoDelete();
 -	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE);
 -	llassert(mOpaqueWaterImagep);
 -	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
 -	mWaterNormp->setNoDelete();
 -
 -	restoreGL();
 -}
 -
 -LLDrawPoolWater::~LLDrawPoolWater()
 -{
 -}
 -
 -//static
 -void LLDrawPoolWater::restoreGL()
 -{
 -	
 -}
 -
 -LLDrawPool *LLDrawPoolWater::instancePool()
 -{
 -	llerrs << "Should never be calling instancePool on a water pool!" << llendl;
 -	return NULL;
 -}
 -
 -
 -void LLDrawPoolWater::prerender()
 -{
 -	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ?
 -		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
 -
 -	// got rid of modulation by light color since it got a little too
 -	// green at sunset and sl-57047 (underwater turns black at 8:00)
 -	sWaterFogColor = LLWaterParamManager::instance().getFogColor();
 -	sWaterFogColor.mV[3] = 0;
 -
 -}
 -
 -S32 LLDrawPoolWater::getNumPasses()
 -{
 -	if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
 -	{
 -		return 1;
 -	}
 -
 -	return 0;
 -}
 -
 -void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
 -{
 -	beginRenderPass(pass);
 -	deferred_render = TRUE;
 -}
 -
 -void LLDrawPoolWater::endPostDeferredPass(S32 pass)
 -{
 -	endRenderPass(pass);
 -	deferred_render = FALSE;
 -}
 -
 -//===============================
 -//DEFERRED IMPLEMENTATION
 -//===============================
 -void LLDrawPoolWater::renderDeferred(S32 pass)
 -{
 -	LLFastTimer t(FTM_RENDER_WATER);
 -	deferred_render = TRUE;
 -	shade();
 -	deferred_render = FALSE;
 -}
 -
 -//=========================================
 -
 -void LLDrawPoolWater::render(S32 pass)
 -{
 -	LLFastTimer ftm(FTM_RENDER_WATER);
 -	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
 -	{
 -		return;
 -	}
 -
 -	//do a quick 'n dirty depth sort
 -	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -			 iter != mDrawFace.end(); iter++)
 -	{
 -		LLFace* facep = *iter;
 -		facep->mDistance = -facep->mCenterLocal.mV[2];
 -	}
 -
 -	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
 -
 -	// See if we are rendering water as opaque or not
 -	if (!gSavedSettings.getBOOL("RenderTransparentWater"))
 -	{
 -		// render water for low end hardware
 -		renderOpaqueLegacyWater();
 -		return;
 -	}
 -
 -	LLGLEnable blend(GL_BLEND);
 -
 -	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
 -	{
 -		shade();
 -		return;
 -	}
 -
 -	LLVOSky *voskyp = gSky.mVOSkyp;
 -
 -	stop_glerror();
 -
 -	if (!gGLManager.mHasMultitexture)
 -	{
 -		// Ack!  No multitexture!  Bail!
 -		return;
 -	}
 -
 -	LLFace* refl_face = voskyp->getReflFace();
 -
 -	gPipeline.disableLights();
 -	
 -	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 -
 -	LLGLDisable cullFace(GL_CULL_FACE);
 -	
 -	// Set up second pass first
 -	mWaterImagep->addTextureStats(1024.f*1024.f);
 -	gGL.getTexUnit(1)->activate();
 -	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
 -	gGL.getTexUnit(1)->bind(mWaterImagep) ;
 -
 -	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
 -	F32 up_dot = camera_up * LLVector3::z_axis;
 -
 -	LLColor4 water_color;
 -	if (LLViewerCamera::getInstance()->cameraUnderWater())
 -	{
 -		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
 -	}
 -	else
 -	{
 -		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
 -	}
 -
 -	gGL.diffuseColor4fv(water_color.mV);
 -
 -	// Automatically generate texture coords for detail map
 -	glEnable(GL_TEXTURE_GEN_S); //texture unit 1
 -	glEnable(GL_TEXTURE_GEN_T); //texture unit 1
 -	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
 -	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
 -
 -	// Slowly move over time.
 -	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
 -	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
 -	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
 -	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
 -	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
 -
 -	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
 -	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
 -
 -	gGL.getTexUnit(0)->activate();
 -	
 -	glClearStencil(1);
 -	glClear(GL_STENCIL_BUFFER_BIT);
 -	LLGLEnable gls_stencil(GL_STENCIL_TEST);
 -	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
 -	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
 -
 -	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -		 iter != mDrawFace.end(); iter++)
 -	{
 -		LLFace *face = *iter;
 -		if (voskyp->isReflFace(face))
 -		{
 -			continue;
 -		}
 -		gGL.getTexUnit(0)->bind(face->getTexture());
 -		face->renderIndexed();
 -	}
 -
 -	// Now, disable texture coord generation on texture state 1
 -	gGL.getTexUnit(1)->activate();
 -	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 -	gGL.getTexUnit(1)->disable();
 -	glDisable(GL_TEXTURE_GEN_S); //texture unit 1
 -	glDisable(GL_TEXTURE_GEN_T); //texture unit 1
 -
 -	// Disable texture coordinate and color arrays
 -	gGL.getTexUnit(0)->activate();
 -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 -
 -	stop_glerror();
 -	
 -	if (gSky.mVOSkyp->getCubeMap())
 -	{
 -		gSky.mVOSkyp->getCubeMap()->enable(0);
 -		gSky.mVOSkyp->getCubeMap()->bind();
 -
 -		gGL.matrixMode(LLRender::MM_TEXTURE);
 -		gGL.loadIdentity();
 -		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
 -		LLMatrix4 camera_rot(camera_mat.getMat3());
 -		camera_rot.invert();
 -
 -		gGL.loadMatrix((F32 *)camera_rot.mMatrix);
 -
 -		gGL.matrixMode(LLRender::MM_MODELVIEW);
 -		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot);
 -
 -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 -
 -		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -			 iter != mDrawFace.end(); iter++)
 -		{
 -			LLFace *face = *iter;
 -			if (voskyp->isReflFace(face))
 -			{
 -				//refl_face = face;
 -				continue;
 -			}
 -
 -			if (face->getGeomCount() > 0)
 -			{					
 -				face->renderIndexed();
 -			}
 -		}
 -
 -		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 -
 -		gSky.mVOSkyp->getCubeMap()->disable();
 -		
 -		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 -		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 -		gGL.matrixMode(LLRender::MM_TEXTURE);
 -		gGL.loadIdentity();
 -		gGL.matrixMode(LLRender::MM_MODELVIEW);
 -		
 -	}
 -
 -	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 -
 -    if (refl_face)
 -	{
 -		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
 -		renderReflection(refl_face);
 -	}
 -
 -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 -}
 -
 -// for low end hardware
 -void LLDrawPoolWater::renderOpaqueLegacyWater()
 -{
 -	LLVOSky *voskyp = gSky.mVOSkyp;
 -
 -	LLGLSLShader* shader = NULL;
 -	if (LLGLSLShader::sNoFixedFunction)
 -	{
 -		if (LLPipeline::sUnderWaterRender)
 -		{
 -			shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
 -		}
 -		else
 -		{
 -			shader = &gObjectSimpleNonIndexedTexGenProgram;
 -		}
 -
 -		shader->bind();
 -	}
 -
 -	stop_glerror();
 -
 -	// Depth sorting and write to depth buffer
 -	// since this is opaque, we should see nothing
 -	// behind the water.  No blending because
 -	// of no transparency.  And no face culling so
 -	// that the underside of the water is also opaque.
 -	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
 -	LLGLDisable no_cull(GL_CULL_FACE);
 -	LLGLDisable no_blend(GL_BLEND);
 -
 -	gPipeline.disableLights();
 -
 -	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
 -
 -	// Activate the texture binding and bind one
 -	// texture since all images will have the same texture
 -	gGL.getTexUnit(0)->activate();
 -	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 -	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);
 -
 -	// Automatically generate texture coords for water texture
 -	if (!shader)
 -	{
 -		glEnable(GL_TEXTURE_GEN_S); //texture unit 0
 -		glEnable(GL_TEXTURE_GEN_T); //texture unit 0
 -		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
 -		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
 -	}
 -
 -	// Use the fact that we know all water faces are the same size
 -	// to save some computation
 -
 -	// Slowly move texture coordinates over time so the watter appears
 -	// to be moving.
 -	F32 movement_period_secs = 50.f;
 -
 -	F32 offset = fmod(gFrameTimeSeconds, movement_period_secs);
 -
 -	if (movement_period_secs != 0)
 -	{
 -	 	offset /= movement_period_secs;
 -	}
 -	else
 -	{
 -		offset = 0;
 -	}
 -
 -	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
 -	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };
 -
 -	if (!shader)
 -	{
 -		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
 -		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
 -	}
 -	else
 -	{
 -		shader->uniform4fv(sObjectPlaneS, 1, tp0);
 -		shader->uniform4fv(sObjectPlaneT, 1, tp1);
 -	}
 -
 -	gGL.diffuseColor3f(1.f, 1.f, 1.f);
 -
 -	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -		 iter != mDrawFace.end(); iter++)
 -	{
 -		LLFace *face = *iter;
 -		if (voskyp->isReflFace(face))
 -		{
 -			continue;
 -		}
 -
 -		face->renderIndexed();
 -	}
 -
 -	stop_glerror();
 -
 -	if (!shader)
 -	{
 -		// Reset the settings back to expected values
 -		glDisable(GL_TEXTURE_GEN_S); //texture unit 0
 -		glDisable(GL_TEXTURE_GEN_T); //texture unit 0
 -	}
 -
 -	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 -	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 -}
 -
 -
 -void LLDrawPoolWater::renderReflection(LLFace* face)
 -{
 -	LLVOSky *voskyp = gSky.mVOSkyp;
 -
 -	if (!voskyp)
 -	{
 -		return;
 -	}
 -
 -	if (!face->getGeomCount())
 -	{
 -		return;
 -	}
 -	
 -	S8 dr = voskyp->getDrawRefl();
 -	if (dr < 0)
 -	{
 -		return;
 -	}
 -
 -	LLGLSNoFog noFog;
 -
 -	gGL.getTexUnit(0)->bind(mHBTex[dr]);
 -
 -	LLOverrideFaceColor override(this, face->getFaceColor().mV);
 -	face->renderIndexed();
 -}
 -
 -void LLDrawPoolWater::shade()
 -{
 -	if (!deferred_render)
 -	{
 -		gGL.setColorMask(true, true);
 -	}
 -
 -	LLVOSky *voskyp = gSky.mVOSkyp;
 -
 -	if(voskyp == NULL) 
 -	{
 -		return;
 -	}
 -
 -	LLGLDisable blend(GL_BLEND);
 -
 -	LLColor3 light_diffuse(0,0,0);
 -	F32 light_exp = 0.0f;
 -	LLVector3 light_dir;
 -	LLColor3 light_color;
 -
 -	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	 
 -    { 	 
 -        light_dir  = gSky.getSunDirection(); 	 
 -        light_dir.normVec(); 	
 -		light_color = gSky.getSunDiffuseColor();
 -		if(gSky.mVOSkyp) {
 -	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	 
 -			light_diffuse.normVec(); 	 
 -		}
 -        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
 -        light_diffuse *= light_exp + 0.25f; 	 
 -    } 	 
 -    else  	 
 -    { 	 
 -        light_dir       = gSky.getMoonDirection(); 	 
 -        light_dir.normVec(); 	 
 -		light_color = gSky.getMoonDiffuseColor();
 -        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	 
 -        light_diffuse.normVec(); 	 
 -        light_diffuse *= 0.5f; 	 
 -        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	 
 -    }
 -
 -	light_exp *= light_exp;
 -	light_exp *= light_exp;
 -	light_exp *= light_exp;
 -	light_exp *= light_exp;
 -	light_exp *= 256.f;
 -	light_exp = light_exp > 32.f ? light_exp : 32.f;
 -
 -	LLGLSLShader* shader;
 -
 -	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
 -	
 -	if (deferred_render)
 -	{
 -		shader = &gDeferredWaterProgram;
 -	}
 -	else if (eyedepth < 0.f && LLPipeline::sWaterReflections)
 -	{
 -		shader = &gUnderWaterProgram;
 -	}
 -	else
 -	{
 -		shader = &gWaterProgram;
 -	}
 -
 -	if (deferred_render)
 -	{
 -		gPipeline.bindDeferredShader(*shader);
 -	}
 -	else
 -	{
 -		shader->bind();
 -	}
 -
 -	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
 -	
 -	S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX);
 -		
 -	if (reftex > -1)
 -	{
 -		gGL.getTexUnit(reftex)->activate();
 -		gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
 -		gGL.getTexUnit(0)->activate();
 -	}	
 -
 -	//bind normal map
 -	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
 -
 -	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance();
 -
 -	// change mWaterNormp if needed
 -	if (mWaterNormp->getID() != param_mgr->getNormalMapID())
 -	{
 -		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID());
 -	}
 -
 -	mWaterNormp->addTextureStats(1024.f*1024.f);
 -	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ;
 -	if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
 -	{
 -		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
 -	}
 -	else 
 -	{
 -		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT);
 -	}
 -	
 -	S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
 -		
 -	if (screentex > -1)
 -	{
 -		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
 -		shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, 
 -			param_mgr->getFogDensity());
 -		gPipeline.mWaterDis.bindTexture(0, screentex);
 -	}
 -	
 -	stop_glerror();
 -	
 -	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	
 -
 -	if (mVertexShaderLevel == 1)
 -	{
 -		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
 -		shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
 -	}
 -
 -	F32 screenRes[] = 
 -	{
 -		1.f/gGLViewport[2],
 -		1.f/gGLViewport[3]
 -	};
 -	shader->uniform2fv(sScreenRes, 1, screenRes);
 -	stop_glerror();
 -	
 -	S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 -	stop_glerror();
 -	
 -	light_dir.normVec();
 -	sLightDir = light_dir;
 -	
 -	light_diffuse *= 6.f;
 -
 -	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
 -	shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth);
 -	shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime);
 -	shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
 -	shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
 -	shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp);
 -	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
 -	shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
 -	shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
 -
 -	shader->uniform3fv(sNormScale, 1, param_mgr->getNormalScale().mV);
 -	shader->uniform1f(sFresnelScale, param_mgr->getFresnelScale());
 -	shader->uniform1f(sFresnelOffset, param_mgr->getFresnelOffset());
 -	shader->uniform1f(sBlurMultiplier, param_mgr->getBlurMultiplier());
 -
 -	F32 sunAngle = llmax(0.f, light_dir.mV[2]);
 -	F32 scaledAngle = 1.f - sunAngle;
 -
 -	shader->uniform1f(sSunAngle, sunAngle);
 -	shader->uniform1f(sScaledAngle, scaledAngle);
 -	shader->uniform1f(sSunAngle2, 0.1f + 0.2f*sunAngle);
 -
 -	LLColor4 water_color;
 -	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
 -	F32 up_dot = camera_up * LLVector3::z_axis;
 -	if (LLViewerCamera::getInstance()->cameraUnderWater())
 -	{
 -		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
 -		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
 -	}
 -	else
 -	{
 -		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
 -		shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
 -	}
 -
 -	if (water_color.mV[3] > 0.9f)
 -	{
 -		water_color.mV[3] = 0.9f;
 -	}
 -
 -	{
 -		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
 -		LLGLDisable cullface(GL_CULL_FACE);
 -		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
 -			iter != mDrawFace.end(); iter++)
 -		{
 -			LLFace *face = *iter;
 -
 -			if (voskyp->isReflFace(face))
 -			{
 -				continue;
 -			}
 -
 -			LLVOWater* water = (LLVOWater*) face->getViewerObject();
 -			gGL.getTexUnit(diffTex)->bind(face->getTexture());
 -
 -			sNeedsReflectionUpdate = TRUE;
 -			
 -			if (water->getUseTexture() || !water->getIsEdgePatch())
 -			{
 -				sNeedsDistortionUpdate = TRUE;
 -				face->renderIndexed();
 -			}
 -			else if (gGLManager.mHasDepthClamp || deferred_render)
 -			{
 -				face->renderIndexed();
 -			}
 -			else
 -			{
 -				LLGLSquashToFarClip far_clip(glh_get_current_projection());
 -				face->renderIndexed();
 -			}
 -		}
 -	}
 -	
 -	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
 -	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX);	
 -	shader->disableTexture(LLViewerShaderMgr::BUMP_MAP);
 -	shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
 -	shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX);
 -	shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH);
 -
 -	if (deferred_render)
 -	{
 -		gPipeline.unbindDeferredShader(*shader);
 -	}
 -	else
 -	{
 -		shader->unbind();
 -	}
 -
 -	gGL.getTexUnit(0)->activate();
 -	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
 -	if (!deferred_render)
 -	{
 -		gGL.setColorMask(true, false);
 -	}
 -
 -}
 -
 -LLViewerTexture *LLDrawPoolWater::getDebugTexture()
 -{
 -	return LLViewerFetchedTexture::sSmokeImagep;
 -}
 -
 -LLColor3 LLDrawPoolWater::getDebugColor() const
 -{
 -	return LLColor3(0.f, 1.f, 1.f);
 -}
 +/**  + * @file lldrawpoolwater.cpp + * @brief LLDrawPoolWater class implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfeaturemanager.h" +#include "lldrawpoolwater.h" + +#include "llviewercontrol.h" +#include "lldir.h" +#include "llerror.h" +#include "m3math.h" +#include "llrender.h" + +#include "llagent.h"		// for gAgent for getRegion for getWaterHeight +#include "llcubemap.h" +#include "lldrawable.h" +#include "llface.h" +#include "llsky.h" +#include "llviewertexturelist.h" +#include "llviewerregion.h" +#include "llvosky.h" +#include "llvowater.h" +#include "llworld.h" +#include "pipeline.h" +#include "llviewershadermgr.h" +#include "llwaterparammanager.h" + +const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); +const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055"); + +static float sTime; + +BOOL deferred_render = FALSE; + +BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; +BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; +BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; +LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); +F32 LLDrawPoolWater::sWaterFogEnd = 0.f; + +LLVector3 LLDrawPoolWater::sLightDir; + +LLDrawPoolWater::LLDrawPoolWater() : +	LLFacePool(POOL_WATER) +{ +	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI); +	gGL.getTexUnit(0)->bind(mHBTex[0]) ; +	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); + +	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI); +	gGL.getTexUnit(0)->bind(mHBTex[1]); +	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); + + +	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE); +	llassert(mWaterImagep); +	mWaterImagep->setNoDelete(); +	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE); +	llassert(mOpaqueWaterImagep); +	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL); +	mWaterNormp->setNoDelete(); + +	restoreGL(); +} + +LLDrawPoolWater::~LLDrawPoolWater() +{ +} + +//static +void LLDrawPoolWater::restoreGL() +{ +	 +} + +LLDrawPool *LLDrawPoolWater::instancePool() +{ +	llerrs << "Should never be calling instancePool on a water pool!" << llendl; +	return NULL; +} + + +void LLDrawPoolWater::prerender() +{ +	mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? +		LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; + +	// got rid of modulation by light color since it got a little too +	// green at sunset and sl-57047 (underwater turns black at 8:00) +	sWaterFogColor = LLWaterParamManager::instance().getFogColor(); +	sWaterFogColor.mV[3] = 0; + +} + +S32 LLDrawPoolWater::getNumPasses() +{ +	if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f) +	{ +		return 1; +	} + +	return 0; +} + +void LLDrawPoolWater::beginPostDeferredPass(S32 pass) +{ +	beginRenderPass(pass); +	deferred_render = TRUE; +} + +void LLDrawPoolWater::endPostDeferredPass(S32 pass) +{ +	endRenderPass(pass); +	deferred_render = FALSE; +} + +//=============================== +//DEFERRED IMPLEMENTATION +//=============================== +void LLDrawPoolWater::renderDeferred(S32 pass) +{ +	LLFastTimer t(FTM_RENDER_WATER); +	deferred_render = TRUE; +	shade(); +	deferred_render = FALSE; +} + +//========================================= + +void LLDrawPoolWater::render(S32 pass) +{ +	LLFastTimer ftm(FTM_RENDER_WATER); +	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1) +	{ +		return; +	} + +	//do a quick 'n dirty depth sort +	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +			 iter != mDrawFace.end(); iter++) +	{ +		LLFace* facep = *iter; +		facep->mDistance = -facep->mCenterLocal.mV[2]; +	} + +	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater()); + +	// See if we are rendering water as opaque or not +	if (!gSavedSettings.getBOOL("RenderTransparentWater")) +	{ +		// render water for low end hardware +		renderOpaqueLegacyWater(); +		return; +	} + +	LLGLEnable blend(GL_BLEND); + +	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy) +	{ +		shade(); +		return; +	} + +	LLVOSky *voskyp = gSky.mVOSkyp; + +	stop_glerror(); + +	if (!gGLManager.mHasMultitexture) +	{ +		// Ack!  No multitexture!  Bail! +		return; +	} + +	LLFace* refl_face = voskyp->getReflFace(); + +	gPipeline.disableLights(); +	 +	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + +	LLGLDisable cullFace(GL_CULL_FACE); +	 +	// Set up second pass first +	mWaterImagep->addTextureStats(1024.f*1024.f); +	gGL.getTexUnit(1)->activate(); +	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(1)->bind(mWaterImagep) ; + +	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); +	F32 up_dot = camera_up * LLVector3::z_axis; + +	LLColor4 water_color; +	if (LLViewerCamera::getInstance()->cameraUnderWater()) +	{ +		water_color.setVec(1.f, 1.f, 1.f, 0.4f); +	} +	else +	{ +		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); +	} + +	gGL.diffuseColor4fv(water_color.mV); + +	// Automatically generate texture coords for detail map +	glEnable(GL_TEXTURE_GEN_S); //texture unit 1 +	glEnable(GL_TEXTURE_GEN_T); //texture unit 1 +	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); +	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + +	// Slowly move over time. +	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f); +	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f}; +	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f}; +	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); +	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); + +	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); +	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA); + +	gGL.getTexUnit(0)->activate(); +	 +	glClearStencil(1); +	glClear(GL_STENCIL_BUFFER_BIT); +	LLGLEnable gls_stencil(GL_STENCIL_TEST); +	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); +	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); + +	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +		 iter != mDrawFace.end(); iter++) +	{ +		LLFace *face = *iter; +		if (voskyp->isReflFace(face)) +		{ +			continue; +		} +		gGL.getTexUnit(0)->bind(face->getTexture()); +		face->renderIndexed(); +	} + +	// Now, disable texture coord generation on texture state 1 +	gGL.getTexUnit(1)->activate(); +	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(1)->disable(); +	glDisable(GL_TEXTURE_GEN_S); //texture unit 1 +	glDisable(GL_TEXTURE_GEN_T); //texture unit 1 + +	// Disable texture coordinate and color arrays +	gGL.getTexUnit(0)->activate(); +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +	stop_glerror(); +	 +	if (gSky.mVOSkyp->getCubeMap()) +	{ +		gSky.mVOSkyp->getCubeMap()->enable(0); +		gSky.mVOSkyp->getCubeMap()->bind(); + +		gGL.matrixMode(LLRender::MM_TEXTURE); +		gGL.loadIdentity(); +		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); +		LLMatrix4 camera_rot(camera_mat.getMat3()); +		camera_rot.invert(); + +		gGL.loadMatrix((F32 *)camera_rot.mMatrix); + +		gGL.matrixMode(LLRender::MM_MODELVIEW); +		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot); + +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + +		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +			 iter != mDrawFace.end(); iter++) +		{ +			LLFace *face = *iter; +			if (voskyp->isReflFace(face)) +			{ +				//refl_face = face; +				continue; +			} + +			if (face->getGeomCount() > 0) +			{					 +				face->renderIndexed(); +			} +		} + +		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + +		gSky.mVOSkyp->getCubeMap()->disable(); +		 +		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +		gGL.matrixMode(LLRender::MM_TEXTURE); +		gGL.loadIdentity(); +		gGL.matrixMode(LLRender::MM_MODELVIEW); +		 +	} + +	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + +    if (refl_face) +	{ +		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); +		renderReflection(refl_face); +	} + +	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +} + +// for low end hardware +void LLDrawPoolWater::renderOpaqueLegacyWater() +{ +	LLVOSky *voskyp = gSky.mVOSkyp; + +	LLGLSLShader* shader = NULL; +	if (LLGLSLShader::sNoFixedFunction) +	{ +		if (LLPipeline::sUnderWaterRender) +		{ +			shader = &gObjectSimpleNonIndexedTexGenWaterProgram; +		} +		else +		{ +			shader = &gObjectSimpleNonIndexedTexGenProgram; +		} + +		shader->bind(); +	} + +	stop_glerror(); + +	// Depth sorting and write to depth buffer +	// since this is opaque, we should see nothing +	// behind the water.  No blending because +	// of no transparency.  And no face culling so +	// that the underside of the water is also opaque. +	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); +	LLGLDisable no_cull(GL_CULL_FACE); +	LLGLDisable no_blend(GL_BLEND); + +	gPipeline.disableLights(); + +	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); + +	// Activate the texture binding and bind one +	// texture since all images will have the same texture +	gGL.getTexUnit(0)->activate(); +	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep); + +	// Automatically generate texture coords for water texture +	if (!shader) +	{ +		glEnable(GL_TEXTURE_GEN_S); //texture unit 0 +		glEnable(GL_TEXTURE_GEN_T); //texture unit 0 +		glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); +		glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); +	} + +	// Use the fact that we know all water faces are the same size +	// to save some computation + +	// Slowly move texture coordinates over time so the watter appears +	// to be moving. +	F32 movement_period_secs = 50.f; + +	F32 offset = fmod(gFrameTimeSeconds, movement_period_secs); + +	if (movement_period_secs != 0) +	{ +	 	offset /= movement_period_secs; +	} +	else +	{ +		offset = 0; +	} + +	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset }; +	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset }; + +	if (!shader) +	{ +		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); +		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); +	} +	else +	{ +		shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0); +		shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1); +	} + +	gGL.diffuseColor3f(1.f, 1.f, 1.f); + +	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +		 iter != mDrawFace.end(); iter++) +	{ +		LLFace *face = *iter; +		if (voskyp->isReflFace(face)) +		{ +			continue; +		} + +		face->renderIndexed(); +	} + +	stop_glerror(); + +	if (!shader) +	{ +		// Reset the settings back to expected values +		glDisable(GL_TEXTURE_GEN_S); //texture unit 0 +		glDisable(GL_TEXTURE_GEN_T); //texture unit 0 +	} + +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +} + + +void LLDrawPoolWater::renderReflection(LLFace* face) +{ +	LLVOSky *voskyp = gSky.mVOSkyp; + +	if (!voskyp) +	{ +		return; +	} + +	if (!face->getGeomCount()) +	{ +		return; +	} +	 +	S8 dr = voskyp->getDrawRefl(); +	if (dr < 0) +	{ +		return; +	} + +	LLGLSNoFog noFog; + +	gGL.getTexUnit(0)->bind(mHBTex[dr]); + +	LLOverrideFaceColor override(this, face->getFaceColor().mV); +	face->renderIndexed(); +} + +void LLDrawPoolWater::shade() +{ +	if (!deferred_render) +	{ +		gGL.setColorMask(true, true); +	} + +	LLVOSky *voskyp = gSky.mVOSkyp; + +	if(voskyp == NULL)  +	{ +		return; +	} + +	LLGLDisable blend(GL_BLEND); + +	LLColor3 light_diffuse(0,0,0); +	F32 light_exp = 0.0f; +	LLVector3 light_dir; +	LLColor3 light_color; + +	if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) 	  +    { 	  +        light_dir  = gSky.getSunDirection(); 	  +        light_dir.normVec(); 	 +		light_color = gSky.getSunDiffuseColor(); +		if(gSky.mVOSkyp) { +	        light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); 	  +			light_diffuse.normVec(); 	  +		} +        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	  +        light_diffuse *= light_exp + 0.25f; 	  +    } 	  +    else  	  +    { 	  +        light_dir       = gSky.getMoonDirection(); 	  +        light_dir.normVec(); 	  +		light_color = gSky.getMoonDiffuseColor(); +        light_diffuse   = gSky.mVOSkyp->getMoon().getColorCached(); 	  +        light_diffuse.normVec(); 	  +        light_diffuse *= 0.5f; 	  +        light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); 	  +    } + +	light_exp *= light_exp; +	light_exp *= light_exp; +	light_exp *= light_exp; +	light_exp *= light_exp; +	light_exp *= 256.f; +	light_exp = light_exp > 32.f ? light_exp : 32.f; + +	LLGLSLShader* shader; + +	F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); +	 +	if (deferred_render) +	{ +		shader = &gDeferredWaterProgram; +	} +	else if (eyedepth < 0.f && LLPipeline::sWaterReflections) +	{ +		shader = &gUnderWaterProgram; +	} +	else +	{ +		shader = &gWaterProgram; +	} + +	if (deferred_render) +	{ +		gPipeline.bindDeferredShader(*shader); +	} +	else +	{ +		shader->bind(); +	} + +	sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; +	 +	S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); +		 +	if (reftex > -1) +	{ +		gGL.getTexUnit(reftex)->activate(); +		gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef); +		gGL.getTexUnit(0)->activate(); +	}	 + +	//bind normal map +	S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); + +	LLWaterParamManager * param_mgr = &LLWaterParamManager::instance(); + +	// change mWaterNormp if needed +	if (mWaterNormp->getID() != param_mgr->getNormalMapID()) +	{ +		mWaterNormp = LLViewerTextureManager::getFetchedTexture(param_mgr->getNormalMapID()); +	} + +	mWaterNormp->addTextureStats(1024.f*1024.f); +	gGL.getTexUnit(bumpTex)->bind(mWaterNormp) ; +	if (gSavedSettings.getBOOL("RenderWaterMipNormal")) +	{ +		mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); +	} +	else  +	{ +		mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT); +	} +	 +	S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);	 +		 +	if (screentex > -1) +	{ +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); +		shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY,  +			param_mgr->getFogDensity()); +		gPipeline.mWaterDis.bindTexture(0, screentex); +	} +	 +	stop_glerror(); +	 +	gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);	 + +	if (mVertexShaderLevel == 1) +	{ +		sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); +	} + +	stop_glerror(); +	 +	S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	stop_glerror(); +	 +	light_dir.normVec(); +	sLightDir = light_dir; +	 +	light_diffuse *= 6.f; + +	//shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix); +	shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth); +	shader->uniform1f(LLShaderMgr::WATER_TIME, sTime); +	shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); +	shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); +	shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); +	shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); +	shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); +	shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); + +	shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV); +	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale()); +	shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset()); +	shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier()); + +	F32 sunAngle = llmax(0.f, light_dir.mV[2]); +	F32 scaledAngle = 1.f - sunAngle; + +	shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle); +	shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle); +	shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle); + +	LLColor4 water_color; +	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); +	F32 up_dot = camera_up * LLVector3::z_axis; +	if (LLViewerCamera::getInstance()->cameraUnderWater()) +	{ +		water_color.setVec(1.f, 1.f, 1.f, 0.4f); +		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); +	} +	else +	{ +		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); +		shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); +	} + +	if (water_color.mV[3] > 0.9f) +	{ +		water_color.mV[3] = 0.9f; +	} + +	{ +		LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); +		LLGLDisable cullface(GL_CULL_FACE); +		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); +			iter != mDrawFace.end(); iter++) +		{ +			LLFace *face = *iter; + +			if (voskyp->isReflFace(face)) +			{ +				continue; +			} + +			LLVOWater* water = (LLVOWater*) face->getViewerObject(); +			gGL.getTexUnit(diffTex)->bind(face->getTexture()); + +			sNeedsReflectionUpdate = TRUE; +			 +			if (water->getUseTexture() || !water->getIsEdgePatch()) +			{ +				sNeedsDistortionUpdate = TRUE; +				face->renderIndexed(); +			} +			else if (gGLManager.mHasDepthClamp || deferred_render) +			{ +				face->renderIndexed(); +			} +			else +			{ +				LLGLSquashToFarClip far_clip(glh_get_current_projection()); +				face->renderIndexed(); +			} +		} +	} +	 +	shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); +	shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);	 +	shader->disableTexture(LLViewerShaderMgr::BUMP_MAP); +	shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); +	shader->disableTexture(LLShaderMgr::WATER_REFTEX); +	shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH); + +	if (deferred_render) +	{ +		gPipeline.unbindDeferredShader(*shader); +	} +	else +	{ +		shader->unbind(); +	} + +	gGL.getTexUnit(0)->activate(); +	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +	if (!deferred_render) +	{ +		gGL.setColorMask(true, false); +	} + +} + +LLViewerTexture *LLDrawPoolWater::getDebugTexture() +{ +	return LLViewerFetchedTexture::sSmokeImagep; +} + +LLColor3 LLDrawPoolWater::getDebugColor() const +{ +	return LLColor3(0.f, 1.f, 1.f); +} diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 3c7a49d5ce..86e5f20812 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -51,7 +51,9 @@  #include "llviewerregion.h"  #include "llviewerwindow.h"  #include "llviewershadermgr.h" +#include "llvoavatar.h" +extern BOOL gGLDebugLoggingEnabled;  #define LL_MAX_INDICES_COUNT 1000000 @@ -328,6 +330,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);  	}		 @@ -1162,6 +1170,15 @@ static LLFastTimer::DeclareTimer FTM_FACE_GEOM_COLOR("Color");  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_FEEDBACK("Face Feedback"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_POSITION("Feedback Position"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_NORMAL("Feedback  Normal"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_TEXTURE("Feedback  Texture"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_COLOR("Feedback  Color"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_EMISSIVE("Feedback  Emissive"); +static LLFastTimer::DeclareTimer FTM_FACE_GEOM_FEEDBACK_BINORMAL("Feedback 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"); @@ -1385,12 +1402,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  #ifdef GL_TRANSFORM_FEEDBACK_BUFFER  	if (use_transform_feedback && +		mVertexBuffer->getUsage() == GL_DYNAMIC_COPY_ARB &&  		gTransformPositionProgram.mProgramObject && //transform shaders are loaded  		mVertexBuffer->useVBOs() && //target buffer is in VRAM  		!rebuild_weights && //TODO: add support for weights  		!volume.isUnique()) //source volume is NOT flexi  	{ //use transform feedback to pack vertex buffer - +		//gGLDebugLoggingEnabled = TRUE; +		LLFastTimer t(FTM_FACE_GEOM_FEEDBACK); +		LLGLEnable discard(GL_RASTERIZER_DISCARD);  		LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();  		if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) @@ -1407,7 +1427,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_pos)  		{ -			LLFastTimer t(FTM_FACE_GEOM_POSITION); +			LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_POSITION);  			gTransformPositionProgram.bind();  			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount); @@ -1420,7 +1440,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			vp[1] = 0;  			vp[2] = 0;  			vp[3] = 0; -						 +			  			gTransformPositionProgram.uniform1i(sTextureIndexIn, val);  			glBeginTransformFeedback(GL_POINTS);  			buff->setBuffer(LLVertexBuffer::MAP_VERTEX); @@ -1432,7 +1452,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_color)  		{ -			LLFastTimer t(FTM_FACE_GEOM_COLOR); +			LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_COLOR);  			gTransformColorProgram.bind();  			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount); @@ -1448,7 +1468,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_emissive)  		{ -			LLFastTimer t(FTM_FACE_GEOM_EMISSIVE); +			LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_EMISSIVE);  			gTransformColorProgram.bind();  			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount); @@ -1469,7 +1489,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_normal)  		{ -			LLFastTimer t(FTM_FACE_GEOM_NORMAL); +			LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_NORMAL);  			gTransformNormalProgram.bind();  			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount); @@ -1482,7 +1502,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_binormal)  		{ -			LLFastTimer t(FTM_FACE_GEOM_BINORMAL); +			LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_BINORMAL);  			gTransformBinormalProgram.bind();  			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount); @@ -1495,7 +1515,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_tcoord)  		{ -			LLFastTimer t(FTM_FACE_GEOM_TEXTURE); +			LLFastTimer t(FTM_FACE_GEOM_FEEDBACK_TEXTURE);  			gTransformTexCoordProgram.bind();  			mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount); @@ -1518,13 +1538,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		}  		glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0); -  		gGL.popMatrix();  		if (cur_shader)  		{  			cur_shader->bind();  		} +		//gGLDebugLoggingEnabled = FALSE;  	}  	else  #endif @@ -1939,21 +1959,31 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_pos)  		{ -			LLFastTimer t(FTM_FACE_GEOM_POSITION); +			LLVector4a* src = vf.mPositions; +			 +			//_mm_prefetch((char*)src, _MM_HINT_T0); + +			LLVector4a* end = src+num_vertices; +			//LLVector4a* end_64 = end-4; + +			//LLFastTimer t(FTM_FACE_GEOM_POSITION);  			llassert(num_vertices > 0);  			mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); -  			LLMatrix4a mat_vert;  			mat_vert.loadu(mat_vert_in); +								 +			F32* dst = (F32*) vert.get(); +			F32* end_f32 = dst+mGeomCount*4; -			LLVector4a* src = vf.mPositions; -			volatile F32* dst = (volatile F32*) vert.get(); - -			volatile F32* end = dst+num_vertices*4; -			LLVector4a res; +			//_mm_prefetch((char*)dst, _MM_HINT_NTA); +			//_mm_prefetch((char*)src, _MM_HINT_NTA); +				 +			//_mm_prefetch((char*)dst, _MM_HINT_NTA); +			LLVector4a res0; //,res1,res2,res3; +			  			LLVector4a texIdx;  			S32 index = mTextureIndex < 255 ? mTextureIndex : 0; @@ -1970,29 +2000,53 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			texIdx.set(0,0,0,val); +			LLVector4a tmp; +  			{ -				LLFastTimer t(FTM_FACE_POSITION_STORE); -				LLVector4a tmp; +				//LLFastTimer t2(FTM_FACE_POSITION_STORE); -				do -				{	 -					mat_vert.affineTransform(*src++, res); -					tmp.setSelectWithMask(mask, texIdx, res); +				/*if (num_vertices > 4) +				{ //more than 64 bytes +					while (src < end_64) +					{	 +						_mm_prefetch((char*)src + 64, _MM_HINT_T0); +						_mm_prefetch((char*)dst + 64, _MM_HINT_T0); + +						mat_vert.affineTransform(*src, res0); +						tmp.setSelectWithMask(mask, texIdx, res0); +						tmp.store4a((F32*) dst); + +						mat_vert.affineTransform(*(src+1), res1); +						tmp.setSelectWithMask(mask, texIdx, res1); +						tmp.store4a((F32*) dst+4); + +						mat_vert.affineTransform(*(src+2), res2); +						tmp.setSelectWithMask(mask, texIdx, res2); +						tmp.store4a((F32*) dst+8); + +						mat_vert.affineTransform(*(src+3), res3); +						tmp.setSelectWithMask(mask, texIdx, res3); +						tmp.store4a((F32*) dst+12); + +						dst += 16; +						src += 4; +					} +				}*/ + +				while (src < end) +				{ +					mat_vert.affineTransform(*src++, res0); +					tmp.setSelectWithMask(mask, texIdx, res0);  					tmp.store4a((F32*) dst);  					dst += 4;  				} -				while(dst < end);  			} - +			  			{ -				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) +				//LLFastTimer t(FTM_FACE_POSITION_PAD); +				while (dst < end_f32)  				{ -					--aligned_pad_vertices; -					res.store4a((F32*) dst); +					res0.store4a((F32*) dst);  					dst += 4;  				}  			} @@ -2006,15 +2060,17 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		if (rebuild_normal)  		{ -			LLFastTimer t(FTM_FACE_GEOM_NORMAL); +			//LLFastTimer t(FTM_FACE_GEOM_NORMAL);  			mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);  			F32* normals = (F32*) norm.get(); -			for (S32 i = 0; i < num_vertices; i++) -			{	 +			LLVector4a* src = vf.mNormals; +			LLVector4a* end = src+num_vertices; +			 +			while (src < end) +			{  				LLVector4a normal; -				mat_normal.rotate(vf.mNormals[i], normal); -				normal.normalize3fast(); +				mat_normal.rotate(*src++, normal);  				normal.store4a(normals);  				normals += 4;  			} @@ -2031,11 +2087,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);  			F32* binormals = (F32*) binorm.get(); -			for (S32 i = 0; i < num_vertices; i++) +			LLVector4a* src = vf.mBinormals; +			LLVector4a* end = vf.mBinormals+num_vertices; + +			while (src < end)  			{	  				LLVector4a binormal; -				mat_normal.rotate(vf.mBinormals[i], binormal); -				binormal.normalize3fast(); +				mat_normal.rotate(*src++, binormal);  				binormal.store4a(binormals);  				binormals += 4;  			} diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 4dfb93f1bc..e7a3f9b390 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -345,7 +345,7 @@ BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)  	return TRUE;  } -static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true); +static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers");  static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1223615079..306f29f703 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -588,7 +588,7 @@ void LLMeshRepoThread::run()  					if (!fetchMeshLOD(req.mMeshParams, req.mLOD, count))//failed, resubmit  					{  						mMutex->lock(); -						mLODReqQ.push(req) ;  +						mLODReqQ.push(req);   						mMutex->unlock();  					}  				} @@ -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. @@ -1919,7 +1918,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,  	if (data_size < mRequestedBytes)  	{ -		if (status == 499 || status == 503) +		if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)  		{ //timeout or service unavailable, try again  			llwarns << "Timeout or service unavailable, retrying." << llendl;  			LLMeshRepository::sHTTPRetryCount++; @@ -1927,7 +1926,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,  		}  		else  		{ -			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint +			llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint  			llwarns << "Unhandled status " << status << llendl;  		}  		return; @@ -1983,7 +1982,7 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason  	if (data_size < mRequestedBytes)  	{ -		if (status == 499 || status == 503) +		if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)  		{ //timeout or service unavailable, try again  			llwarns << "Timeout or service unavailable, retrying." << llendl;  			LLMeshRepository::sHTTPRetryCount++; @@ -1991,7 +1990,7 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason  		}  		else  		{ -			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint +			llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint  			llwarns << "Unhandled status " << status << llendl;  		}  		return; @@ -2046,7 +2045,7 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r  	if (data_size < mRequestedBytes)  	{ -		if (status == 499 || status == 503) +		if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)  		{ //timeout or service unavailable, try again  			llwarns << "Timeout or service unavailable, retrying." << llendl;  			LLMeshRepository::sHTTPRetryCount++; @@ -2054,7 +2053,7 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r  		}  		else  		{ -			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint +			llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint  			llwarns << "Unhandled status " << status << llendl;  		}  		return; @@ -2110,7 +2109,7 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re  	if (data_size < mRequestedBytes)  	{ -		if (status == 499 || status == 503) +		if (status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE)  		{ //timeout or service unavailable, try again  			llwarns << "Timeout or service unavailable, retrying." << llendl;  			LLMeshRepository::sHTTPRetryCount++; @@ -2118,7 +2117,7 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re  		}  		else  		{ -			llassert(status == 499 || status == 503); //intentionally trigger a breakpoint +			llassert(status == HTTP_INTERNAL_ERROR || status == HTTP_SERVICE_UNAVAILABLE); //intentionally trigger a breakpoint  			llwarns << "Unhandled status " << status << llendl;  		}  		return; @@ -2171,16 +2170,16 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,  		//	<< "Header responder failed with status: "  		//	<< status << ": " << reason << llendl; -		// 503 (service unavailable) or 499 (timeout) +		// 503 (service unavailable) or 499 (internal Linden-generated error)  		// can be due to server load and can be retried  		// TODO*: Add maximum retry logic, exponential backoff  		// and (somewhat more optional than the others) retries  		// again after some set period of time -		llassert(status == 503 || status == 499); +		llassert(status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_REQUEST_TIME_OUT || status == HTTP_INTERNAL_ERROR); -		if (status == 503 || status == 499) +		if (status == HTTP_SERVICE_UNAVAILABLE || status == HTTP_REQUEST_TIME_OUT || status == HTTP_INTERNAL_ERROR)  		{ //retry  			llwarns << "Timeout or service unavailable, retrying." << llendl;  			LLMeshRepository::sHTTPRetryCount++; @@ -2192,7 +2191,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,  		}  		else  		{ -			llwarns << "Unhandled status." << llendl; +			llwarns << "Unhandled status: " << status << llendl;  		}  	} diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index ffeea2f4df..9ffc64312d 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -212,13 +212,13 @@ void display_stats()  }  static LLFastTimer::DeclareTimer FTM_PICK("Picking"); -static LLFastTimer::DeclareTimer FTM_RENDER("Render", true); +static LLFastTimer::DeclareTimer FTM_RENDER("Render");  static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky");  static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Image Update Bump"); -static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List"); +static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List", true);  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete");  static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window");  static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update"); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index fc7e51d06c..7d7889845d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -311,47 +311,6 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void)  	if (mReservedAttribs.empty())  	{  		LLShaderMgr::initAttribsAndUniforms(); - -		mAvatarUniforms.push_back(LLStaticHashedString("matrixPalette")); -		mAvatarUniforms.push_back(LLStaticHashedString("gWindDir")); -		mAvatarUniforms.push_back(LLStaticHashedString("gSinWaveParams")); -		mAvatarUniforms.push_back(LLStaticHashedString("gGravity")); - -		mWLUniforms.push_back(LLStaticHashedString("camPosLocal")); - -		mTerrainUniforms.reserve(5); -		mTerrainUniforms.push_back(LLStaticHashedString("detail_0")); -		mTerrainUniforms.push_back(LLStaticHashedString("detail_1")); -		mTerrainUniforms.push_back(LLStaticHashedString("detail_2")); -		mTerrainUniforms.push_back(LLStaticHashedString("detail_3")); -		mTerrainUniforms.push_back(LLStaticHashedString("alpha_ramp")); - -		mGlowUniforms.push_back(LLStaticHashedString("glowDelta")); -		mGlowUniforms.push_back(LLStaticHashedString("glowStrength")); - -		mGlowExtractUniforms.push_back(LLStaticHashedString("minLuminance")); -		mGlowExtractUniforms.push_back(LLStaticHashedString("maxExtractAlpha")); -		mGlowExtractUniforms.push_back(LLStaticHashedString("lumWeights")); -		mGlowExtractUniforms.push_back(LLStaticHashedString("warmthWeights")); -		mGlowExtractUniforms.push_back(LLStaticHashedString("warmthAmount")); - -		mShinyUniforms.push_back(LLStaticHashedString("origin")); - -		mWaterUniforms.reserve(12); -		mWaterUniforms.push_back(LLStaticHashedString("screenTex")); -		mWaterUniforms.push_back(LLStaticHashedString("screenDepth")); -		mWaterUniforms.push_back(LLStaticHashedString("refTex")); -		mWaterUniforms.push_back(LLStaticHashedString("eyeVec")); -		mWaterUniforms.push_back(LLStaticHashedString("time")); -		mWaterUniforms.push_back(LLStaticHashedString("d1")); -		mWaterUniforms.push_back(LLStaticHashedString("d2")); -		mWaterUniforms.push_back(LLStaticHashedString("lightDir")); -		mWaterUniforms.push_back(LLStaticHashedString("specular")); -		mWaterUniforms.push_back(LLStaticHashedString("lightExp")); -		mWaterUniforms.push_back(LLStaticHashedString("fogCol")); -		mWaterUniforms.push_back(LLStaticHashedString("kd")); -		mWaterUniforms.push_back(LLStaticHashedString("refScale")); -		mWaterUniforms.push_back(LLStaticHashedString("waterHeight"));  	}	  } @@ -922,7 +881,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()  		gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));  		gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));  		gTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT]; -		success = gTerrainProgram.createShader(NULL, &mTerrainUniforms); +		success = gTerrainProgram.createShader(NULL, NULL);  	}  	if (!success) @@ -960,7 +919,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));  		gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER]; -		success = gWaterProgram.createShader(NULL, &mWaterUniforms); +		success = gWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -974,7 +933,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gUnderWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_WATER];  		gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gUnderWaterProgram.createShader(NULL, &mWaterUniforms); +		success = gUnderWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -992,7 +951,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()  		gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gTerrainWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_ENVIRONMENT];  		gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, &mTerrainUniforms); +		terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL);  	}	  	/// Keep track of water shader levels @@ -1041,7 +1000,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  		gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));  		gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gGlowProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; -		success = gGlowProgram.createShader(NULL, &mGlowUniforms); +		success = gGlowProgram.createShader(NULL, NULL);  		if (!success)  		{  			LLPipeline::sRenderGlow = FALSE; @@ -1055,7 +1014,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()  		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));  		gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));  		gGlowExtractProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; -		success = gGlowExtractProgram.createShader(NULL, &mGlowExtractUniforms); +		success = gGlowExtractProgram.createShader(NULL, NULL);  		if (!success)  		{  			LLPipeline::sRenderGlow = FALSE; @@ -1415,7 +1374,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredWaterProgram.createShader(NULL, &mWaterUniforms); +		success = gDeferredWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1474,7 +1433,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredAvatarShadowProgram.createShader(NULL, &mAvatarUniforms); +		success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1495,7 +1454,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredTerrainProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredTerrainProgram.createShader(NULL, &mTerrainUniforms); +		success = gDeferredTerrainProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1506,7 +1465,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB));  		gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredAvatarProgram.createShader(NULL, &mAvatarUniforms); +		success = gDeferredAvatarProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1526,7 +1485,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaNonIndexedNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; -		success = gDeferredAvatarAlphaProgram.createShader(NULL, &mAvatarUniforms); +		success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);  		gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = true;  		gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; @@ -1591,7 +1550,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gDeferredWLSkyProgram.createShader(NULL, &mWLUniforms); +		success = gDeferredWLSkyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1602,7 +1561,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gDeferredWLCloudProgram.createShader(NULL, &mWLUniforms); +		success = gDeferredWLCloudProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1613,7 +1572,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  		gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB));  		gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gDeferredStarProgram.createShader(NULL, &mWLUniforms); +		success = gDeferredStarProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1964,7 +1923,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		  		gObjectShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -		success = gObjectShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectShinyNonIndexedProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1981,7 +1940,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectShinyNonIndexedWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -1997,7 +1956,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyNonIndexedProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectFullbrightShinyNonIndexedProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2015,7 +1974,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectFullbrightShinyNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectFullbrightShinyNonIndexedWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2094,7 +2053,6 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		success = gObjectBumpProgram.createShader(NULL, NULL); -  		if (success)  		{ //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1  			gObjectBumpProgram.bind(); @@ -2248,7 +2206,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));		  		gObjectShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -		success = gObjectShinyProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectShinyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2265,7 +2223,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectShinyWaterProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectShinyWaterProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2281,7 +2239,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -		success = gObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectFullbrightShinyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2299,7 +2257,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  		gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  		gObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT];  		gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; -		success = gObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); +		success = gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);  	}  	if (mVertexShaderLevel[SHADER_AVATAR] > 0) @@ -2384,7 +2342,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));  			gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); +			success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, NULL);  		}  		if (success) @@ -2401,7 +2359,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));  			gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectShinySimpleProgram.createShader(NULL, &mShinyUniforms); +			success = gSkinnedObjectShinySimpleProgram.createShader(NULL, NULL);  		}  		if (success) @@ -2458,7 +2416,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  			gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); +			success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);  		}  		if (success) @@ -2477,7 +2435,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));  			gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));  			gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; -			success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, &mShinyUniforms); +			success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, NULL);  		}  	} @@ -2518,7 +2476,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));  		gAvatarProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; -		success = gAvatarProgram.createShader(NULL, &mAvatarUniforms); +		success = gAvatarProgram.createShader(NULL, NULL);  		if (success)  		{ @@ -2537,7 +2495,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  			// Note: no cloth under water:  			gAvatarWaterProgram.mShaderLevel = llmin(mVertexShaderLevel[SHADER_AVATAR], 1);	  			gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;				 -			success = gAvatarWaterProgram.createShader(NULL, &mAvatarUniforms); +			success = gAvatarWaterProgram.createShader(NULL, NULL);  		}  		/// Keep track of avatar levels @@ -2556,7 +2514,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()  		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));  		gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));  		gAvatarPickProgram.mShaderLevel = mVertexShaderLevel[SHADER_AVATAR]; -		success = gAvatarPickProgram.createShader(NULL, &mAvatarUniforms); +		success = gAvatarPickProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2824,7 +2782,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  		gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB));  		gWLSkyProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT];  		gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gWLSkyProgram.createShader(NULL, &mWLUniforms); +		success = gWLSkyProgram.createShader(NULL, NULL);  	}  	if (success) @@ -2836,7 +2794,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()  		gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));  		gWLCloudProgram.mShaderLevel = mVertexShaderLevel[SHADER_WINDLIGHT];  		gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY; -		success = gWLCloudProgram.createShader(NULL, &mWLUniforms); +		success = gWLCloudProgram.createShader(NULL, NULL);  	}  	return success; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 999baa0ad0..6cd52dc736 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -74,56 +74,7 @@ public:  		SHADER_COUNT  	}; -	typedef enum -	{ -		SHINY_ORIGIN = END_RESERVED_UNIFORMS -	} eShinyUniforms; - -	typedef enum -	{ -		WATER_SCREENTEX = END_RESERVED_UNIFORMS, -		WATER_SCREENDEPTH, -		WATER_REFTEX, -		WATER_EYEVEC, -		WATER_TIME, -		WATER_WAVE_DIR1, -		WATER_WAVE_DIR2, -		WATER_LIGHT_DIR, -		WATER_SPECULAR, -		WATER_SPECULAR_EXP, -		WATER_FOGCOLOR, -		WATER_FOGDENSITY, -		WATER_REFSCALE, -		WATER_WATERHEIGHT, -	} eWaterUniforms; - -	typedef enum -	{ -		WL_CAMPOSLOCAL = END_RESERVED_UNIFORMS, -		WL_WATERHEIGHT -	} eWLUniforms; - -	typedef enum -	{ -		TERRAIN_DETAIL0 = END_RESERVED_UNIFORMS, -		TERRAIN_DETAIL1, -		TERRAIN_DETAIL2, -		TERRAIN_DETAIL3, -		TERRAIN_ALPHARAMP -	} eTerrainUniforms; - -	typedef enum -	{ -		GLOW_DELTA = END_RESERVED_UNIFORMS -	} eGlowUniforms; - -	typedef enum -	{ -		AVATAR_MATRIX = END_RESERVED_UNIFORMS, -		AVATAR_WIND, -		AVATAR_SINWAVE, -		AVATAR_GRAVITY, -	} eAvatarUniforms; +	  	// simple model of forward iterator  	// http://www.sgi.com/tech/stl/ForwardIterator.html @@ -176,25 +127,6 @@ public:  	/* virtual */ void updateShaderUniforms(LLGLSLShader * shader);  private: -	 -	typedef std::vector< LLStaticHashedString > UniformVec; - -	UniformVec mShinyUniforms; - -	//water parameters -	UniformVec mWaterUniforms; - -	UniformVec mWLUniforms; - -	//terrain parameters -	UniformVec mTerrainUniforms; - -	//glow parameters -	UniformVec mGlowUniforms; - -	UniformVec mGlowExtractUniforms; - -	UniformVec mAvatarUniforms;  	// the list of shaders we need to propagate parameters to.  	std::vector<LLGLSLShader *> mShaderList; 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..7adf18b6d0 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -99,6 +99,8 @@ static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");  static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");  static LLFastTimer::DeclareTimer FTM_VOLUME_TEXTURES("Volume Textures"); +extern BOOL gGLDebugLoggingEnabled; +  // Implementation class of LLMediaDataClientObject.  See llmediadataclient.h  class LLMediaDataClientObjectImpl : public LLMediaDataClientObject  { @@ -1067,7 +1069,9 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  					break;  				}  				volume->genBinormals(i); +				//gGLDebugLoggingEnabled = TRUE;  				LLFace::cacheFaceInVRAM(face); +				//gGLDebugLoggingEnabled = FALSE;  			}  		} @@ -1116,6 +1120,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 @@ -3836,10 +3846,13 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  	}  	//build matrix palette -	LLMatrix4a mp[64]; +	static const size_t kMaxJoints = 64; + +	LLMatrix4a mp[kMaxJoints];  	LLMatrix4* mat = (LLMatrix4*) mp; -	for (U32 j = 0; j < skin->mJointNames.size(); ++j) +	U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints); +	for (U32 j = 0; j < maxJoints; ++j)  	{  		LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);  		if (joint) @@ -3894,8 +3907,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  						F32 w = wght[k];  						LLMatrix4a src; -						src.setMul(mp[idx[k]], w); - +						// Insure ref'd bone is in our clamped array of mats +						llassert(idx[k] < kMaxJoints); +						// clamp k to kMaxJoints to avoid reading garbage off stack in release +						src.setMul(mp[idx[(k < kMaxJoints) ? k : 0]], w);  						final_mat.add(src);  					} @@ -4644,7 +4659,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		bump_mask |= LLVertexBuffer::MAP_BINORMAL;  		genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, TRUE);  		genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, TRUE); -		genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, TRUE); +		genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, FALSE);  		genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, TRUE);  	}  	else @@ -4830,6 +4845,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  	U32 buffer_usage = group->mBufferUsage; +	static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); + +	if (use_transform_feedback && +		gTransformPositionProgram.mProgramObject && //transform shaders are loaded +		buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM +		!(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights +	{ +		buffer_usage = GL_DYNAMIC_COPY_ARB; +	} +  #if LL_DARWIN  	// HACK from Leslie:  	// Disable VBO usage for alpha on Mac OS X because it kills the framerate @@ -4889,6 +4914,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  	//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)  	texture_index_channels = llmin(texture_index_channels, 16); +	bool flexi = false; +  	while (face_iter != faces.end())  	{  		//pull off next face @@ -4915,6 +4942,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  		U32 index_count = facep->getIndicesCount();  		U32 geom_count = facep->getGeomCount(); +		flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); +  		//sum up vertices needed for this render batch  		std::vector<LLFace*>::iterator i = face_iter;  		++i; @@ -4983,6 +5012,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  						}  						++i; + +						flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); +  						index_count += facep->getIndicesCount();  						geom_count += facep->getGeomCount(); @@ -5012,8 +5044,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  					++i;  					index_count += facep->getIndicesCount();  					geom_count += facep->getGeomCount(); + +					flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); +				}  				}  			} + + +		if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB) +		{ +			buffer_usage = GL_STREAM_DRAW_ARB;  		}  		//create vertex buffer diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 376715a2d6..548890b5b5 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -57,14 +57,6 @@  #include "curl/curl.h" -static LLStaticHashedString sCamPosLocal("camPosLocal");
 -static LLStaticHashedString sWaterFogColor("waterFogColor");
 -static LLStaticHashedString sWaterFogEnd("waterFogEnd");
 -static LLStaticHashedString sWaterPlane("waterPlane");
 -static LLStaticHashedString sWaterFogDensity("waterFogDensity");
 -static LLStaticHashedString sWaterFogKS("waterFogKS");
 -static LLStaticHashedString sDistanceMultiplier("distance_multiplier"); -  LLWaterParamManager::LLWaterParamManager() :  	mFogColor(22.f/255.f, 43.f/255.f, 54.f/255.f, 0.0f, 0.0f, "waterFogColor", "WaterFogColor"),  	mFogDensity(4, "waterFogDensity", 2), @@ -196,13 +188,11 @@ void LLWaterParamManager::updateShaderUniforms(LLGLSLShader * shader)  	if (shader->mShaderGroup == LLGLSLShader::SG_WATER)  	{  		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, LLWLParamManager::getInstance()->getRotatedLightDir().mV); -		shader->uniform3fv(sCamPosLocal, 1, LLViewerCamera::getInstance()->getOrigin().mV); -		shader->uniform4fv(sWaterFogColor, 1, LLDrawPoolWater::sWaterFogColor.mV); -		shader->uniform1f(sWaterFogEnd, LLDrawPoolWater::sWaterFogEnd); -		shader->uniform4fv(sWaterPlane, 1, mWaterPlane.mV); -		shader->uniform1f(sWaterFogDensity, getFogDensity()); -		shader->uniform1f(sWaterFogKS, mWaterFogKS); -		shader->uniform1f(sDistanceMultiplier, 0); +		shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, LLDrawPoolWater::sWaterFogColor.mV); +		shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, mWaterPlane.mV); +		shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, getFogDensity()); +		shader->uniform1f(LLShaderMgr::WATER_FOGKS, mWaterFogKS); +		shader->uniform1f(LLViewerShaderMgr::DISTANCE_MULTIPLIER, 0);  	}  } diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 65cb80c3e7..04d41a2512 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -61,9 +61,6 @@  #include "curl/curl.h"  #include "llstreamtools.h" -static LLStaticHashedString sCamPosLocal("camPosLocal"); -static LLStaticHashedString sSceneLightStrength("scene_light_strength"); -  LLWLParamManager::LLWLParamManager() :  	//set the defaults for the controls @@ -355,7 +352,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)  	if (shader->mShaderGroup == LLGLSLShader::SG_DEFAULT)  	{  		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mRotatedLightDir.mV); -		shader->uniform3fv(sCamPosLocal, 1, LLViewerCamera::getInstance()->getOrigin().mV); +		shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);  	}   	else if (shader->mShaderGroup == LLGLSLShader::SG_SKY) @@ -363,7 +360,7 @@ void LLWLParamManager::updateShaderUniforms(LLGLSLShader * shader)  		shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mClampedLightDir.mV);  	} -	shader->uniform1f(sSceneLightStrength, mSceneLightStrength); +	shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);  } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 92c5ac8583..54a62a858a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -253,15 +253,15 @@ LLFastTimer::DeclareTimer FTM_RENDER_DEFERRED("Deferred Shading");  static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables");  static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort"); -static LLStaticHashedString sTint("tint");
 -static LLStaticHashedString sAmbiance("ambiance");
 -static LLStaticHashedString sAlphaScale("alpha_scale");
 -static LLStaticHashedString sNormMat("norm_mat");
 -static LLStaticHashedString sOffset("offset");
 -static LLStaticHashedString sScreenRes("screenRes");
 -static LLStaticHashedString sDelta("delta");
 -static LLStaticHashedString sDistFactor("dist_factor");
 -static LLStaticHashedString sKern("kern");
 +static LLStaticHashedString sTint("tint"); +static LLStaticHashedString sAmbiance("ambiance"); +static LLStaticHashedString sAlphaScale("alpha_scale"); +static LLStaticHashedString sNormMat("norm_mat"); +static LLStaticHashedString sOffset("offset"); +static LLStaticHashedString sScreenRes("screenRes"); +static LLStaticHashedString sDelta("delta"); +static LLStaticHashedString sDistFactor("dist_factor"); +static LLStaticHashedString sKern("kern");  static LLStaticHashedString sKernScale("kern_scale");  //---------------------------------------- @@ -7868,13 +7868,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n  	shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight());  	shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);  	shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); -	 -	static LLStaticHashedString sNormMat("norm_mat"); -	if (shader.getUniformLocation(sNormMat) >= 0) -	{ -		glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); -		shader.uniformMatrix4fv(sNormMat, 1, FALSE, norm_mat.m); -	}  }  static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace"); @@ -7984,8 +7977,7 @@ void LLPipeline::renderDeferredLighting()  				}  				gDeferredSunProgram.uniform3fv(sOffset, slice, offset); -				gDeferredSunProgram.uniform2f(sScreenRes, mDeferredLight.getWidth(), mDeferredLight.getHeight()); -				 +								  				{  					LLGLDisable blend(GL_BLEND);  					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); @@ -10258,6 +10250,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(); @@ -10272,6 +10271,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		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) @@ -10285,6 +10286,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		if (muted)  		{  			gGL.setColorMask(true, true); +  		}  		else  		{ @@ -10303,14 +10305,24 @@ 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); + +		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); @@ -10318,10 +10330,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  		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> | 
