diff options
41 files changed, 840 insertions, 206 deletions
| diff --git a/doc/contributions.txt b/doc/contributions.txt index c98c974e62..88322bdfe1 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -217,6 +217,7 @@ Ansariel Hiller  	MAINT-6519  	MAINT-7899  	STORM-2105 +	MAINT-6917  Aralara Rajal  Arare Chantilly  	CHUIBUG-191 diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8b73f0ae8e..8d5e9de76b 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -545,7 +545,7 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3  {  	// Generate an n-sided "circular" path.  	// 0 is (1,0), and we go counter-clockwise along a circular path from there. -	const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; +	static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };  	F32 scale = 0.5f;  	F32 t, t_step, t_first, t_fraction, ang, ang_step;  	LLVector4a pt1,pt2; @@ -1304,7 +1304,7 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff  void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)  {  	// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane. -	const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f }; +	static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };  	F32 revolutions = params.getRevolutions();  	F32 skew		= params.getSkew(); @@ -1602,7 +1602,8 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,  			if (is_sculpted)  				sides = llmax(sculpt_size, 1); -			genNGon(params, sides); +			if (0 < sides) +				genNGon(params, sides);  		}  		break; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index bba691d243..65fbc4685e 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1088,7 +1088,7 @@ public:  	F32 mSurfaceArea; //unscaled surface area  	BOOL mIsMeshAssetLoaded; -	LLVolumeParams mParams; +	const LLVolumeParams mParams;  	LLPath *mPathp;  	LLProfile *mProfilep;  	LLAlignedArray<LLVector4a,64> mMesh; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index bfa65666b5..edf7c41e40 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -732,6 +732,16 @@ S32	face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& fac  BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)  { +	if (NO_LOD == detail) +	{ +		// build the new object +		setChanged(GEOMETRY); +		sVolumeManager->unrefVolume(mVolumep); +		mVolumep = new LLVolume(volume_params, 1, TRUE, TRUE); +		setNumTEs(mVolumep->getNumFaces()); +		return FALSE; +	} +  	LLVolume *volumep;  	if (unique_volume)  	{ diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 19d9d52817..99a32e614c 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -489,6 +489,11 @@ protected:  public:  	static LLVolumeMgr* sVolumeManager; + +	enum +	{ +		NO_LOD = -1 +	};  };  inline BOOL LLPrimitive::isAvatar() const diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 331f988382..07a0d8c402 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -51,6 +51,7 @@ set(llrender_SOURCE_FILES      lltexture.cpp      lluiimage.cpp      llvertexbuffer.cpp +    llglcommonfunc.cpp      )  set(llrender_HEADER_FILES @@ -78,6 +79,7 @@ set(llrender_HEADER_FILES      lltexture.h      lluiimage.h      llvertexbuffer.h +    llglcommonfunc.h      )  set_source_files_properties(${llrender_HEADER_FILES} diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index aa98b3f6bc..4c4302d05b 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -256,6 +256,9 @@ void clear_glerror();  	if the existing GL state does not match the expected GL state.  */ + +#include "boost/function.hpp" +  class LLGLState  {  public: @@ -297,6 +300,20 @@ public:  	LLGLEnableAlphaReject(bool enable);  }; +// Enable with functor +class LLGLEnableFunc : LLGLState +{ +public: +	LLGLEnableFunc(LLGLenum state, bool enable, boost::function<void()> func) +		: LLGLState(state, enable) +	{ +		if (enable) +		{ +			func(); +		} +	} +}; +  /// TODO: Being deprecated.  class LLGLEnable : public LLGLState  { diff --git a/indra/llrender/llglcommonfunc.cpp b/indra/llrender/llglcommonfunc.cpp new file mode 100644 index 0000000000..e9ec28927f --- /dev/null +++ b/indra/llrender/llglcommonfunc.cpp @@ -0,0 +1,37 @@ +/** +* @file llglcommonfunc.cpp +* @brief Implementation of the LLGLCommonFunc. +* +* $LicenseInfo:firstyear=2001&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 "llglheaders.h" +#include "llglcommonfunc.h" + +namespace LLGLCommonFunc  +{ +	void selected_stencil_test() +	{ +		glStencilFunc(GL_ALWAYS, 2, 0xffff); +		glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); +	} +} diff --git a/indra/llrender/llglcommonfunc.h b/indra/llrender/llglcommonfunc.h new file mode 100644 index 0000000000..f1f8ff7bc4 --- /dev/null +++ b/indra/llrender/llglcommonfunc.h @@ -0,0 +1,30 @@ +/** +* @file llphoenixfunc.h +* @brief File include common opengl code snippets +* +* $LicenseInfo:firstyear=2003&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$ +*/ + +namespace LLGLCommonFunc +{ +	void selected_stencil_test(); +} diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 970502f2d6..97557267cf 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -744,24 +744,25 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)  	, even if the "diffuseMap" will be appear and use first in shader code.  	As example where this situation appear see: "Deferred Material Shader 28/29/30/31" -	And tickets: MAINT-4165, MAINT-4839, MAINT-3568 +	And tickets: MAINT-4165, MAINT-4839, MAINT-3568, MAINT-6437  	*/  	S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap"); +	S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");  	S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");  	S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");  	std::set<S32> skip_index; -	if (-1 != diffuseMap && (-1 != bumpMap || -1 != environmentMap)) +	if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap))  	{  		GLenum type;  		GLsizei length;  		GLint size = -1;  		char name[1024]; -		diffuseMap = bumpMap = environmentMap = -1; +		diffuseMap = specularMap = bumpMap = environmentMap = -1;  		for (S32 i = 0; i < activeCount; i++)  		{ @@ -775,6 +776,18 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)  				continue;  			} +			if (-1 == specularMap && std::string(name) == "specularMap") +			{ +				specularMap = i; +				continue; +			} + +			if (-1 == specularMap && std::string(name) == "specularMap") +			{ +				specularMap = i; +				continue; +			} +  			if (-1 == bumpMap && std::string(name) == "bumpMap")  			{  				bumpMap = i; @@ -788,34 +801,29 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)  			}  		} +		bool specularDiff = specularMap < diffuseMap && -1 != specularMap;  		bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;  		bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap; -		if (bumpLessDiff && envLessDiff) +		if (specularDiff || bumpLessDiff || envLessDiff)  		{  			mapUniform(diffuseMap, uniforms); -			mapUniform(bumpMap, uniforms); -			mapUniform(environmentMap, uniforms); -  			skip_index.insert(diffuseMap); -			skip_index.insert(bumpMap); -			skip_index.insert(environmentMap); -		} -		else if (bumpLessDiff) -		{ -			mapUniform(diffuseMap, uniforms); -			mapUniform(bumpMap, uniforms); -			skip_index.insert(diffuseMap); -			skip_index.insert(bumpMap); -		} -		else if (envLessDiff) -		{ -			mapUniform(diffuseMap, uniforms); -			mapUniform(environmentMap, uniforms); +			if (-1 != specularMap) { +				mapUniform(specularMap, uniforms); +				skip_index.insert(specularMap); +			} -			skip_index.insert(diffuseMap); -			skip_index.insert(environmentMap); +			if (-1 != bumpMap) { +				mapUniform(bumpMap, uniforms); +				skip_index.insert(bumpMap); +			} + +			if (-1 != environmentMap) { +				mapUniform(environmentMap, uniforms); +				skip_index.insert(environmentMap); +			}  		}  	} diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 5048799854..7e47471db6 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -509,7 +509,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)  				}  			} -			U32 map_tc[] =  +			static const U32 map_tc[] =   			{  				MAP_TEXCOORD1,  				MAP_TEXCOORD2, diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 77065dcf8d..8136a3e88a 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -357,7 +357,8 @@ private:  		mCachedValue = convert_from_llsd<T>(controlp->get(), mType, name);  		// Add a listener to the controls signal... -		mConnection = controlp->getSignal()->connect( +		// NOTE: All listeners connected to 0 group, for guaranty that variable handlers (gSavedSettings) call last +		mConnection = controlp->getSignal()->connect(0,  			boost::bind(&LLControlCache<T>::handleValueChange, this, _2)  			);  		mType = controlp->type(); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 2100c91cfe..1594711197 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -528,6 +528,7 @@ set(viewer_SOURCE_FILES      llscriptfloater.cpp      llscrollingpanelparam.cpp      llscrollingpanelparambase.cpp +    llsculptidsize.cpp      llsearchcombobox.cpp      llsearchhistory.cpp      llsecapi.cpp @@ -1140,6 +1141,7 @@ set(viewer_HEADER_FILES      llscriptruntimeperms.h      llscrollingpanelparam.h      llscrollingpanelparambase.h +    llsculptidsize.h      llsearchcombobox.h      llsearchhistory.h      llsecapi.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4a4f4bfc61..7c3867bdfb 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4646,6 +4646,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>IgnoreFOVZoomForLODs</key> +    <map> +      <key>Comment</key> +      <string>Ignore zoom effect(CTRL+0) when calculating lods.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>IgnoreAllNotifications</key>      <map>        <key>Comment</key> @@ -10158,9 +10169,9 @@    <key>RenderAutoMuteByteLimit</key>    <map>      <key>Comment</key> -    <string>OBSOLETE and UNUSED.</string> +    <string>If avatar attachment size exceed this value (in bytes) attachment will not be rendered. Excludes attachments worn by own avatar.</string>      <key>Persist</key> -    <integer>0</integer> +    <integer>1</integer>      <key>Type</key>      <string>U32</string>      <key>Value</key> diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index f956023358..6ca8f1ae9c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -50,6 +50,7 @@  #include "llviewerobjectlist.h"  #include "llviewerwindow.h"  #include "llvocache.h" +#include "lldrawpoolavatar.h"  const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;  const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -143,6 +144,28 @@ void LLDrawable::init(bool new_entry)  	initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.  } +void LLDrawable::unload() +{ +	LLVOVolume *pVVol = getVOVolume(); +	pVVol->setNoLOD(); + +	for (S32 i = 0; i < getNumFaces(); i++) +	{ +		LLFace* facep = getFace(i); +		if (facep->isState(LLFace::RIGGED)) +		{ +			LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); +			if (pool) { +				pool->removeRiggedFace(facep); +			} +			facep->setVertexBuffer(NULL); +		} +		facep->clearState(LLFace::RIGGED); +	} + +	pVVol->markForUpdate(TRUE); +} +  // static  void LLDrawable::initClass()  { @@ -595,7 +618,7 @@ F32 LLDrawable::updateXform(BOOL undamped)  	BOOL damped = !undamped;  	// Position -	LLVector3 old_pos(mXform.getPosition()); +	const LLVector3 old_pos(mXform.getPosition());  	LLVector3 target_pos;  	if (mXform.isRoot())  	{ @@ -609,7 +632,7 @@ F32 LLDrawable::updateXform(BOOL undamped)  	}  	// Rotation -	LLQuaternion old_rot(mXform.getRotation()); +	const LLQuaternion old_rot(mXform.getRotation());  	LLQuaternion target_rot = mVObjp->getRotation();  	//scaling  	LLVector3 target_scale = mVObjp->getScale(); @@ -644,6 +667,9 @@ F32 LLDrawable::updateXform(BOOL undamped)  		{  			// snap to final position (only if no target omega is applied)  			dist_squared = 0.0f; +			//set target scale here, because of dist_squared = 0.0f remove object from move list +			mCurrentScale = target_scale; +  			if (getVOVolume() && !isRoot())  			{ //child prim snapping to some position, needs a rebuild  				gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); @@ -660,11 +686,16 @@ F32 LLDrawable::updateXform(BOOL undamped)  		//dist_squared += dist_vec_squared(old_scale, target_scale);  	} -	LLVector3 vec = mCurrentScale-target_scale; +	const LLVector3 vec = mCurrentScale-target_scale; +	 +	//It's a very important on each cycle on Drawable::update form(), when object remained in move +	//, list update the CurrentScale member, because if do not do that, it remained in this list forever  +	//or when the delta time between two frames a become a sufficiently large (due to interpolation)  +	//for overcome the MIN_INTERPOLATE_DISTANCE_SQUARED. +	mCurrentScale = target_scale;  	if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)  	{ //scale change requires immediate rebuild -		mCurrentScale = target_scale;  		gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);  	}  	else if (!isRoot() &&  @@ -979,9 +1010,7 @@ void LLDrawable::updateSpatialExtents()  	if (mVObjp)  	{  		const LLVector4a* exts = getSpatialExtents(); -		LLVector4a extents[2]; -		extents[0] = exts[0]; -		extents[1] = exts[1]; +		LLVector4a extents[2] = { exts[0], exts[1] };  		mVObjp->updateSpatialExtents(extents[0], extents[1]);  		setSpatialExtents(extents[0], extents[1]); diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index a3461d4c01..14d782d6f2 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -84,6 +84,7 @@ public:  	void markDead();			// Mark this drawable as dead  	BOOL isDead() const			{ return isState(DEAD); }  	BOOL isNew() const			{ return !isState(BUILT); } +	BOOL isUnload() const		{ return isState(FOR_UNLOAD); }  	BOOL isLight() const; @@ -141,6 +142,7 @@ public:  	void				mergeFaces(LLDrawable* src);  	void init(bool new_entry); +	void unload();  	void destroy();  	void update(); @@ -282,6 +284,7 @@ public:  		PARTITION_MOVE	= 0x10000000,  		ANIMATED_CHILD  = 0x20000000,  		ACTIVE_CHILD	= 0x40000000, +		FOR_UNLOAD		= 0x80000000, //should be unload from memory  	} EDrawableFlags;  public: diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index f74164aea6..075375082d 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -49,6 +49,7 @@  #include "llviewercamera.h"  #include "lldrawpoolwlsky.h"  #include "llglslshader.h" +#include "llglcommonfunc.h"  S32 LLDrawPool::sNumDrawPools = 0; @@ -504,7 +505,9 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba  		{  			params.mGroup->rebuildMesh();  		} -		 + +		LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); +	  		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/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 60056ac21d..32630237ce 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -47,6 +47,7 @@  #include "llviewerregion.h"  #include "lldrawpoolwater.h"  #include "llspatialpartition.h" +#include "llglcommonfunc.h"  BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; @@ -583,11 +584,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  				{  					LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH); -    gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);					 -				params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); -                 -				params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); -				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + +					LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); + +					gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); +					params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); + +					params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); +					gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);  				}  				// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow).  Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. @@ -597,7 +601,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)  				{  					// install glow-accumulating blend mode  					gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color -						      LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) +					LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)  					emissive_shader->bind(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 8128790eb6..ef69990170 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1574,6 +1574,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(  	LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();  	LLDrawable* drawable = face->getDrawable(); +	if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD()) +	{ +		return; +	} +  	U32 data_mask = face->getRiggedVertexBufferDataMask();      if (!vol_face.mWeightsScrubbed) @@ -1621,7 +1626,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(  		return;  	} -	if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime()) +	if (!buffer.isNull() &&  +		sShaderLevel <= 0 &&  +		face->mLastSkinTime < avatar->getLastSkinTime())  	{  		//perform software vertex skinning for this face  		LLStrider<LLVector3> position; @@ -1914,7 +1921,7 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)  			LLVOVolume* vobj = drawable->getVOVolume(); -			if (!vobj) +			if (!vobj || vobj->isNoLOD())  			{  				continue;  			} diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index f92320490a..63e96a93b5 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -30,6 +30,7 @@  #include "lldrawpoolmaterials.h"  #include "llviewershadermgr.h"  #include "pipeline.h" +#include "llglcommonfunc.h"  S32 diffuse_channel = -1; @@ -211,6 +212,9 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,  	{  		params.mGroup->rebuildMesh();  	} + +	LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); +  	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/llface.cpp b/indra/newview/llface.cpp index 50a4925c37..7f7d7f3dcc 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -53,6 +53,7 @@  #include "llviewershadermgr.h"  #include "llviewertexture.h"  #include "llvoavatar.h" +#include "llsculptidsize.h"  #if LL_LINUX  // Work-around spurious used before init warning on Vector4a @@ -2650,12 +2651,27 @@ LLViewerTexture* LLFace::getTexture(U32 ch) const  void LLFace::setVertexBuffer(LLVertexBuffer* buffer)  { +	if (buffer) +	{ +		LLSculptIDSize::instance().inc(mDrawablep, buffer->getSize() + buffer->getIndicesSize()); +	} + +	if (mVertexBuffer) +	{ +		LLSculptIDSize::instance().dec(mDrawablep); +	} +  	mVertexBuffer = buffer;  	llassert(verify());  }  void LLFace::clearVertexBuffer()  { +	if (mVertexBuffer) +	{ +		LLSculptIDSize::instance().dec(mDrawablep); +	} +  	mVertexBuffer = NULL;  } diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 785022792b..92a09357c8 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1060,6 +1060,7 @@ void LLManipTranslate::render()  		renderGuidelines();  	}  	{ +		LLGLDisable gls_stencil(GL_STENCIL_TEST);  		renderTranslationHandles();  		renderSnapGuides();  	} @@ -1638,8 +1639,8 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,  	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; -	U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY }; -	U32 num_types = LL_ARRAY_SIZE(types); +	static const U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY }; +	static const U32 num_types = LL_ARRAY_SIZE(types);  	GLuint stencil_mask = 0xFFFFFFFF;  	//stencil in volumes diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index df708013fc..9edffea1c1 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3945,7 +3945,7 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3  S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)  { -	if (mThread && mesh_id.notNull()) +	if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod)  	{  		LLMutexLock lock(mThread->mHeaderMutex);  		LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); diff --git a/indra/newview/llsculptidsize.cpp b/indra/newview/llsculptidsize.cpp new file mode 100644 index 0000000000..9edd78bff0 --- /dev/null +++ b/indra/newview/llsculptidsize.cpp @@ -0,0 +1,154 @@ +/** +* @file llsculptidsize.cpp +* @brief LLSculptIDSize 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 "llsculptidsize.h" +#include "llvovolume.h" +#include "lldrawable.h" +#include "llvoavatar.h" +//boost +#include "boost/make_shared.hpp" + +//........... + +extern LLControlGroup gSavedSettings; + +//........... + +typedef std::pair<LLSculptIDSize::container_BY_SCULPT_ID_view::iterator, LLSculptIDSize::container_BY_SCULPT_ID_view::iterator> pair_iter_iter_BY_SCULPT_ID_t; + +//........... + +void _nothing_to_do_func(int) { /*nothing todo here because of the size it's a shared member*/ } + +void LLSculptIDSize::inc(const LLDrawable *pdrawable, int sz) +{ +	llassert(sz >= 0); + +	if (!pdrawable) return; +	LLVOVolume* vvol = pdrawable->getVOVolume(); +	if (!vvol) return; +	if (!vvol->isAttachment()) return; +	if (!vvol->getAvatar()) return; +	if (vvol->getAvatar()->isSelf()) return; +	LLVolume *vol = vvol->getVolume(); +	if (!vol) return; + +	const LLUUID &sculptId = vol->getParams().getSculptID(); +	if (sculptId.isNull()) return; + +	unsigned int total_size = 0; + +	pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId); +	if (itLU.first == itLU.second) +	{ //register +		llassert(mSizeInfo.get<tag_BY_DRAWABLE>().end() == mSizeInfo.get<tag_BY_DRAWABLE>().find(pdrawable)); +		mSizeInfo.get<tag_BY_DRAWABLE>().insert(Info(pdrawable, sz, boost::make_shared<SizeSum>(sz), sculptId)); +		total_size = sz; +	} +	else +	{ //update + register +		Info &nfo = const_cast<Info &>(*itLU.first); +		//calc new size +		total_size = nfo.getSizeSum() + sz; +		nfo.mSharedSizeSum->mSizeSum = total_size; +		nfo.mSize = sz; +		//update size for all LLDrwable in range of sculptId +		for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first; it != itLU.second; ++it) +		{ +			mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1)); +		} + +		//trying insert the LLDrawable +		mSizeInfo.get<tag_BY_DRAWABLE>().insert(Info(pdrawable, sz, nfo.mSharedSizeSum, sculptId)); +	} + +	static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U); + +	if (0 != render_auto_mute_byte_limit && total_size > render_auto_mute_byte_limit) +	{ +		pair_iter_iter_BY_SCULPT_ID_t it_eqr = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId); +		for (; it_eqr.first != it_eqr.second; ++it_eqr.first) +		{ +			const Info &i = *it_eqr.first; +			LLVOVolume *pVVol = i.mDrawable->getVOVolume(); +			if (pVVol +				&& !pVVol->isDead() +				&& pVVol->isAttachment() +				&& !pVVol->getAvatar()->isSelf() +				&& LLVOVolume::NO_LOD != pVVol->getLOD() +				) +			{ +				addToUnloaded(sculptId); +				//immediately +				const_cast<LLDrawable*>(i.mDrawable)->unload(); +			} +		} +	} +} + +void LLSculptIDSize::dec(const LLDrawable *pdrawable) +{ +	container_BY_DRAWABLE_view::iterator it = mSizeInfo.get<tag_BY_DRAWABLE>().find(pdrawable); +	if (mSizeInfo.get<tag_BY_DRAWABLE>().end() == it) return; + +	unsigned int size = it->getSizeSum() - it->getSize(); + +	if (0 == size) +	{ +		mSizeInfo.get<tag_BY_SCULPT_ID>().erase(it->getSculptId()); +	} +	else +	{ +		Info &nfo = const_cast<Info &>(*it); +		nfo.mSize = 0; +		pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(it->getSculptId()); +		it->mSharedSizeSum->mSizeSum = size; +		for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first; it != itLU.second; ++it) +		{ +			mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1)); +		} +	} +} + +void LLSculptIDSize::rem(const LLUUID &sculptId) +{ +	mSizeInfo.get<tag_BY_SCULPT_ID>().erase(sculptId); +} + +void LLSculptIDSize::resetSizeSum(const LLUUID &sculptId) +{ +	const pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId); + +	if (itLU.first != itLU.second) { +		itLU.first->mSharedSizeSum->mSizeSum = 0; +	} + +	for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first, itE = itLU.second; it != itE; ++it) +	{ +		mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1)); +	} +} diff --git a/indra/newview/llsculptidsize.h b/indra/newview/llsculptidsize.h new file mode 100644 index 0000000000..87ee417b86 --- /dev/null +++ b/indra/newview/llsculptidsize.h @@ -0,0 +1,134 @@ +/** +* @file llsculptidsize.h +* @brief LLSculptIDSize class definition +* +* $LicenseInfo:firstyear=2009&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$ +*/ + +#ifndef LL_LLSCULPTIDSIZE_H +#define LL_LLSCULPTIDSIZE_H + +#include "lluuid.h" + +//std +#include <set> +//boost +#include "boost/multi_index_container.hpp" +#include "boost/multi_index/ordered_index.hpp" +#include "boost/multi_index/mem_fun.hpp" + +class LLDrawable; + + +class LLSculptIDSize +{ +public: +	struct SizeSum +	{ +		SizeSum(int size)  +			: mSizeSum(size) +		{} +		unsigned int mSizeSum; +	}; + +	struct Info +	{ +		typedef boost::shared_ptr<SizeSum> PtrSizeSum; + +		Info(const LLDrawable *drawable, int size, PtrSizeSum sizeInfo, LLUUID sculptId) +			: mDrawable(drawable) +			, mSize(size) +			, mSharedSizeSum(sizeInfo) +			, mSculptId(sculptId) +		{} + +		const LLDrawable *mDrawable; +		unsigned int mSize; +		PtrSizeSum	mSharedSizeSum; +		LLUUID mSculptId; + +		inline const LLDrawable*	getPtrLLDrawable() const { return mDrawable; } +		inline unsigned int			getSize() const { return mSize; } +		inline unsigned int			getSizeSum() const { return mSharedSizeSum->mSizeSum; } +		inline LLUUID				getSculptId() const { return mSculptId; } +		PtrSizeSum					getSizeInfo() { return mSharedSizeSum; } +	}; + +public: +	//tags +	struct tag_BY_DRAWABLE {}; +	struct tag_BY_SCULPT_ID {}; +	struct tag_BY_SIZE {}; + +	//container +	typedef boost::multi_index_container < +		Info, +		boost::multi_index::indexed_by < +		boost::multi_index::ordered_unique< boost::multi_index::tag<tag_BY_DRAWABLE> +		, boost::multi_index::const_mem_fun<Info, const LLDrawable*, &Info::getPtrLLDrawable> +		> +		, boost::multi_index::ordered_non_unique<boost::multi_index::tag<tag_BY_SCULPT_ID> +		, boost::multi_index::const_mem_fun<Info, LLUUID, &Info::getSculptId> +		> +		, boost::multi_index::ordered_non_unique < boost::multi_index::tag<tag_BY_SIZE> +		, boost::multi_index::const_mem_fun < Info, unsigned int, &Info::getSizeSum > +		> +		> +	> container; + +	//views +	typedef container::index<tag_BY_DRAWABLE>::type			container_BY_DRAWABLE_view; +	typedef container::index<tag_BY_SCULPT_ID>::type		container_BY_SCULPT_ID_view; +	typedef container::index<tag_BY_SIZE>::type				container_BY_SIZE_view; + +private: +	LLSculptIDSize() +	{} + +public: +	static LLSculptIDSize & instance()  +	{ +		static LLSculptIDSize inst; +		return inst; +	} + +public: +	void inc(const LLDrawable *pdrawable, int sz); +	void dec(const LLDrawable *pdrawable); +	void rem(const LLUUID &sculptId); + +	inline void addToUnloaded(const LLUUID &sculptId) { mMarkAsUnloaded.insert(sculptId); } +	inline void remFromUnloaded(const LLUUID &sculptId) { mMarkAsUnloaded.erase(sculptId); } +	inline bool isUnloaded(const LLUUID &sculptId) const { return mMarkAsUnloaded.end() != mMarkAsUnloaded.find(sculptId); } +	inline void clearUnloaded() { mMarkAsUnloaded.clear(); } +	 +	void resetSizeSum(const LLUUID &sculptId); + +	inline const container & getSizeInfo() const { return mSizeInfo; } + +private: +	container mSizeInfo; +	typedef std::set<LLUUID> std_LLUUID; +	std_LLUUID mMarkAsUnloaded; +}; + +#endif diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index c44aca6fa5..4bf2aa2d0b 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6271,92 +6271,101 @@ void pushWireframe(LLDrawable* drawable)  void LLSelectNode::renderOneWireframe(const LLColor4& color)  { -	//Need to because crash on ATI 3800 (and similar cards) MAINT-5018  -	LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); +    //Need to because crash on ATI 3800 (and similar cards) MAINT-5018  +    LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); -	LLViewerObject* objectp = getObject(); -	if (!objectp) -	{ -		return; -	} +    LLViewerObject* objectp = getObject(); +    if (!objectp) +    { +        return; +    } -	LLDrawable* drawable = objectp->mDrawable; -	if(!drawable) -	{ -		return; -	} +    LLDrawable* drawable = objectp->mDrawable; +    if (!drawable) +    { +        return; +    } -	LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +    LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; -	if (shader) -	{ -		gDebugProgram.bind(); -	} +    if (shader) +    { +        gDebugProgram.bind(); +    } -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.pushMatrix(); -	 -	BOOL is_hud_object = objectp->isHUDAttachment(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.pushMatrix(); -	if (drawable->isActive()) -	{ -		gGL.loadMatrix(gGLModelView); -		gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix); -	} -	else if (!is_hud_object) -	{ -		gGL.loadIdentity(); -		gGL.multMatrix(gGLModelView); -		LLVector3 trans = objectp->getRegion()->getOriginAgent();		 -		gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);		 -	} -	 -	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -	 -	if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible()) -	{ -		gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE); -		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL); -		if (shader) -		{ -			gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); -			pushWireframe(drawable); -		} -		else -		{ -			LLGLEnable fog(GL_FOG); -			glFogi(GL_FOG_MODE, GL_LINEAR); -			float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec(); -			LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0); -			glFogf(GL_FOG_START, d); -			glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV()))); -			glFogfv(GL_FOG_COLOR, fogCol.mV); +    BOOL is_hud_object = objectp->isHUDAttachment(); -			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); -			{ -				gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); -				pushWireframe(drawable); -			} -		} -	} +    if (drawable->isActive()) +    { +        gGL.loadMatrix(gGLModelView); +        gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix); +    } +    else if (!is_hud_object) +    { +        gGL.loadIdentity(); +        gGL.multMatrix(gGLModelView); +        LLVector3 trans = objectp->getRegion()->getOriginAgent(); +        gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); +    } -	gGL.flush(); -	gGL.setSceneBlendType(LLRender::BT_ALPHA); +    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -	gGL.diffuseColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); -	 -	LLGLEnable offset(GL_POLYGON_OFFSET_LINE); -	glPolygonOffset(3.f, 3.f); -	glLineWidth(3.f); -	pushWireframe(drawable); -	glLineWidth(1.f); -	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -	gGL.popMatrix(); +    if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible()) +    { +        gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE); +        LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL); +        if (shader) +        { +            gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); +            pushWireframe(drawable); +        } +        else +        { +            LLGLEnable fog(GL_FOG); +            glFogi(GL_FOG_MODE, GL_LINEAR); +            float d = (LLViewerCamera::getInstance()->getPointOfInterest() - LLViewerCamera::getInstance()->getOrigin()).magVec(); +            LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0); +            glFogf(GL_FOG_START, d); +            glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV()))); +            glFogfv(GL_FOG_COLOR, fogCol.mV); + +            gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +            { +                gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); +                pushWireframe(drawable); +            } +        } +    } -	if (shader) -	{ -		shader->bind(); -	} +    gGL.flush(); +    gGL.setSceneBlendType(LLRender::BT_ALPHA); + +    gGL.diffuseColor4f(color.mV[VRED] * 2, color.mV[VGREEN] * 2, color.mV[VBLUE] * 2, LLSelectMgr::sHighlightAlpha * 2); + +    { +        LLGLDisable depth(GL_BLEND); +        LLGLEnable stencil(GL_STENCIL_TEST); +        glStencilFunc(GL_NOTEQUAL, 2, 0xffff); +        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + +        LLGLEnable offset(GL_POLYGON_OFFSET_LINE); +        glPolygonOffset(3.f, 3.f); +        glLineWidth(5.f); +        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +        pushWireframe(drawable); +    } + +    glLineWidth(1.f); +    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +    gGL.popMatrix(); + +    if (shader) +    { +        shader->bind(); +    }  }  //----------------------------------------------------------------------------- diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index d2a87ee2af..9791f4a921 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3941,6 +3941,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co  LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,   					   LLViewerTexture* texture, LLVertexBuffer* buffer, +					   bool selected,  					   BOOL fullbright, U8 bump, BOOL particle, F32 part_size)  :	LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16>("LLDrawInfo"),  	mVertexBuffer(buffer), @@ -3968,7 +3969,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,  	mHasGlow(FALSE),  	mEnvIntensity(0.0f),  	mAlphaMaskCutoff(0.5f), -	mDiffuseAlphaMode(0) +	mDiffuseAlphaMode(0), +	mSelected(selected)  {  	mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 7633e46200..6104b92d43 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -75,6 +75,7 @@ public:  	LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,   				LLViewerTexture* image, LLVertexBuffer* buffer,  +				bool selected,  				BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); @@ -117,6 +118,7 @@ public:  	F32  mEnvIntensity;  	F32  mAlphaMaskCutoff;  	U8   mDiffuseAlphaMode; +	bool mSelected;  	struct CompareTexture @@ -646,7 +648,7 @@ class LLVolumeGeometryManager: public LLGeometryManager  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group); -	void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE); +	U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);  private: diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 57a0195d23..778e275727 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -113,6 +113,7 @@ LLViewerCamera::LLViewerCamera() : LLCamera()  {  	calcProjection(getFar());  	mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; +	mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;  	mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);  	mPixelMeterRatio = 0.f;  	mScreenPixelArea = 0; @@ -882,6 +883,15 @@ void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads)  	mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);  } +BOOL LLViewerCamera::isDefaultFOVChanged() +{ +	if(mPrevCameraFOVDefault != mCameraFOVDefault) +	{ +		mPrevCameraFOVDefault = mCameraFOVDefault; +		return !gSavedSettings.getBOOL("IgnoreFOVZoomForLODs"); +	} +	return FALSE; +}  // static  void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value) diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index f8c973690a..5901de289f 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -115,6 +115,8 @@ public:  	void setDefaultFOV(F32 fov) ;  	F32 getDefaultFOV() { return mCameraFOVDefault; } +	BOOL isDefaultFOVChanged(); +  	BOOL cameraUnderWater() const;  	BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts); @@ -138,6 +140,7 @@ protected:  	mutable LLMatrix4	mProjectionMatrix;	// Cache of perspective matrix  	mutable LLMatrix4	mModelviewMatrix;  	F32					mCameraFOVDefault; +	F32					mPrevCameraFOVDefault;  	F32					mCosHalfCameraFOV;  	LLVector3			mLastPointOfInterest;  	F32					mPixelMeterRatio; // Divide by distance from camera to get pixels per meter at that distance. diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index d9d66ef254..3280aa718d 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -582,6 +582,7 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)  	return true;  } +void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);  ////////////////////////////////////////////////////////////////////////////  void settings_setup_listeners() @@ -734,7 +735,8 @@ void settings_setup_listeners()  	gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));  	gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));  	gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged)); -    gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2)); +	gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2)); +	gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2));  }  #if TEST_CACHED_CONTROL diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 96ef160c72..86a9e7e2ad 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1005,7 +1005,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  															  gPipeline.mDeferredScreen.getHeight(), 0, 0,   															  gPipeline.mDeferredScreen.getWidth(),   															  gPipeline.mDeferredScreen.getHeight(),  -															  GL_DEPTH_BUFFER_BIT, GL_NEAREST); +															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);  				}  			}  			else @@ -1017,7 +1017,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  															  gPipeline.mScreen.getHeight(), 0, 0,   															  gPipeline.mScreen.getWidth(),   															  gPipeline.mScreen.getHeight(),  -															  GL_DEPTH_BUFFER_BIT, GL_NEAREST); +															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);  				}  			}  		} diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6c2d4d7fea..293df89bf0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5868,6 +5868,14 @@ void LLViewerObject::markForUpdate(BOOL priority)  	}  } +void LLViewerObject::markForUnload(BOOL priority) +{ +	if (mDrawable.notNull()) +	{ +		gPipeline.markRebuild(mDrawable, LLDrawable::FOR_UNLOAD, priority); +	} +} +  bool LLViewerObject::isPermanentEnforced() const  {  	return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike(); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 7a490f6957..e4224a79d1 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -412,6 +412,7 @@ public:  	void clearIcon();  	void markForUpdate(BOOL priority); +	void markForUnload(BOOL priority);  	void updateVolume(const LLVolumeParams& volume_params);  	virtual	void updateSpatialExtents(LLVector4a& min, LLVector4a& max);  	virtual F32 getBinRadius(); diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 023f1b92ba..5f0e21db71 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -465,7 +465,7 @@ LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node)  {  	LLVector4a tmp;  	tmp.splat(0.f); -	mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =  +	mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[1] =  		mObjectExtents[0] = mObjectExtents[1] = tmp;  	mBounds[0] = node->getCenter(); diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index de63a3963c..b5c90a8f60 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -741,7 +741,7 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)  			U32 count = facep->getIndicesCount();  			LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),   				//facep->getTexture(), -				buffer, fullbright);  +				buffer, object->isSelected(), fullbright);  			const LLVector4a* exts = group->getObjectExtents();  			info->mExtents[0] = exts[0]; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index f7b21338f8..f006ad2867 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -964,7 +964,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  			U32 count = facep->getIndicesCount();  			LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),   				//facep->getTexture(), -				buffer, fullbright);  +				buffer, object->isSelected(), fullbright);  			const LLVector4a* exts = group->getObjectExtents();  			info->mExtents[0] = exts[0]; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f77b48ff80..ad4466073a 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -78,6 +78,7 @@  #include "llvoavatar.h"  #include "llvocache.h"  #include "llmaterialmgr.h" +#include "llsculptidsize.h"  const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;  const F32 FORCE_CULL_AREA = 8.f; @@ -249,6 +250,8 @@ void LLVOVolume::markDead()  {  	if (!mDead)  	{ +		LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID()); +  		if(getMDCImplCount() > 0)  		{  			LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false); @@ -951,13 +954,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  		// if it's a mesh  		if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)  		{ //meshes might not have all LODs, get the force detail to best existing LOD -			LLUUID mesh_id = volume_params.getSculptID(); - -			lod = gMeshRepo.getActualMeshLOD(volume_params, lod); -			if (lod == -1) +			if (NO_LOD != lod)  			{ -				is404 = TRUE; -				lod = 0; +				lod = gMeshRepo.getActualMeshLOD(volume_params, lod); +				if (lod == -1) +				{ +					is404 = TRUE; +					lod = 0; +				}  			}  		}  	} @@ -1054,12 +1058,13 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo  				LLFace::cacheFaceInVRAM(face);  			}  		} -		  		return TRUE;  	} - - +	else if (NO_LOD == lod)  +	{ +		LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID()); +	}  	return FALSE;  } @@ -1214,18 +1219,18 @@ void LLVOVolume::sculpt()  	}  } -S32	LLVOVolume::computeLODDetail(F32 distance, F32 radius) +S32	LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor)  {  	S32	cur_detail;  	if (LLPipeline::sDynamicLOD)  	{  		// We've got LOD in the profile, and in the twist.  Use radius. -		F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance; +		F32 tan_angle = (lod_factor*radius)/distance;  		cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f));  	}  	else  	{ -		cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);		 +		cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3);  	}  	return cur_detail;  } @@ -1241,6 +1246,7 @@ BOOL LLVOVolume::calcLOD()  	F32 radius;  	F32 distance; +	F32 lod_factor = LLVOVolume::sLODFactor;  	if (mDrawable->isState(LLDrawable::RIGGED))  	{ @@ -1276,12 +1282,18 @@ BOOL LLVOVolume::calcLOD()  		distance *= rampDist;  	} -	// DON'T Compensate for field of view changing on FOV zoom. +  	distance *= F_PI/3.f; -	cur_detail = computeLODDetail(ll_round(distance, 0.01f),  -									ll_round(radius, 0.01f)); +	static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs"); +	if(!ignore_fov_zoom) +	{ +		lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV(); +	} +	cur_detail = computeLODDetail(ll_round(distance, 0.01f),  +									ll_round(radius, 0.01f), +									lod_factor);  	if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&  		mDrawable->getFace(0)) @@ -1294,7 +1306,8 @@ BOOL LLVOVolume::calcLOD()  	if (cur_detail != mLOD)  	{  		mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); -		mLOD = cur_detail;		 +		mLOD = cur_detail; +  		return TRUE;  	} @@ -1308,7 +1321,16 @@ BOOL LLVOVolume::updateLOD()  		return FALSE;  	} -	BOOL lod_changed = calcLOD(); +	BOOL lod_changed = FALSE; + +	if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID()))  +	{ +		lod_changed = calcLOD(); +	} +	else +	{ +		return FALSE; +	}  	if (lod_changed)  	{ @@ -1478,7 +1500,6 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)  		res &= face->genVolumeBBoxes(*volume, i,  										mRelativeXform,   										(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); -		  		if (rebuild)  		{  			if (i == 0) @@ -1754,6 +1775,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)  		dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));  		compiled = TRUE;  		lodOrSculptChanged(drawable, compiled); +		 +		if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED))  +		{ +			updateRiggedVolume(false); +		}  		genBBoxes(FALSE);  	}  	// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local @@ -4203,7 +4229,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons  			LLVector4a* pos = dst_face.mPositions; -			if( pos && weight && dst_face.mExtents ) +			if (pos && dst_face.mExtents)  			{  				LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED); @@ -4389,7 +4415,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;  	} -	if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects) +	bool selected = facep->getViewerObject()->isSelected(); + +	if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects)  	{  		return;  	} @@ -4486,7 +4514,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  			batchable = true;  		}  	} -	 +  	if (idx >= 0 &&   		draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&  		draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && @@ -4502,7 +4530,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different  		draw_vec[idx]->mTextureMatrix == tex_mat &&  		draw_vec[idx]->mModelMatrix == model_mat && -		draw_vec[idx]->mShaderMask == shader_mask) +		draw_vec[idx]->mShaderMask == shader_mask && +		draw_vec[idx]->mSelected == selected)  	{  		draw_vec[idx]->mCount += facep->getIndicesCount();  		draw_vec[idx]->mEnd += facep->getGeomCount(); @@ -4524,7 +4553,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		U32 offset = facep->getIndicesStart();  		U32 count = facep->getIndicesCount();  		LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,  -			facep->getVertexBuffer(), fullbright, bump);  +			facep->getVertexBuffer(), selected, fullbright, bump);  		draw_info->mGroup = group;  		draw_info->mVSize = facep->getVirtualSize();  		draw_vec.push_back(draw_info); @@ -4551,26 +4580,25 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		if (mat)  		{ -				draw_info->mMaterialID = mat_id; +			draw_info->mMaterialID = mat_id; -				// We have a material.  Update our draw info accordingly. +			// We have a material.  Update our draw info accordingly. -				if (!mat->getSpecularID().isNull()) -				{ -					LLVector4 specColor; -					specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); -					specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); -					specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); -					specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); -					draw_info->mSpecColor = specColor; -					draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); -					draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); -				} +			if (!mat->getSpecularID().isNull()) +			{ +				LLVector4 specColor; +				specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f); +				specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f); +				specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f); +				specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f); +				draw_info->mSpecColor = specColor; +				draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f); +				draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset()); +			} -				draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); -				draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); -				draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); -				 +			draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); +			draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); +			draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());  		}  		else   		{ @@ -4641,10 +4669,83 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)  	return NULL;  } -void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) +void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value)  { -	 +	static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U); +	if (0 != render_auto_mute_byte_limit) +	{ +		//for unload +		LLSculptIDSize::container_BY_SIZE_view::iterator +			itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().lower_bound(render_auto_mute_byte_limit), +			itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().end(); + +		for (; itL != itU; ++itL) +		{ +			const LLSculptIDSize::Info &nfo = *itL; +			LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume(); +			if (pVVol +				&& !pVVol->isDead() +				&& pVVol->isAttachment() +				&& !pVVol->getAvatar()->isSelf() +				&& LLVOVolume::NO_LOD != pVVol->getLOD() +				) +			{ +				//postponed +				pVVol->markForUnload(); +				LLSculptIDSize::instance().addToUnloaded(nfo.getSculptId()); +			} +		} + +		//for load if it was unload +		itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().begin(); +		itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().upper_bound(render_auto_mute_byte_limit); + +		for (; itL != itU; ++itL) +		{ +			const LLSculptIDSize::Info &nfo = *itL; +			LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume(); +			if (pVVol +				&& !pVVol->isDead() +				&& pVVol->isAttachment() +				&& !pVVol->getAvatar()->isSelf() +				&& LLVOVolume::NO_LOD == pVVol->getLOD() +				) +			{ +				LLSculptIDSize::instance().remFromUnloaded(nfo.getSculptId()); +				pVVol->updateLOD(); +				pVVol->markForUpdate(TRUE); +			} +		} +	} +	else +	{ +		LLSculptIDSize::instance().clearUnloaded(); + +		LLSculptIDSize::container_BY_SIZE_view::iterator +			itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().begin(), +			itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().end(); + +		for (; itL != itU; ++itL) +		{ +			const LLSculptIDSize::Info &nfo = *itL; +			LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume(); +			if (pVVol +				&& !pVVol->isDead() +				&& pVVol->isAttachment() +				&& !pVVol->getAvatar()->isSelf() +				&& LLVOVolume::NO_LOD == pVVol->getLOD() +				)  +			{ +				pVVol->updateLOD(); +				pVVol->markForUpdate(TRUE); +			} +		} +	} +} + +void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) +{  	if (group->changeLOD())  	{  		group->mLastUpdateDistance = group->mDistance; @@ -5205,13 +5306,19 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;  	} -	genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE); -	genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures); -	genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures); -	genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE); -	genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE); -	genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE); -	genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE); +	group->mGeometryBytes = 0; + +	U32 geometryBytes = 0; + +	geometryBytes += genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE); +	geometryBytes += genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures); +	geometryBytes += genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures); +	geometryBytes += genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE); +	geometryBytes += genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE); +	geometryBytes += genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE); +	geometryBytes += genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE); + +	group->mGeometryBytes = geometryBytes;  	if (!LLPipeline::sDelayVBUpdate)  	{ @@ -5269,6 +5376,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  			if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )  			{  				LLVOVolume* vobj = drawablep->getVOVolume(); +				if (vobj->isNoLOD()) continue; +  				vobj->preRebuild();  				if (drawablep->isState(LLDrawable::ANIMATED_CHILD)) @@ -5401,10 +5510,11 @@ static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB"); -void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials) +U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)  {  	LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); +	U32 geometryBytes = 0;  	U32 buffer_usage = group->mBufferUsage;  	static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); @@ -5654,7 +5764,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac  		if (buffer)  		{ -			group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); +			geometryBytes += buffer->getSize() + buffer->getIndicesSize();  			buffer_map[mask][*face_iter].push_back(buffer);  		} @@ -5942,7 +6052,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac  					}  					else  					{ -					registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); +						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);  					}  					if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)  					{ //if this is the deferred render and a bump map is present, register in post deferred bump @@ -5964,8 +6074,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac  						}  						else  						{ -						registerFace(group, facep, LLRenderPass::PASS_SIMPLE); -					} +							registerFace(group, facep, LLRenderPass::PASS_SIMPLE); +						}  				}  				} @@ -6010,6 +6120,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac  	{  		group->mBufferMap[mask][i->first] = i->second;  	} + +	return geometryBytes;  }  void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) @@ -6076,4 +6188,3 @@ void LLHUDPartition::shift(const LLVector4a &offset)  {  	//HUD objects don't shift with region crossing.  That would be silly.  } - diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index a331908320..f9d04844fc 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -35,6 +35,8 @@  #include "m3math.h"		// LLMatrix3  #include "m4math.h"		// LLMatrix4  #include <map> +#include <set> +  class LLViewerTextureAnim;  class LLDrawPool; @@ -125,7 +127,9 @@ public:  				void	generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);  	/*virtual*/	BOOL	setParent(LLViewerObject* parent); -				S32		getLOD() const							{ return mLOD; } +				S32		getLOD() const						{ return mLOD; } +				void	setNoLOD()							{ mLOD = NO_LOD; mLODChanged = TRUE; } +				bool	isNoLOD() const						{ return NO_LOD == mLOD; }  	const LLVector3		getPivotPositionAgent() const;  	const LLMatrix4&	getRelativeXform() const				{ return mRelativeXform; }  	const LLMatrix3&	getRelativeXformInvTrans() const		{ return mRelativeXformInvTrans; } @@ -160,6 +164,7 @@ public:  				const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;  				void	markForUpdate(BOOL priority)			{ LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; } +				void	markForUnload()							{ LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; }  				void    faceMappingChanged()                    { mFaceMappingChanged=TRUE; };  	/*virtual*/ void	onShift(const LLVector4a &shift_vector); // Called when the drawable shifts @@ -327,7 +332,7 @@ public:  	void clearRiggedVolume();  protected: -	S32	computeLODDetail(F32	distance, F32 radius); +	S32	computeLODDetail(F32	distance, F32 radius, F32 lod_factor);  	BOOL calcLOD();  	LLFace* addFace(S32 face_index);  	void updateTEData(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1d083bb2fd..5a8e6ced6c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2656,7 +2656,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d  	{  		scratch_space->copyContents(source,   									0, 0, source.getWidth(), source.getHeight(),  -									0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); +									0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);  	}  	dest.bindTarget(); @@ -3031,6 +3031,12 @@ void LLPipeline::updateGeom(F32 max_dtime)  				}  			} +			if (drawablep->isUnload()) +			{ +				drawablep->unload(); +				drawablep->clearState(LLDrawable::FOR_UNLOAD); +			} +  			if (updateDrawableGeom(drawablep, TRUE))  			{  				drawablep->clearState(LLDrawable::IN_REBUILD_Q1); @@ -3424,6 +3430,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  	if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)  	{  		LLSpatialGroup* last_group = NULL; +		BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();  		for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)  		{  			LLCullResult::bridge_iterator cur_iter = i; @@ -3437,7 +3444,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  			if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED))  			{ -				stateSort(bridge, camera); +				stateSort(bridge, camera, fov_changed);  			}  			if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && @@ -3509,9 +3516,9 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)  } -void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) +void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed)  { -	if (bridge->getSpatialGroup()->changeLOD()) +	if (bridge->getSpatialGroup()->changeLOD() || fov_changed)  	{  		bool force_update = false;  		bridge->updateDistance(camera, force_update); @@ -4577,12 +4584,6 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)  	LLGLEnable cull(GL_CULL_FACE); -	LLGLEnable stencil(GL_STENCIL_TEST); -	glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); -	stop_glerror(); -	glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); -	stop_glerror(); -  	for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)  	{  		LLDrawPool *poolp = *iter; @@ -8138,7 +8139,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)  	if (LLRenderTarget::sUseFBO)  	{ //copy depth buffer from mScreen to framebuffer  		LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(),  -			0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); +			0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);  	} @@ -9019,7 +9020,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)  		{  			LLGLDepthTest depth(GL_TRUE);  			mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), -							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);	 +							0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);	  		}  		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); @@ -10117,7 +10118,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  	}  	LLPipeline::sShadowRender = true; -	U32 types[] = {  +	static const U32 types[] = {   		LLRenderPass::PASS_SIMPLE,   		LLRenderPass::PASS_FULLBRIGHT,   		LLRenderPass::PASS_SHINY,  @@ -11622,7 +11623,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	avatar->setImpostorDim(tdim); -	LLVOAvatar::sUseImpostors = true; // @TODO ??? +	LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors);  	sUseOcclusion = occlusion;  	sReflectionRender = false;  	sImpostorRender = false; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c9670a60f2..f43607ccb0 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -254,7 +254,7 @@ public:  	void stateSort(LLCamera& camera, LLCullResult& result);  	void stateSort(LLSpatialGroup* group, LLCamera& camera); -	void stateSort(LLSpatialBridge* bridge, LLCamera& camera); +	void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE);  	void stateSort(LLDrawable* drawablep, LLCamera& camera);  	void postSort(LLCamera& camera);  	void forAllVisibleDrawables(void (*func)(LLDrawable*)); | 
