diff options
| author | Richard Linden <none@none> | 2013-06-05 19:05:43 -0700 | 
|---|---|---|
| committer | Richard Linden <none@none> | 2013-06-05 19:05:43 -0700 | 
| commit | 0a96b47663c99914c587cdcb8bcdc096bbf55fa3 (patch) | |
| tree | 67bca4958927ed7f6df423de05e42cd271292391 | |
| parent | dcfb18373eca7986a73d8b9a1d34970cc0a23ed9 (diff) | |
| parent | a74b5dfa923f8eeccc9b786143f0f832de3ad450 (diff) | |
merge with viewer-release
434 files changed, 15782 insertions, 20137 deletions
@@ -74,4 +74,6 @@ glob:indra/newview/filters.xml  glob:indra/newview/avatar_icons_cache.txt  glob:indra/newview/avatar_lad.log  glob:*.diff -#*.rej +indra/newview/pilot.txt +indra/newview/pilot.xml +*.rej diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 472f271fa8..ac9e717c82 100755 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -61,6 +61,7 @@ if (WINDOWS)    add_definitions(        /DLL_WINDOWS=1 +      /DNOMINMAX        /DDOM_DYNAMIC        /DUNICODE        /D_UNICODE  diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 3bb759d458..35d1a8b247 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -36,8 +36,8 @@  #include "llavatarappearancedefines.h"  #include "llavatarjointmesh.h"  #include "imageids.h" -#include "lldir.h"  #include "lldeleteutils.h" +#include "lldir.h"  #include "llpolymorph.h"  #include "llpolymesh.h"  #include "llpolyskeletaldistortion.h" diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp index 4a5cff1dc3..753805b314 100644 --- a/indra/llappearance/llavatarjointmesh.cpp +++ b/indra/llappearance/llavatarjointmesh.cpp @@ -117,7 +117,6 @@ BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint)  //-----------------------------------------------------------------------------  BOOL LLAvatarJointMesh::sPipelineRender = FALSE; -EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;  U32 LLAvatarJointMesh::sClothingMaskImageName = 0;  LLColor4 LLAvatarJointMesh::sClothingInnerColor; diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h index 6486932cdf..5980b29b46 100644 --- a/indra/llappearance/llavatarjointmesh.h +++ b/indra/llappearance/llavatarjointmesh.h @@ -82,7 +82,6 @@ public:  	static BOOL					sPipelineRender;  	//RN: this is here for testing purposes  	static U32					sClothingMaskImageName; -	static EAvatarRenderPass	sRenderPass;  	static LLColor4				sClothingInnerColor;  public: diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 8a17819083..d40dfadfc8 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -35,6 +35,7 @@  #include "llxmltree.h"  #include "llendianswizzle.h"  #include "llpolymesh.h" +#include "llfasttimer.h"  //#include "../tools/imdebug/imdebug.h" diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index 4ba16691c2..a98a11b357 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -29,18 +29,11 @@  //-----------------------------------------------------------------------------  #include "llpreprocessor.h"  #include "llerrorlegacy.h" -//#include "llcommon.h" -//#include "llmemory.h"  #include "llavatarappearance.h"  #include "llavatarjoint.h"  #include "llpolymorph.h" -//#include "llviewercontrol.h" -//#include "llxmltree.h" -//#include "llvoavatar.h"  #include "llwearable.h" -//#include "lldir.h" -//#include "llvolume.h" -//#include "llendianswizzle.h" +#include "llfasttimer.h"  #include "llpolyskeletaldistortion.h" diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index f951a982e5..f65829febe 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -38,11 +38,13 @@  #include "llvfs.h"  #include "lltexlayerparams.h"  #include "lltexturemanagerbridge.h" +#include "lllocaltextureobject.h"  #include "../llui/llui.h"  #include "llwearable.h"  #include "llwearabledata.h"  #include "llvertexbuffer.h"  #include "llviewervisualparam.h" +#include "llfasttimer.h"  //#include "../tools/imdebug/imdebug.h" diff --git a/indra/llappearance/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp index 6aae9a8cc1..674e8c3c06 100644 --- a/indra/llappearance/lltexlayerparams.cpp +++ b/indra/llappearance/lltexlayerparams.cpp @@ -35,6 +35,7 @@  #include "lltexturemanagerbridge.h"  #include "../llui/llui.h"  #include "llwearable.h" +#include "llfasttimer.h"  //-----------------------------------------------------------------------------  // LLTexLayerParam diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h index 6f5a1e14e8..8c2a1721b7 100644 --- a/indra/llappearance/llwearable.h +++ b/indra/llappearance/llwearable.h @@ -32,12 +32,12 @@  #include "llpermissions.h"  #include "llsaleinfo.h"  #include "llwearabletype.h" -#include "lllocaltextureobject.h"  class LLMD5;  class LLVisualParam;  class LLTexGlobalColorInfo;  class LLTexGlobalColor; +class LLLocalTextureObject;  class LLAvatarAppearance;  // Abstract class. @@ -116,7 +116,7 @@ public:  protected:  	typedef std::map<S32, LLLocalTextureObject*> te_map_t;  	void				syncImages(te_map_t &src, te_map_t &dst); -	void				destroyTextures(); +	void				destroyTextures();	  	void			 	createVisualParams(LLAvatarAppearance *avatarp);  	void 				createLayers(S32 te, LLAvatarAppearance *avatarp);  	BOOL				getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size); diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 6c97a64ed7..bcff03ceaa 100755 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -40,6 +40,7 @@  #include "vorbis/codec.h"  #include "vorbis/vorbisfile.h" +#include <iterator>  extern LLAudioEngine *gAudiop; diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index 85cf1cd3f5..045b4abf50 100755 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -32,6 +32,7 @@  #include "llcharacter.h"  #include "llstring.h" +#include "llfasttimer.h"  #define SKEL_HEADER "Linden Skeleton 1.0" diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp index 0d0b85ba60..ff7ad1c289 100755 --- a/indra/llcharacter/lleditingmotion.cpp +++ b/indra/llcharacter/lleditingmotion.cpp @@ -232,7 +232,7 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)  		mIKSolver.solve();  		// use blending... -		F32 slerp_amt = LLCriticalDamp::getInterpolant(TARGET_LAG_HALF_LIFE); +		F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TARGET_LAG_HALF_LIFE);  		shoulderRot = slerp(slerp_amt, mShoulderJoint.getRotation(), shoulderRot);  		elbowRot = slerp(slerp_amt, mElbowJoint.getRotation(), elbowRot); diff --git a/indra/llcharacter/llheadrotmotion.cpp b/indra/llcharacter/llheadrotmotion.cpp index 15a58a8389..4a8af2f00c 100755 --- a/indra/llcharacter/llheadrotmotion.cpp +++ b/indra/llcharacter/llheadrotmotion.cpp @@ -182,8 +182,8 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask)  	LLQuaternion	currentRootRotWorld = mRootJoint->getWorldRotation();  	LLQuaternion	currentInvRootRotWorld = ~currentRootRotWorld; -	F32 head_slerp_amt = LLCriticalDamp::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE); -	F32 torso_slerp_amt = LLCriticalDamp::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE); +	F32 head_slerp_amt = LLSmoothInterpolation::getInterpolant(HEAD_LOOKAT_LAG_HALF_LIFE); +	F32 torso_slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_LOOKAT_LAG_HALF_LIFE);  	LLVector3* targetPos = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 2b1e2005c6..07374b7814 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -31,6 +31,7 @@  // Header Files  //-----------------------------------------------------------------------------  #include <string> +#include <list>  #include "linked_lists.h"  #include "v3math.h" diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index c6f45bffa2..831a0a6719 100755 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1031,11 +1031,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  	if (constraint->mSharedData->mChainLength != 0 &&  		dist_vec_squared(root_pos, target_pos) * 0.95f > constraint->mTotalLength * constraint->mTotalLength)  	{ -		constraint->mWeight = lerp(constraint->mWeight, 0.f, LLCriticalDamp::getInterpolant(0.1f)); +		constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 0.f, 0.1f);  	}  	else  	{ -		constraint->mWeight = lerp(constraint->mWeight, 1.f, LLCriticalDamp::getInterpolant(0.3f)); +		constraint->mWeight = LLSmoothInterpolation::lerp(constraint->mWeight, 1.f, 0.3f);  	}  	F32 weight = constraint->mWeight * ((shared_data->mEaseOutStopTime == 0.f) ? 1.f :  @@ -1082,9 +1082,9 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8  			// convert intermediate joint positions to world coordinates  			positions[joint_num] = ( constraint->mPositions[joint_num] * mPelvisp->getWorldRotation()) + mPelvisp->getWorldPosition();  			F32 time_constant = 1.f / clamp_rescale(constraint->mFixupDistanceRMS, 0.f, 0.5f, 0.2f, 8.f); -//			llinfos << "Interpolant " << LLCriticalDamp::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl; +//			llinfos << "Interpolant " << LLSmoothInterpolation::getInterpolant(time_constant, FALSE) << " and fixup distance " << constraint->mFixupDistanceRMS << " on " << mCharacter->findCollisionVolume(shared_data->mSourceConstraintVolume)->getName() << llendl;  			positions[joint_num] = lerp(positions[joint_num], kinematic_position,  -				LLCriticalDamp::getInterpolant(time_constant, FALSE)); +				LLSmoothInterpolation::getInterpolant(time_constant, FALSE));  		}  		S32 iteration_count; diff --git a/indra/llcharacter/llkeyframewalkmotion.cpp b/indra/llcharacter/llkeyframewalkmotion.cpp index d52eb89a5c..e188b06c03 100755 --- a/indra/llcharacter/llkeyframewalkmotion.cpp +++ b/indra/llcharacter/llkeyframewalkmotion.cpp @@ -258,7 +258,7 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)  		// but this will cause the animation playback rate calculation below to   		// kick in too slowly and sometimes start playing the animation in reverse. -		//mPelvisOffset -= PELVIS_COMPENSATION_WIEGHT * (foot_slip_vector * world_to_avatar_rot);//lerp(LLVector3::zero, -1.f * (foot_slip_vector * world_to_avatar_rot), LLCriticalDamp::getInterpolant(0.1f)); +		//mPelvisOffset -= PELVIS_COMPENSATION_WIEGHT * (foot_slip_vector * world_to_avatar_rot);//lerp(LLVector3::zero, -1.f * (foot_slip_vector * world_to_avatar_rot), LLSmoothInterpolation::getInterpolant(0.1f));  		////F32 drift_comp_max = DRIFT_COMP_MAX_TOTAL * (llclamp(speed, 0.f, DRIFT_COMP_MAX_SPEED) / DRIFT_COMP_MAX_SPEED);  		//F32 drift_comp_max = DRIFT_COMP_MAX_TOTAL; @@ -287,7 +287,7 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)  		F32 desired_speed_multiplier = llclamp(speed / foot_speed, min_speed_multiplier, ANIM_SPEED_MAX);  		// blend towards new speed adjustment value -		F32 new_speed_adjust = lerp(mAdjustedSpeed, desired_speed_multiplier, LLCriticalDamp::getInterpolant(SPEED_ADJUST_TIME_CONSTANT)); +		F32 new_speed_adjust = LLSmoothInterpolation::lerp(mAdjustedSpeed, desired_speed_multiplier, SPEED_ADJUST_TIME_CONSTANT);  		// limit that rate at which the speed adjustment changes  		F32 speedDelta = llclamp(new_speed_adjust - mAdjustedSpeed, -SPEED_ADJUST_MAX_SEC * delta_time, SPEED_ADJUST_MAX_SEC * delta_time); @@ -305,8 +305,8 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)  	{	// standing/turning  		// damp out speed adjustment to 0 -		mAnimSpeed = lerp(mAnimSpeed, 1.f, LLCriticalDamp::getInterpolant(0.2f)); -		//mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLCriticalDamp::getInterpolant(0.2f)); +		mAnimSpeed = LLSmoothInterpolation::lerp(mAnimSpeed, 1.f, 0.2f); +		//mPelvisOffset = lerp(mPelvisOffset, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.2f));  	}  	// broadcast walk speed change @@ -383,7 +383,7 @@ BOOL LLFlyAdjustMotion::onUpdate(F32 time, U8* joint_mask)  	F32 target_roll = llclamp(ang_vel.mV[VZ], -4.f, 4.f) * roll_factor;  	// roll is critically damped interpolation between current roll and angular velocity-derived target roll -	mRoll = lerp(mRoll, target_roll, LLCriticalDamp::getInterpolant(0.1f)); +	mRoll = LLSmoothInterpolation::lerp(mRoll, target_roll, LLUnit<LLUnits::Milliseconds, F32>(100));  	LLQuaternion roll(mRoll, LLVector3(0.f, 0.f, 1.f));  	mPelvisState->setRotation(roll); diff --git a/indra/llcharacter/llmotion.cpp b/indra/llcharacter/llmotion.cpp index 2551f125d0..af2e10220a 100755 --- a/indra/llcharacter/llmotion.cpp +++ b/indra/llcharacter/llmotion.cpp @@ -73,7 +73,7 @@ void LLMotion::fadeOut()  {  	if (mFadeWeight > 0.01f)  	{ -		mFadeWeight = lerp(mFadeWeight, 0.f, LLCriticalDamp::getInterpolant(0.15f)); +		mFadeWeight = lerp(mFadeWeight, 0.f, LLSmoothInterpolation::getInterpolant(0.15f));  	}  	else  	{ @@ -88,7 +88,7 @@ void LLMotion::fadeIn()  {  	if (mFadeWeight < 0.99f)  	{ -		mFadeWeight = lerp(mFadeWeight, 1.f, LLCriticalDamp::getInterpolant(0.15f)); +		mFadeWeight = lerp(mFadeWeight, 1.f, LLSmoothInterpolation::getInterpolant(0.15f));  	}  	else  	{ diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp index e9fb91ad73..d1c605451a 100755 --- a/indra/llcharacter/llmotioncontroller.cpp +++ b/indra/llcharacter/llmotioncontroller.cpp @@ -30,6 +30,7 @@  #include "linden_common.h"  #include "llmotioncontroller.h" +#include "llfasttimer.h"  #include "llkeyframemotion.h"  #include "llmath.h"  #include "lltimer.h" diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index 52eaf557b1..2bd5271c4f 100755 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -34,7 +34,6 @@  #include <map>  #include <deque> -#include "lluuidhashmap.h"  #include "llmotion.h"  #include "llpose.h"  #include "llframetimer.h" diff --git a/indra/llcharacter/lltargetingmotion.cpp b/indra/llcharacter/lltargetingmotion.cpp index 489aef923c..633c1d51eb 100755 --- a/indra/llcharacter/lltargetingmotion.cpp +++ b/indra/llcharacter/lltargetingmotion.cpp @@ -106,7 +106,7 @@ BOOL LLTargetingMotion::onActivate()  //-----------------------------------------------------------------------------  BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask)  { -	F32 slerp_amt = LLCriticalDamp::getInterpolant(TORSO_TARGET_HALF_LIFE); +	F32 slerp_amt = LLSmoothInterpolation::getInterpolant(TORSO_TARGET_HALF_LIFE);  	LLVector3 target;  	LLVector3* lookAtPoint = (LLVector3*)mCharacter->getAnimationData("LookAtPoint"); diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 3a4a8facc2..bf99a4c3a0 100755 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -75,8 +75,10 @@ set(llcommon_SOURCE_FILES      llmetrics.cpp      llmetricperformancetester.cpp      llmortician.cpp +    llmutex.cpp      lloptioninterface.cpp      llptrto.cpp  +    llpredicate.cpp      llprocess.cpp      llprocessor.cpp      llqueuedthread.cpp @@ -90,7 +92,6 @@ set(llcommon_SOURCE_FILES      llsdutil.cpp      llsecondlifeurls.cpp      llsingleton.cpp -    llstat.cpp      llstacktrace.cpp      llstreamqueue.cpp      llstreamtools.cpp @@ -98,14 +99,15 @@ set(llcommon_SOURCE_FILES      llstringtable.cpp      llsys.cpp      llthread.cpp +    llthreadlocalstorage.cpp      llthreadsafequeue.cpp      lltimer.cpp +    lltrace.cpp +    lltracerecording.cpp +    lltracethreadrecorder.cpp      lluri.cpp      lluuid.cpp      llworkerthread.cpp -    metaclass.cpp -    metaproperty.cpp -    reflective.cpp      timing.cpp      u64.cpp      ) @@ -115,7 +117,6 @@ set(llcommon_HEADER_FILES      bitpack.h      ctype_workaround.h -    doublelinkedlist.h      fix_macros.h      imageids.h      indra_constants.h @@ -129,7 +130,6 @@ set(llcommon_HEADER_FILES      llapp.h      llapr.h      llassettype.h -    llassoclist.h      llavatarconstants.h      llbase32.h      llbase64.h @@ -143,18 +143,14 @@ set(llcommon_HEADER_FILES      llcriticaldamp.h      llcursortypes.h      lldarray.h -    lldarrayptr.h      lldate.h      lldefs.h      lldependencies.h      lldeleteutils.h      lldepthstack.h      lldictionary.h -    lldlinked.h      lldoubledispatch.h -    lldqueueptr.h      llendianswizzle.h -    llenum.h      llerror.h      llerrorcontrol.h      llerrorlegacy.h @@ -178,18 +174,15 @@ set(llcommon_HEADER_FILES      llhash.h      llheartbeat.h      llhttpstatuscodes.h -    llindexedqueue.h      llinitparam.h      llinstancetracker.h      llkeythrottle.h -    lllazy.h      llleap.h      llleaplistener.h      lllistenerwrapper.h      lllinkedqueue.h      llliveappconfig.h      lllivefile.h -    lllocalidhashmap.h      lllog.h      lllslconstants.h      llmap.h @@ -199,15 +192,15 @@ set(llcommon_HEADER_FILES      llmetrics.h      llmetricperformancetester.h      llmortician.h +    llmutex.h      llnametable.h      lloptioninterface.h      llpointer.h +    llpredicate.h      llpreprocessor.h      llpriqueuemap.h      llprocess.h      llprocessor.h -    llptrskiplist.h -    llptrskipmap.h      llptrto.h      llqueuedthread.h      llrand.h @@ -224,12 +217,7 @@ set(llcommon_HEADER_FILES      llsecondlifeurls.h      llsimplehash.h      llsingleton.h -    llskiplist.h -    llskipmap.h -    llsortedvector.h -    llstack.h      llstacktrace.h -    llstat.h      llstatenums.h      llstl.h      llstreamqueue.h @@ -239,22 +227,21 @@ set(llcommon_HEADER_FILES      llstringtable.h      llsys.h      llthread.h +    llthreadlocalstorage.h      llthreadsafequeue.h      lltimer.h +    lltrace.h +    lltracerecording.h +    lltracethreadrecorder.h      lltreeiterators.h -    lltypeinfolookup.h +    llunit.h      lluri.h      lluuid.h -    lluuidhashmap.h      llversionserver.h +	llwin32headers.h +    llwin32headerslean.h      llworkerthread.h      ll_template_cast.h -    metaclass.h -    metaclasst.h -    metaproperty.h -    metapropertyt.h -    reflective.h -    reflectivet.h      roles_constants.h      stdenums.h      stdtypes.h @@ -326,7 +313,6 @@ if (LL_TESTS)    LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llinstancetracker "" "${test_libs}") -  LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}") @@ -334,7 +320,7 @@ if (LL_TESTS)    LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}") -  LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}") +  LL_ADD_INTEGRATION_TEST(llunits "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(lleventdispatcher "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(lleventcoro "" "${test_libs};${BOOST_CONTEXT_LIBRARY}") diff --git a/indra/llcommon/doublelinkedlist.h b/indra/llcommon/doublelinkedlist.h deleted file mode 100755 index 0aeaa69df3..0000000000 --- a/indra/llcommon/doublelinkedlist.h +++ /dev/null @@ -1,1397 +0,0 @@ -/**  - * @file doublelinkedlist.h - * @brief Provides a standard doubly linked list for fun and profit. - * - * $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$ - */ - -#ifndef LL_DOUBLELINKEDLIST_H -#define LL_DOUBLELINKEDLIST_H - -#include "llerror.h" -#include "llrand.h" - -// node that actually contains the data -template <class DATA_TYPE> class LLDoubleLinkedNode -{ -public: -	DATA_TYPE			*mDatap; -	LLDoubleLinkedNode	*mNextp; -	LLDoubleLinkedNode	*mPrevp; - - -public: -	// assign the mDatap pointer -	LLDoubleLinkedNode(DATA_TYPE *data); - -	// destructor does not, by default, destroy associated data -	// however, the mDatap must be NULL to ensure that we aren't causing memory leaks -	~LLDoubleLinkedNode(); - -	// delete associated data and NULL out pointer -	void deleteData(); - -	// remove associated data and NULL out pointer -	void removeData(); -}; - - -const U32 LLDOUBLE_LINKED_LIST_STATE_STACK_DEPTH = 4; - -template <class DATA_TYPE> class LLDoubleLinkedList -{ -private: -	LLDoubleLinkedNode<DATA_TYPE> mHead;		// head node -	LLDoubleLinkedNode<DATA_TYPE> mTail;		// tail node -	LLDoubleLinkedNode<DATA_TYPE> *mQueuep;		// The node in the batter's box -	LLDoubleLinkedNode<DATA_TYPE> *mCurrentp;	// The node we're talking about - -	// The state stack allows nested exploration of the LLDoubleLinkedList -	// but should be used with great care -	LLDoubleLinkedNode<DATA_TYPE> *mQueuepStack[LLDOUBLE_LINKED_LIST_STATE_STACK_DEPTH]; -	LLDoubleLinkedNode<DATA_TYPE> *mCurrentpStack[LLDOUBLE_LINKED_LIST_STATE_STACK_DEPTH]; -	U32 mStateStackDepth; -	U32	mCount; - -	// mInsertBefore is a pointer to a user-set function that returns  -	// TRUE if "first" should be located before "second" -	// NOTE: mInsertBefore() should never return TRUE when ("first" == "second") -	// or never-ending loops can occur -	BOOL				(*mInsertBefore)(DATA_TYPE *first, DATA_TYPE *second);	 -																				 -public: -	LLDoubleLinkedList(); - -	// destructor destroys list and nodes, but not data in nodes -	~LLDoubleLinkedList(); - -	// put data into a node and stick it at the front of the list -	// set mCurrentp to mQueuep -	void addData(DATA_TYPE *data); - -	// put data into a node and stick it at the end of the list -	// set mCurrentp to mQueuep -	void addDataAtEnd(DATA_TYPE *data); - -	S32 getLength() const; -	// search the list starting at mHead.mNextp and remove the link with mDatap == data -	// set mCurrentp to mQueuep -	// return TRUE if found, FALSE if not found -	BOOL removeData(const DATA_TYPE *data); - -	// search the list starting at mHead.mNextp and delete the link with mDatap == data -	// set mCurrentp to mQueuep -	// return TRUE if found, FALSE if not found -	BOOL deleteData(DATA_TYPE *data); - -	// remove all nodes from the list and delete the associated data -	void deleteAllData(); - -	// remove all nodes from the list but do not delete data -	void removeAllNodes(); - -	BOOL isEmpty(); - -	// check to see if data is in list -	// set mCurrentp and mQueuep to the target of search if found, otherwise set mCurrentp to mQueuep -	// return TRUE if found, FALSE if not found -	BOOL	checkData(const DATA_TYPE *data); - -	// NOTE: This next two funtions are only included here  -	// for those too familiar with the LLLinkedList template class. -	// They are depreciated.  resetList() is unecessary while  -	// getCurrentData() is identical to getNextData() and has -	// a misleading name. -	// -	// The recommended way to loop through a list is as follows: -	// -	// datap = list.getFirstData(); -	// while (datap) -	// { -	//     /* do stuff */ -	//     datap = list.getNextData(); -	// } - -		// place mQueuep on mHead node -		void resetList(); -	 -		// return the data currently pointed to,  -		// set mCurrentp to that node and bump mQueuep down the list -		// NOTE: this function is identical to getNextData() -		DATA_TYPE *getCurrentData(); - - -	// reset the list and return the data currently pointed to,  -	// set mCurrentp to that node and bump mQueuep down the list -	DATA_TYPE *getFirstData(); - - -	// reset the list and return the data at position n, set mCurentp  -	// to that node and bump mQueuep down the list -	// Note: n=0 will behave like getFirstData() -	DATA_TYPE *getNthData(U32 n); - -	// reset the list and return the last data in it,  -	// set mCurrentp to that node and bump mQueuep up the list -	DATA_TYPE *getLastData(); - -	// return data in mQueuep, -	// set mCurrentp mQueuep and bump mQueuep down the list -	DATA_TYPE *getNextData(); - -	// return the data in mQueuep,  -	// set mCurrentp to mQueuep and bump mQueuep up the list -	DATA_TYPE *getPreviousData(); - -	// remove the Node at mCurrentp -	// set mCurrentp to mQueuep -	void removeCurrentData(); - -	// delete the Node at mCurrentp -	// set mCurrentp to mQueuep -	void deleteCurrentData(); - -	// remove the Node at mCurrentp and insert it into newlist -	// set mCurrentp to mQueuep -	void moveCurrentData(LLDoubleLinkedList<DATA_TYPE> *newlist); - -	// insert the node in front of mCurrentp -	// set mCurrentp to mQueuep -	void insertNode(LLDoubleLinkedNode<DATA_TYPE> *node); - -	// insert the data in front of mCurrentp -	// set mCurrentp to mQueuep -	void insertData(DATA_TYPE *data); - -	// if mCurrentp has a previous node then : -	//   * swaps mCurrentp with its previous -	//   * set mCurrentp to mQueuep -	//     (convenient for forward bubble-sort) -	// otherwise does nothing -	void swapCurrentWithPrevious(); - -	// if mCurrentp has a next node then : -	//   * swaps mCurrentp with its next -	//   * set mCurrentp to mQueuep -	//     (convenient for backwards bubble-sort) -	// otherwise does nothing -	void swapCurrentWithNext(); - -	// move mCurrentp to the front of the list -	// set mCurrentp to mQueuep -	void moveCurrentToFront(); -	 -	// move mCurrentp to the end of the list -	// set mCurrentp to mQueuep -	void moveCurrentToEnd(); - -	// set mInsertBefore -	void setInsertBefore(BOOL (*insert_before)(DATA_TYPE *first, DATA_TYPE *second)); - -	// add data in front of first node for which mInsertBefore(datap, node->mDatap) returns TRUE -	// set mCurrentp to mQueuep -	BOOL addDataSorted(DATA_TYPE *datap); - -	// sort the list using bubble-sort -	// Yes, this is a different name than the same function in LLLinkedList. -	// When it comes time for a name consolidation hopefully this one will win. -	BOOL bubbleSort(); - -	// does a single bubble sort pass on the list -	BOOL lazyBubbleSort(); - -	// returns TRUE if state successfully pushed (state stack not full) -	BOOL pushState(); - -	// returns TRUE if state successfully popped (state stack not empty) -	BOOL popState(); - -	// empties the state stack -	void clearStateStack(); - -	// randomly move the the links in the list for debug or (Discordian) purposes -	// sets mCurrentp and mQueuep to top of list -	void scramble(); - -private: -	// add node to beginning of list -	// set mCurrentp to mQueuep -	void addNode(LLDoubleLinkedNode<DATA_TYPE> *node); - -	// add node to end of list -	// set mCurrentp to mQueuep -	void addNodeAtEnd(LLDoubleLinkedNode<DATA_TYPE> *node); -}; - -//#endif - -//////////////////////////////////////////////////////////////////////////////////////////// - -// doublelinkedlist.cpp -// LLDoubleLinkedList template class implementation file. -// Provides a standard doubly linked list for fun and profit. -//  -// Copyright 2001, Linden Research, Inc. - -//#include "llerror.h" -//#include "doublelinkedlist.h" - -////////////////////////////////////////////////////////////////////////////////////////// -// LLDoubleLinkedNode -////////////////////////////////////////////////////////////////////////////////////////// - - -// assign the mDatap pointer -template <class DATA_TYPE> -LLDoubleLinkedNode<DATA_TYPE>::LLDoubleLinkedNode(DATA_TYPE *data) :  -	mDatap(data), mNextp(NULL), mPrevp(NULL) -{ -} - - -// destructor does not, by default, destroy associated data -// however, the mDatap must be NULL to ensure that we aren't causing memory leaks -template <class DATA_TYPE> -LLDoubleLinkedNode<DATA_TYPE>::~LLDoubleLinkedNode() -{ -	if (mDatap) -	{ -		llerror("Attempting to call LLDoubleLinkedNode destructor with a non-null mDatap!", 1); -	} -} - - -// delete associated data and NULL out pointer -template <class DATA_TYPE> -void LLDoubleLinkedNode<DATA_TYPE>::deleteData() -{ -	delete mDatap; -	mDatap = NULL; -} - - -template <class DATA_TYPE> -void LLDoubleLinkedNode<DATA_TYPE>::removeData() -{ -	mDatap = NULL; -} - - -////////////////////////////////////////////////////////////////////////////////////// -// LLDoubleLinkedList -////////////////////////////////////////////////////////////////////////////////////// - -//                                   <------- up ------- -// -//                                               mCurrentp -//                                   mQueuep         | -//                                      |            | -//                                      |            |  -//                      .------.     .------.     .------.      .------. -//                      |      |---->|      |---->|      |----->|      |-----> NULL -//           NULL <-----|      |<----|      |<----|      |<-----|      | -//                     _'------'     '------'     '------'      '------:_ -//             .------. /|               |             |               |\ .------. -//  NULL <-----|mHead |/                 |         mQueuep               \|mTail |-----> NULL -//             |      |               mCurrentp                           |      | -//             '------'                                                   '------' -//                               -------- down ---------> - -template <class DATA_TYPE> -LLDoubleLinkedList<DATA_TYPE>::LLDoubleLinkedList() -: mHead(NULL), mTail(NULL), mQueuep(NULL) -{ -	mCurrentp = mHead.mNextp; -	mQueuep = mHead.mNextp; -	mStateStackDepth = 0; -	mCount = 0; -	mInsertBefore = NULL; -} - - -// destructor destroys list and nodes, but not data in nodes -template <class DATA_TYPE> -LLDoubleLinkedList<DATA_TYPE>::~LLDoubleLinkedList() -{ -	removeAllNodes(); -} - - -// put data into a node and stick it at the front of the list -// doesn't change mCurrentp nor mQueuep -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::addData(DATA_TYPE *data) -{ -	// don't allow NULL to be passed to addData -	if (!data) -	{ -		llerror("NULL pointer passed to LLDoubleLinkedList::addData()", 0); -	} - -	// make the new node -	LLDoubleLinkedNode<DATA_TYPE> *temp = new LLDoubleLinkedNode<DATA_TYPE> (data); - -	// add the node to the front of the list -	temp->mPrevp = NULL;  -	temp->mNextp = mHead.mNextp; -	mHead.mNextp = temp; - -	// if there's something in the list, fix its back pointer -	if (temp->mNextp) -	{ -		temp->mNextp->mPrevp = temp; -	} -	// otherwise, fix the tail of the list -	else  -	{ -		mTail.mPrevp = temp; -	} - -	mCount++; -} - - -// put data into a node and stick it at the end of the list -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::addDataAtEnd(DATA_TYPE *data) -{ -	// don't allow NULL to be passed to addData -	if (!data) -	{ -		llerror("NULL pointer passed to LLDoubleLinkedList::addData()", 0); -	} - -	// make the new node -	LLDoubleLinkedNode<DATA_TYPE> *nodep = new LLDoubleLinkedNode<DATA_TYPE>(data); - -	addNodeAtEnd(nodep); -	mCount++; -} - - -// search the list starting at mHead.mNextp and remove the link with mDatap == data -// set mCurrentp to mQueuep, or NULL if mQueuep points to node with mDatap == data -// return TRUE if found, FALSE if not found -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::removeData(const DATA_TYPE *data) -{ -	BOOL b_found = FALSE; -	// don't allow NULL to be passed to addData -	if (!data) -	{ -		llerror("NULL pointer passed to LLDoubleLinkedList::removeData()", 0); -	} - -	mCurrentp = mHead.mNextp; - -	while (mCurrentp) -	{ -		if (mCurrentp->mDatap == data) -		{ -			b_found = TRUE; - -			// if there is a next one, fix it -			if (mCurrentp->mNextp) -			{ -				mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -			} -			else // we are at end of list -			{ -				mTail.mPrevp = mCurrentp->mPrevp; -			} - -			// if there is a previous one, fix it -			if (mCurrentp->mPrevp) -			{ -				mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -			} -			else // we are at beginning of list -			{ -				mHead.mNextp = mCurrentp->mNextp; -			} - -			// remove the node -			mCurrentp->removeData(); -			delete mCurrentp; -			mCount--; -			break; -		} -		mCurrentp = mCurrentp->mNextp;  -	} - -	// reset the list back to where it was -	if (mCurrentp == mQueuep) -	{ -		mCurrentp = mQueuep = NULL; -	} -	else -	{ -		mCurrentp = mQueuep; -	} - -	return b_found; -} - - -// search the list starting at mHead.mNextp and delete the link with mDatap == data -// set mCurrentp to mQueuep, or NULL if mQueuep points to node with mDatap == data -// return TRUE if found, FALSE if not found -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::deleteData(DATA_TYPE *data) -{ -	BOOL b_found = FALSE; -	// don't allow NULL to be passed to addData -	if (!data) -	{ -		llerror("NULL pointer passed to LLDoubleLinkedList::deleteData()", 0); -	} - -	mCurrentp = mHead.mNextp; - -	while (mCurrentp) -	{ -		if (mCurrentp->mDatap == data) -		{ -			b_found = TRUE; - -			// if there is a next one, fix it -			if (mCurrentp->mNextp) -			{ -				mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -			} -			else // we are at end of list -			{ -				mTail.mPrevp = mCurrentp->mPrevp; -			} - -			// if there is a previous one, fix it -			if (mCurrentp->mPrevp) -			{ -				mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -			} -			else // we are at beginning of list -			{ -				mHead.mNextp = mCurrentp->mNextp; -			} - -			// remove the node -			mCurrentp->deleteData(); -			delete mCurrentp; -			mCount--; -			break; -		} -		mCurrentp = mCurrentp->mNextp; -	} - -	// reset the list back to where it was -	if (mCurrentp == mQueuep) -	{ -		mCurrentp = mQueuep = NULL; -	} -	else -	{ -		mCurrentp = mQueuep; -	} - -	return b_found; -} - - -// remove all nodes from the list and delete the associated data -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::deleteAllData() -{ -	mCurrentp = mHead.mNextp; - -	while (mCurrentp) -	{ -		mQueuep = mCurrentp->mNextp; -		mCurrentp->deleteData(); -		delete mCurrentp; -		mCurrentp = mQueuep; -	} - -	// reset mHead and mQueuep -	mHead.mNextp = NULL; -	mTail.mPrevp = NULL; -	mCurrentp = mHead.mNextp; -	mQueuep = mHead.mNextp; -	mStateStackDepth = 0; -	mCount = 0; -} - - -// remove all nodes from the list but do not delete associated data -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::removeAllNodes() -{ -	mCurrentp = mHead.mNextp; - -	while (mCurrentp) -	{ -		mQueuep = mCurrentp->mNextp; -		mCurrentp->removeData(); -		delete mCurrentp; -		mCurrentp = mQueuep; -	} - -	// reset mHead and mCurrentp -	mHead.mNextp = NULL; -	mTail.mPrevp = NULL; -	mCurrentp = mHead.mNextp; -	mQueuep = mHead.mNextp; -	mStateStackDepth = 0; -	mCount = 0; -} - -template <class DATA_TYPE> -S32 LLDoubleLinkedList<DATA_TYPE>::getLength() const -{ -//	U32	length = 0; -//	for (LLDoubleLinkedNode<DATA_TYPE>* temp = mHead.mNextp; temp != NULL; temp = temp->mNextp) -//	{ -//		length++; -//	} -	return mCount; -} - -// check to see if data is in list -// set mCurrentp and mQueuep to the target of search if found, otherwise set mCurrentp to mQueuep -// return TRUE if found, FALSE if not found -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::checkData(const DATA_TYPE *data) -{ -	mCurrentp = mHead.mNextp; - -	while (mCurrentp) -	{ -		if (mCurrentp->mDatap == data) -		{ -			mQueuep = mCurrentp; -			return TRUE; -		} -		mCurrentp = mCurrentp->mNextp; -	} - -	mCurrentp = mQueuep; -	return FALSE; -} - -// NOTE: This next two funtions are only included here  -// for those too familiar with the LLLinkedList template class. -// They are depreciated.  resetList() is unecessary while  -// getCurrentData() is identical to getNextData() and has -// a misleading name. -// -// The recommended way to loop through a list is as follows: -// -// datap = list.getFirstData(); -// while (datap) -// { -//     /* do stuff */ -//     datap = list.getNextData(); -// } - -	// place mCurrentp and mQueuep on first node -	template <class DATA_TYPE> -	void LLDoubleLinkedList<DATA_TYPE>::resetList() -	{ -		mCurrentp = mHead.mNextp; -		mQueuep = mHead.mNextp; -		mStateStackDepth = 0; -	} -	 -	 -	// return the data currently pointed to,  -	// set mCurrentp to that node and bump mQueuep down the list -	template <class DATA_TYPE> -	DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getCurrentData() -	{ -		if (mQueuep) -		{ -			mCurrentp = mQueuep; -			mQueuep = mQueuep->mNextp; -			return mCurrentp->mDatap; -		} -		else -		{ -			return NULL; -		} -	} - - -// reset the list and return the data currently pointed to,  -// set mCurrentp to that node and bump mQueuep down the list -template <class DATA_TYPE> -DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getFirstData() -{ -	mQueuep = mHead.mNextp; -	mCurrentp = mQueuep; -	if (mQueuep) -	{ -		mQueuep = mQueuep->mNextp; -		return mCurrentp->mDatap; -	} -	else -	{ -		return NULL; -	} -} - - -// reset the list and return the data at position n, set mCurentp  -// to that node and bump mQueuep down the list -// Note: n=0 will behave like getFirstData() -template <class DATA_TYPE> -DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getNthData(U32 n) -{ -	mCurrentp = mHead.mNextp; - -	if (mCurrentp) -	{ -		for (U32 i=0; i<n; i++) -		{ -			mCurrentp = mCurrentp->mNextp; -			if (!mCurrentp) -			{ -				break; -			}		 -		} -	} - -	if (mCurrentp) -	{ -		// bump mQueuep down the list -		mQueuep = mCurrentp->mNextp; -		return mCurrentp->mDatap; -	} -	else -	{ -		mQueuep = NULL; -		return NULL; -	} -} - - -// reset the list and return the last data in it,  -// set mCurrentp to that node and bump mQueuep up the list -template <class DATA_TYPE> -DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getLastData() -{ -	mQueuep = mTail.mPrevp; -	mCurrentp = mQueuep; -	if (mQueuep) -	{ -		mQueuep = mQueuep->mPrevp; -		return mCurrentp->mDatap; -	} -	else -	{ -		return NULL; -	} -} - - -// return the data in mQueuep,  -// set mCurrentp to mQueuep and bump mQueuep down the list -template <class DATA_TYPE> -DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getNextData() -{ -	if (mQueuep) -	{ -		mCurrentp = mQueuep; -		mQueuep = mQueuep->mNextp; -		return mCurrentp->mDatap; -	} -	else -	{ -		return NULL; -	} -} - - -// return the data in mQueuep,  -// set mCurrentp to mQueuep and bump mQueuep up the list -template <class DATA_TYPE> -DATA_TYPE* LLDoubleLinkedList<DATA_TYPE>::getPreviousData() -{ -	if (mQueuep) -	{ -		mCurrentp = mQueuep; -		mQueuep = mQueuep->mPrevp; -		return mCurrentp->mDatap; -	} -	else -	{ -		return NULL; -	} -} - - -// remove the Node at mCurrentp -// set mCurrentp to mQueuep, or NULL if (mCurrentp == mQueuep) -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::removeCurrentData() -{ -	if (mCurrentp) -	{ -		// if there is a next one, fix it -		if (mCurrentp->mNextp) -		{ -			mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -		} -		else	// otherwise we are at end of list -		{ -			mTail.mPrevp = mCurrentp->mPrevp; -		} - -		// if there is a previous one, fix it -		if (mCurrentp->mPrevp) -		{ -			mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -		} -		else	// otherwise we are at beginning of list -		{ -			mHead.mNextp = mCurrentp->mNextp; -		} - -		// remove the node -		mCurrentp->removeData(); -		delete mCurrentp; -		mCount--; - -		// check for redundant pointing -		if (mCurrentp == mQueuep) -		{ -			mCurrentp = mQueuep = NULL; -		} -		else -		{ -			mCurrentp = mQueuep; -		} -	} -} - - -// delete the Node at mCurrentp -// set mCurrentp to mQueuep, or NULL if (mCurrentp == mQueuep)  -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::deleteCurrentData() -{ -	if (mCurrentp) -	{ -		// remove the node -		// if there is a next one, fix it -		if (mCurrentp->mNextp) -		{ -			mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -		} -		else	// otherwise we are at end of list -		{ -			mTail.mPrevp = mCurrentp->mPrevp; -		} - -		// if there is a previous one, fix it -		if (mCurrentp->mPrevp) -		{ -			mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -		} -		else	// otherwise we are at beginning of list -		{ -			mHead.mNextp = mCurrentp->mNextp; -		} - -		// remove the LLDoubleLinkedNode -		mCurrentp->deleteData(); -		delete mCurrentp; -		mCount--; - -		// check for redundant pointing -		if (mCurrentp == mQueuep) -		{ -			mCurrentp = mQueuep = NULL; -		} -		else -		{ -			mCurrentp = mQueuep; -		} -	} -} - - -// remove the Node at mCurrentp and insert it into newlist -// set mCurrentp to mQueuep, or NULL if (mCurrentp == mQueuep) -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::moveCurrentData(LLDoubleLinkedList<DATA_TYPE> *newlist) -{ -	if (mCurrentp) -	{ -		// remove the node -		// if there is a next one, fix it -		if (mCurrentp->mNextp) -		{ -			mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -		} -		else	// otherwise we are at end of list -		{ -			mTail.mPrevp = mCurrentp->mPrevp; -		} - -		// if there is a previous one, fix it -		if (mCurrentp->mPrevp) -		{ -			mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -		} -		else	// otherwise we are at beginning of list -		{ -			mHead.mNextp = mCurrentp->mNextp; -		} - -		// move the node to the new list -		newlist->addNode(mCurrentp); - -		// check for redundant pointing -		if (mCurrentp == mQueuep) -		{ -			mCurrentp = mQueuep = NULL; -		} -		else -		{ -			mCurrentp = mQueuep; -		} -	} -} - - -// Inserts the node previous to mCurrentp -// set mCurrentp to mQueuep -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::insertNode(LLDoubleLinkedNode<DATA_TYPE> *nodep) -{ -	// don't allow pointer to NULL to be passed -	if (!nodep) -	{ -		llerror("NULL pointer passed to LLDoubleLinkedList::insertNode()", 0); -	} -	if (!nodep->mDatap) -	{ -		llerror("NULL data pointer passed to LLDoubleLinkedList::insertNode()", 0); -	} - -	if (mCurrentp) -	{ -		if (mCurrentp->mPrevp) -		{ -			nodep->mPrevp = mCurrentp->mPrevp; -			nodep->mNextp = mCurrentp; -			mCurrentp->mPrevp->mNextp = nodep; -			mCurrentp->mPrevp = nodep; -		} -		else	// at beginning of list -		{ -			nodep->mPrevp = NULL; -			nodep->mNextp = mCurrentp; -			mHead.mNextp = nodep; -			mCurrentp->mPrevp = nodep; -		} -		mCurrentp = mQueuep; -	} -	else	// add to front of list -	{ -		addNode(nodep); -	} -} - - -// insert the data in front of mCurrentp -// set mCurrentp to mQueuep -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::insertData(DATA_TYPE *data) -{ -	if (!data) -	{ -		llerror("NULL data pointer passed to LLDoubleLinkedList::insertNode()", 0); -	} -	LLDoubleLinkedNode<DATA_TYPE> *node = new LLDoubleLinkedNode<DATA_TYPE>(data); -	insertNode(node); -	mCount++; -} - - -// if mCurrentp has a previous node then : -//   * swaps mCurrentp with its previous -//   * set mCurrentp to mQueuep -// otherwise does nothing -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::swapCurrentWithPrevious() -{ -	if (mCurrentp) -	{ -		if (mCurrentp->mPrevp) -		{ -			// Pull mCurrentp out of list -			mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -			if (mCurrentp->mNextp) -			{ -				mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -			} -			else 	// mCurrentp was at end of list -			{ -				mTail.mPrevp = mCurrentp->mPrevp; -			} - -			// Fix mCurrentp's pointers -			mCurrentp->mNextp = mCurrentp->mPrevp; -			mCurrentp->mPrevp = mCurrentp->mNextp->mPrevp; -			mCurrentp->mNextp->mPrevp = mCurrentp; - -			if (mCurrentp->mPrevp) -			{ -				// Fix the backward pointer of mCurrentp's new previous -				mCurrentp->mPrevp->mNextp = mCurrentp; -			} -			else	// mCurrentp is now at beginning of list -			{ -				mHead.mNextp = mCurrentp; -			} - -			// Set the list back to the way it was -			mCurrentp = mQueuep; -		} -	} -} - - -// if mCurrentp has a next node then : -//   * swaps mCurrentp with its next -//   * set mCurrentp to mQueuep -// otherwise does nothing -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::swapCurrentWithNext() -{ -	if (mCurrentp) -	{ -		if (mCurrentp->mNextp) -		{ -			// Pull mCurrentp out of list -			mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -			if (mCurrentp->mPrevp) -			{ -				mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -			} -			else 	// mCurrentp was at beginning of list -			{ -				mHead.mNextp = mCurrentp->mNextp; -			} - -			// Fix mCurrentp's pointers -			mCurrentp->mPrevp = mCurrentp->mNextp; -			mCurrentp->mNextp = mCurrentp->mPrevp->mNextp; -			mCurrentp->mPrevp->mNextp = mCurrentp; - -			if (mCurrentp->mNextp) -			{ -				// Fix the back pointer of mCurrentp's new next -				mCurrentp->mNextp->mPrevp = mCurrentp; -			} -			else 	// mCurrentp is now at end of list -			{ -				mTail.mPrevp = mCurrentp; -			} -			 -			// Set the list back to the way it was -			mCurrentp = mQueuep; -		} -	} -} - -// move mCurrentp to the front of the list -// set mCurrentp to mQueuep -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::moveCurrentToFront() -{ -	if (mCurrentp) -	{ -		// if there is a previous one, fix it -		if (mCurrentp->mPrevp) -		{ -			mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -		} -		else	// otherwise we are at beginning of list -		{ -			// check for redundant pointing -			if (mCurrentp == mQueuep) -			{ -				mCurrentp = mQueuep = NULL; -			} -			else -			{ -				mCurrentp = mQueuep; -			} -			return; -		} - -		// if there is a next one, fix it -		if (mCurrentp->mNextp) -		{ -			mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -		} -		else	// otherwise we are at end of list -		{ -			mTail.mPrevp = mCurrentp->mPrevp; -		} - -		// add mCurrentp to beginning of list -		mCurrentp->mNextp = mHead.mNextp; -		mHead.mNextp->mPrevp = mCurrentp;	// mHead.mNextp MUST be valid,  -											// or the list had only one node -											// and we would have returned already -		mCurrentp->mPrevp = NULL; -		mHead.mNextp = mCurrentp; - -		// check for redundant pointing -		if (mCurrentp == mQueuep) -		{ -			mCurrentp = mQueuep = NULL; -		} -		else -		{ -			mCurrentp = mQueuep; -		} -	} - -} - -// move mCurrentp to the end of the list -// set mCurrentp to mQueuep -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::moveCurrentToEnd() -{ -	if (mCurrentp) -	{ -		// if there is a next one, fix it -		if (mCurrentp->mNextp) -		{ -			mCurrentp->mNextp->mPrevp = mCurrentp->mPrevp; -		} -		else	// otherwise we are at end of list and we're done -		{ -			// check for redundant pointing -			if (mCurrentp == mQueuep) -			{ -				mCurrentp = mQueuep = NULL; -			} -			else -			{ -				mCurrentp = mQueuep; -			} -			return; -		} - -		// if there is a previous one, fix it -		if (mCurrentp->mPrevp) -		{ -			mCurrentp->mPrevp->mNextp = mCurrentp->mNextp; -		} -		else	// otherwise we are at beginning of list -		{ -			mHead.mNextp = mCurrentp->mNextp; -		} - -		// add mCurrentp to end of list -		mCurrentp->mPrevp = mTail.mPrevp; -		mTail.mPrevp->mNextp = mCurrentp;	// mTail.mPrevp MUST be valid,  -											// or the list had only one node -											// and we would have returned already -		mCurrentp->mNextp = NULL; -		mTail.mPrevp = mCurrentp; - -		// check for redundant pointing -		if (mCurrentp == mQueuep) -		{ -			mCurrentp = mQueuep = NULL; -		} -		else -		{ -			mCurrentp = mQueuep; -		} -	} -} - - -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::setInsertBefore(BOOL (*insert_before)(DATA_TYPE *first, DATA_TYPE *second) ) -{ -	mInsertBefore = insert_before; -} - - -// add data in front of the first node for which mInsertBefore(datap, node->mDatap) returns TRUE -// set mCurrentp to mQueuep -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::addDataSorted(DATA_TYPE *datap) -{ -	// don't allow NULL to be passed to addData() -	if (!datap) -	{ -		llerror("NULL pointer passed to LLDoubleLinkedList::addDataSorted()", 0); -	} - -	// has mInsertBefore not been set? -	if (!mInsertBefore) -	{ -		addData(datap); -		return FALSE; -	} - -	// is the list empty? -	if (!mHead.mNextp) -	{ -		addData(datap); -		return TRUE; -	} - -	// Note: this step has been added so that the behavior of LLDoubleLinkedList -	// is as rigorous as the LLLinkedList class about adding duplicate nodes. -	// Duplicate nodes can cause a problem when sorting if mInsertBefore(foo, foo)  -	// returns TRUE.  However, if mInsertBefore(foo, foo) returns FALSE, then there  -	// shouldn't be any reason to exclude duplicate nodes (as we do here). -	if (checkData(datap)) -	{ -		return FALSE; -	} -	 -	mCurrentp = mHead.mNextp; -	while (mCurrentp) -	{ -		// check to see if datap is already in the list -		if (datap == mCurrentp->mDatap) -		{ -			return FALSE; -		} -		else if (mInsertBefore(datap, mCurrentp->mDatap)) -		{ -			insertData(datap); -			return TRUE; -		} -		mCurrentp = mCurrentp->mNextp; -	} -	 -	addDataAtEnd(datap); -	return TRUE; -} - - -// bubble-sort until sorted and return TRUE if anything was sorted -// leaves mQueuep pointing at last node that was swapped with its mNextp -// -// NOTE: if you find this function looping for really long times, then you -// probably need to check your implementation of mInsertBefore(a,b) and make  -// sure it does not return TRUE when (a == b)! -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::bubbleSort() -{ -	BOOL b_swapped = FALSE; -	U32 count = 0; -	while (lazyBubbleSort())  -	{ -		b_swapped = TRUE; -		if (count++ > 0x7FFFFFFF) -		{ -			llwarning("LLDoubleLinkedList::bubbleSort() : too many passes...", 1); -			llwarning("    make sure the mInsertBefore(a, b) does not return TRUE for a == b", 1); -			break; -		} -	} -	return b_swapped; -} - - -// do a single bubble-sort pass and return TRUE if anything was sorted -// leaves mQueuep pointing at last node that was swapped with its mNextp -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::lazyBubbleSort() -{ -	// has mInsertBefore been set? -	if (!mInsertBefore) -	{ -		return FALSE; -	} - -	// is list empty? -	mCurrentp = mHead.mNextp; -	if (!mCurrentp) -	{ -		return FALSE; -	} - -	BOOL b_swapped = FALSE; - -	// the sort will exit after 0x7FFFFFFF nodes or the end of the list, whichever is first -	S32  length = 0x7FFFFFFF; -	S32  count = 0; - -	while (mCurrentp  &&  mCurrentp->mNextp  &&  count<length) -	{ -		if (mInsertBefore(mCurrentp->mNextp->mDatap, mCurrentp->mDatap)) -		{ -			b_swapped = TRUE; -			mQueuep = mCurrentp; -			swapCurrentWithNext();	// sets mCurrentp to mQueuep -		} -		count++; -		mCurrentp = mCurrentp->mNextp; -	} -	 -	return b_swapped; -} - - -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::pushState() -{ -	if (mStateStackDepth < LLDOUBLE_LINKED_LIST_STATE_STACK_DEPTH) -	{ -		*(mQueuepStack + mStateStackDepth) = mQueuep; -		*(mCurrentpStack + mStateStackDepth) = mCurrentp; -		mStateStackDepth++; -		return TRUE; -	} -	return FALSE; -} - - -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::popState() -{ -	if (mStateStackDepth > 0) -	{ -		mStateStackDepth--; -		mQueuep = *(mQueuepStack + mStateStackDepth); -		mCurrentp = *(mCurrentpStack + mStateStackDepth); -		return TRUE; -	} -	return FALSE; -} - - -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::clearStateStack() -{ -	mStateStackDepth = 0; -} - -////////////////////////////////////////////////////////////////////////////////////////// -// private members -////////////////////////////////////////////////////////////////////////////////////////// - -// add node to beginning of list -// set mCurrentp to mQueuep -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::addNode(LLDoubleLinkedNode<DATA_TYPE> *nodep) -{ -	// add the node to the front of the list -	nodep->mPrevp = NULL; -	nodep->mNextp = mHead.mNextp; -	mHead.mNextp = nodep; - -	// if there's something in the list, fix its back pointer -	if (nodep->mNextp) -	{ -		nodep->mNextp->mPrevp = nodep; -	} -	else	// otherwise fix the tail node -	{ -		mTail.mPrevp = nodep; -	} - -	mCurrentp = mQueuep; -} - - -// add node to end of list -// set mCurrentp to mQueuep -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::addNodeAtEnd(LLDoubleLinkedNode<DATA_TYPE> *node) -{ -	// add the node to the end of the list -	node->mNextp = NULL; -	node->mPrevp = mTail.mPrevp; -	mTail.mPrevp = node; - -	// if there's something in the list, fix its back pointer -	if (node->mPrevp) -	{ -		node->mPrevp->mNextp = node; -	} -	else	// otherwise fix the head node -	{ -		mHead.mNextp = node; -	} - -	mCurrentp = mQueuep; -} - - -// randomly move nodes in the list for DEBUG (or Discordian) purposes -// sets mCurrentp and mQueuep to top of list -template <class DATA_TYPE> -void LLDoubleLinkedList<DATA_TYPE>::scramble() -{ -	S32 random_number; -	DATA_TYPE *datap = getFirstData(); -	while(datap) -	{ -		random_number = ll_rand(5); - -		if (0 == random_number) -		{ -			removeCurrentData(); -			addData(datap); -		} -		else if (1 == random_number) -		{ -			removeCurrentData(); -			addDataAtEnd(datap); -		} -		else if (2 == random_number) -		{ -			swapCurrentWithPrevious(); -		} -		else if (3 == random_number) -		{ -			swapCurrentWithNext(); -		} -		datap = getNextData(); -	} -	mQueuep = mHead.mNextp; -	mCurrentp = mQueuep; -} - -template <class DATA_TYPE> -BOOL LLDoubleLinkedList<DATA_TYPE>::isEmpty() -{ -	return (mCount == 0); -} - - -#endif diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index d1c44c9403..47fa70614f 100755 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -29,6 +29,7 @@  #include "linden_common.h"  #include "llapr.h"  #include "apr_dso.h" +#include "llthreadlocalstorage.h"  apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool  LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool. @@ -37,12 +38,15 @@ apr_thread_mutex_t *gCallStacksLogMutexp = NULL;  const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool +bool gAPRInitialized = false; +  void ll_init_apr()  { +	// Initialize APR and create the global pool +	apr_initialize(); +	  	if (!gAPRPoolp)  	{ -		// Initialize APR and create the global pool -		apr_initialize();  		apr_pool_create(&gAPRPoolp, NULL);  		// Initialize the logging mutex @@ -52,13 +56,23 @@ void ll_init_apr()  	if(!LLAPRFile::sAPRFilePoolp)  	{ -		LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; +		LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE);  	} + +	LLThreadLocalPointerBase::initAllThreadLocalStorage(); +	gAPRInitialized = true;  } +bool ll_apr_is_initialized() +{ +	return gAPRInitialized; +} +  void ll_cleanup_apr()  { +	gAPRInitialized = false; +  	LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL;  	if (gLogMutexp) @@ -77,6 +91,9 @@ void ll_cleanup_apr()  		apr_thread_mutex_destroy(gCallStacksLogMutexp);  		gCallStacksLogMutexp = NULL;  	} + +	LLThreadLocalPointerBase::destroyAllThreadLocalStorage(); +  	if (gAPRPoolp)  	{  		apr_pool_destroy(gAPRPoolp); @@ -84,7 +101,7 @@ void ll_cleanup_apr()  	}  	if (LLAPRFile::sAPRFilePoolp)  	{ -		delete LLAPRFile::sAPRFilePoolp ; +		delete LLAPRFile::sAPRFilePoolp ;	  		LLAPRFile::sAPRFilePoolp = NULL ;  	}  	apr_terminate(); diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 752574c65d..e9b13c5919 100755 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -32,28 +32,34 @@  #if LL_LINUX || LL_SOLARIS  #include <sys/param.h>  // Need PATH_MAX in APR headers...  #endif -#if LL_WINDOWS -	// Limit Windows API to small and manageable set. -	// If you get undefined symbols, find the appropriate -	// Windows header file and include that in your .cpp file. -	#define WIN32_LEAN_AND_MEAN -	#include <winsock2.h> -	#include <windows.h> -#endif  #include <boost/noncopyable.hpp> - +#include "llwin32headerslean.h"  #include "apr_thread_proc.h"  #include "apr_thread_mutex.h"  #include "apr_getopt.h"  #include "apr_signal.h"  #include "apr_atomic.h" +  #include "llstring.h"  extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;  extern apr_thread_mutex_t* gCallStacksLogMutexp;  struct apr_dso_handle_t; +/** + * @brief Function which appropriately logs error or remains quiet on + * APR_SUCCESS. + * @return Returns <code>true</code> if status is an error condition. + */ +bool LL_COMMON_API ll_apr_warn_status(apr_status_t status); +/// There's a whole other APR error-message function if you pass a DSO handle. +bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* handle); + +void LL_COMMON_API ll_apr_assert_status(apr_status_t status); +void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle); + +extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool  /**    * @brief initialize the common apr constructs -- apr itself, the @@ -66,6 +72,9 @@ void LL_COMMON_API ll_init_apr();   */  void LL_COMMON_API ll_cleanup_apr(); +bool LL_COMMON_API ll_apr_is_initialized(); + +  //  //LL apr_pool  //manage apr_pool_t, destroy allocated apr_pool in the destruction function. @@ -163,14 +172,17 @@ public:  	LLAtomic32<Type>(Type x) {apr_atomic_set32(&mData, apr_uint32_t(x)); };  	~LLAtomic32<Type>() {}; -	operator const Type() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); } +	operator const Type() { return get(); }  	Type operator =(const Type& x) { apr_atomic_set32(&mData, apr_uint32_t(x)); return Type(mData); }  	void operator -=(Type x) { apr_atomic_sub32(&mData, apr_uint32_t(x)); }  	void operator +=(Type x) { apr_atomic_add32(&mData, apr_uint32_t(x)); }  	Type operator ++(int) { return apr_atomic_inc32(&mData); } // Type++ -	Type operator --(int) { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise) +	Type operator ++()	  { apr_atomic_inc32(&mData); return get();  } // ++Type +	Type operator --(int) { const Type result(get()); apr_atomic_dec32(&mData); return result; } // Type--  +	Type operator --()	  { return apr_atomic_dec32(&mData); } // approximately --Type (0 if final is 0, non-zero otherwise)  private: +	const Type get() { apr_uint32_t data = apr_atomic_read32(&mData); return Type(data); }  	apr_uint32_t mData;  }; @@ -257,18 +269,5 @@ public:  //*******************************************************************************************************************************  }; -/** - * @brief Function which appropriately logs error or remains quiet on - * APR_SUCCESS. - * @return Returns <code>true</code> if status is an error condition. - */ -bool LL_COMMON_API ll_apr_warn_status(apr_status_t status); -/// There's a whole other APR error-message function if you pass a DSO handle. -bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* handle); - -void LL_COMMON_API ll_apr_assert_status(apr_status_t status); -void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle); - -extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool  #endif // LL_LLAPR_H diff --git a/indra/llcommon/llassoclist.h b/indra/llcommon/llassoclist.h deleted file mode 100755 index 2950504155..0000000000 --- a/indra/llcommon/llassoclist.h +++ /dev/null @@ -1,296 +0,0 @@ -/**  - * @file llassoclist.h - * @brief LLAssocList class header file - * - * $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$ - */ - -#ifndef LL_LLASSOCLIST_H -#define LL_LLASSOCLIST_H - -//------------------------------------------------------------------------ -// LLAssocList is an associative list container class. -// -// The implementation is a single linked list. -// Both index and value objects are stored by value (not reference). -// If pointer values are specified for index and/or value, this -// container does NOT assume ownership of the referenced objects, -// and does NOT delete() them on removal or destruction of the container. -// -// Note that operations are generally not optimized, and may of them -// are O(n) complexity. -//------------------------------------------------------------------------ - -#include <iostream> - -template<class INDEX_TYPE, class VALUE_TYPE> -class LLAssocList -{ -private: -	// internal list node type -	class Node -	{ -	public: -		Node(const INDEX_TYPE &index, const VALUE_TYPE &value, Node *next) -		{ -			mIndex = index; -			mValue = value; -			mNext = next; -		} -		~Node() { } -		INDEX_TYPE	mIndex; -		VALUE_TYPE	mValue; -		Node		*mNext; -	}; - -	// head of the linked list -	Node *mHead; - -public: -	// Constructor -	LLAssocList() -	{ -		mHead = NULL; -	} - -	// Destructor -	~LLAssocList() -	{ -		removeAll(); -	} - -	// Returns TRUE if list is empty. -	BOOL isEmpty() -	{ -		return (mHead == NULL); -	} - -	// Returns the number of items in the list. -	U32 length() -	{ -		U32 count = 0; -		for (	Node *node = mHead; -				node; -				node = node->mNext ) -		{ -			count++; -		} -		return count; -	} - -	// Removes item with the specified index. -	BOOL remove( const INDEX_TYPE &index ) -	{ -		if (!mHead) -			return FALSE; - -		if (mHead->mIndex == index) -		{ -			Node *node = mHead; -			mHead = mHead->mNext; -			delete node; -			return TRUE; -		} - -		for (	Node *prev = mHead; -				prev->mNext; -				prev = prev->mNext ) -		{ -			if (prev->mNext->mIndex == index) -			{ -				Node *node = prev->mNext; -				prev->mNext = prev->mNext->mNext; -				delete node; -				return TRUE; -			} -		} -		return FALSE; -	} - -	// Removes all items from the list. -	void removeAll() -	{ -		while ( mHead ) -		{ -			Node *node = mHead; -			mHead = mHead->mNext; -			delete node; -		} -	} - -	// Adds a new item to the head of the list, -	// removing any existing item with same index. -	void addToHead( const INDEX_TYPE &index, const VALUE_TYPE &value ) -	{ -		remove(index); -		Node *node = new Node(index, value, mHead); -		mHead = node; -	} - -	// Adds a new item to the end of the list, -	// removing any existing item with the same index. -	void addToTail( const INDEX_TYPE &index, const VALUE_TYPE &value ) -	{ -		remove(index); -		Node *node = new Node(index, value, NULL); -		if (!mHead) -		{ -			mHead = node; -			return; -		} -		for (	Node *prev=mHead; -				prev; -				prev=prev->mNext ) -		{ -			if (!prev->mNext) -			{ -				prev->mNext=node; -				return; -			} -		} -	} - -	// Sets the value of a specified index. -	// If index does not exist, a new value will be added only if -	// 'addIfNotFound' is set to TRUE. -	// Returns TRUE if successful. -	BOOL setValue( const INDEX_TYPE &index, const VALUE_TYPE &value, BOOL addIfNotFound=FALSE ) -	{ -		VALUE_TYPE *valueP = getValue(index); -		if (valueP) -		{ -			*valueP = value; -			return TRUE; -		} -		if (!addIfNotFound) -			return FALSE; -		addToTail(index, value); -		return TRUE; -	} - -	// Sets the ith value in the list. -	// A new value will NOT be addded, if the ith value does not exist. -	// Returns TRUE if successful. -	BOOL setValueAt( U32 i, const VALUE_TYPE &value ) -	{ -		VALUE_TYPE *valueP = getValueAt(i); -		if (valueP) -		{ -			*valueP = value; -			return TRUE; -		} -		return FALSE; -	} - -	// Returns a pointer to the value for the specified index, -	// or NULL if no item found. -	VALUE_TYPE *getValue( const INDEX_TYPE &index ) -	{ -		for (	Node *node = mHead; -				node; -				node = node->mNext ) -		{ -			if (node->mIndex == index) -				return &node->mValue; -		} -		return NULL; -	} - -	// Returns a pointer to the ith value in the list, or -	// NULL if i is not valid. -	VALUE_TYPE *getValueAt( U32 i ) -	{ -		U32 count = 0; -		for (	Node *node = mHead; -				node; -				node = node->mNext ) -		{ -			if (count == i) -				return &node->mValue; -			count++; -		} -		return NULL; -	} - -	// Returns a pointer to the index for the specified index, -	// or NULL if no item found. -	INDEX_TYPE *getIndex( const INDEX_TYPE &index ) -	{ -		for (	Node *node = mHead; -				node; -				node = node->mNext ) -		{ -			if (node->mIndex == index) -				return &node->mIndex; -		} -		return NULL; -	} - -	// Returns a pointer to the ith index in the list, or -	// NULL if i is not valid. -	INDEX_TYPE *getIndexAt( U32 i ) -	{ -		U32 count = 0; -		for (	Node *node = mHead; -				node; -				node = node->mNext ) -		{ -			if (count == i) -				return &node->mIndex; -			count++; -		} -		return NULL; -	} - -	// Returns a pointer to the value for the specified index, -	// or NULL if no item found. -	VALUE_TYPE *operator[](const INDEX_TYPE &index) -	{ -		return getValue(index); -	} - -	// Returns a pointer to the ith value in the list, or -	// NULL if i is not valid. -	VALUE_TYPE *operator[](U32 i) -	{ -		return getValueAt(i); -	} - -	// Prints the list contents to the specified stream. -	friend std::ostream &operator<<( std::ostream &os, LLAssocList &map ) -	{ -		os << "{"; -		for (	Node *node = map.mHead; -				node; -				node = node->mNext ) -		{ -			os << "<" << node->mIndex << ", " << node->mValue << ">"; -			if (node->mNext) -				os << ", "; -		} -		os << "}"; - -		return os; -	} -}; - -#endif // LL_LLASSOCLIST_H diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 8be9e4f4de..c720df7555 100755 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -29,6 +29,7 @@  #include "llmemory.h"  #include "llthread.h" +#include "lltrace.h"  //static  BOOL LLCommon::sAprInitialized = FALSE; @@ -44,15 +45,13 @@ void LLCommon::initClass()  	}  	LLTimer::initClass();  	LLThreadSafeRefCount::initThreadSafeRefCount(); -// 	LLWorkerThread::initClass(); -// 	LLFrameCallbackManager::initClass(); +	LLTrace::init();  }  //static  void LLCommon::cleanupClass()  { -// 	LLFrameCallbackManager::cleanupClass(); -// 	LLWorkerThread::cleanupClass(); +	LLTrace::cleanup();  	LLThreadSafeRefCount::cleanupThreadSafeRefCount();  	LLTimer::cleanupClass();  	if (sAprInitialized) diff --git a/indra/llcommon/llcriticaldamp.cpp b/indra/llcommon/llcriticaldamp.cpp index 87d79b1ee0..2f013fe255 100755 --- a/indra/llcommon/llcriticaldamp.cpp +++ b/indra/llcommon/llcriticaldamp.cpp @@ -27,18 +27,38 @@  #include "linden_common.h"  #include "llcriticaldamp.h" +#include <algorithm>  //-----------------------------------------------------------------------------  // static members  //----------------------------------------------------------------------------- -LLFrameTimer LLCriticalDamp::sInternalTimer; -std::map<F32, F32> LLCriticalDamp::sInterpolants; -F32 LLCriticalDamp::sTimeDelta; +LLFrameTimer LLSmoothInterpolation::sInternalTimer; +std::vector<LLSmoothInterpolation::Interpolant> LLSmoothInterpolation::sInterpolants; +F32 LLSmoothInterpolation::sTimeDelta; + +// helper functors +struct LLSmoothInterpolation::CompareTimeConstants +{ +	bool operator()(const F32& a, const LLSmoothInterpolation::Interpolant& b) const +	{ +		return a < b.mTimeScale; +	} + +	bool operator()(const LLSmoothInterpolation::Interpolant& a, const F32& b) const +	{ +		return a.mTimeScale < b; // bottom of a is higher than bottom of b +	} + +	bool operator()(const LLSmoothInterpolation::Interpolant& a, const LLSmoothInterpolation::Interpolant& b) const +	{ +		return a.mTimeScale < b.mTimeScale; // bottom of a is higher than bottom of b +	} +};  //----------------------------------------------------------------------------- -// LLCriticalDamp() +// LLSmoothInterpolation()  //----------------------------------------------------------------------------- -LLCriticalDamp::LLCriticalDamp() +LLSmoothInterpolation::LLSmoothInterpolation()  {  	sTimeDelta = 0.f;  } @@ -47,43 +67,54 @@ LLCriticalDamp::LLCriticalDamp()  //-----------------------------------------------------------------------------  // updateInterpolants()  //----------------------------------------------------------------------------- -void LLCriticalDamp::updateInterpolants() +void LLSmoothInterpolation::updateInterpolants()  {  	sTimeDelta = sInternalTimer.getElapsedTimeAndResetF32(); -	F32 time_constant; - -	for (std::map<F32, F32>::iterator iter = sInterpolants.begin(); -		 iter != sInterpolants.end(); iter++) +	for (S32 i = 0; i < sInterpolants.size(); i++)  	{ -		time_constant = iter->first; -		F32 new_interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant); -		new_interpolant = llclamp(new_interpolant, 0.f, 1.f); -		sInterpolants[time_constant] = new_interpolant; +		Interpolant& interp = sInterpolants[i]; +		interp.mInterpolant = calcInterpolant(interp.mTimeScale);  	}  }   //-----------------------------------------------------------------------------  // getInterpolant()  //----------------------------------------------------------------------------- -F32 LLCriticalDamp::getInterpolant(const F32 time_constant, BOOL use_cache) +F32 LLSmoothInterpolation::getInterpolant(LLUnit<LLUnits::Seconds, F32> time_constant, bool use_cache)  {  	if (time_constant == 0.f)  	{  		return 1.f;  	} -	if (use_cache && sInterpolants.count(time_constant)) +	if (use_cache)  	{ -		return sInterpolants[time_constant]; +		interpolant_vec_t::iterator find_it = std::lower_bound(sInterpolants.begin(), sInterpolants.end(), time_constant.value(), CompareTimeConstants()); +		if (find_it != sInterpolants.end() && find_it->mTimeScale == time_constant)  +		{ +			return find_it->mInterpolant; +		} +		else +		{ +			Interpolant interp; +			interp.mTimeScale = time_constant.value(); +			interp.mInterpolant = calcInterpolant(time_constant.value()); +			sInterpolants.insert(find_it, interp); +			return interp.mInterpolant; +		}  	} -	 -	F32 interpolant = 1.f - pow(2.f, -sTimeDelta / time_constant); -	interpolant = llclamp(interpolant, 0.f, 1.f); -	if (use_cache) +	else  	{ -		sInterpolants[time_constant] = interpolant; +		return calcInterpolant(time_constant.value()); +  	} +} -	return interpolant; +//----------------------------------------------------------------------------- +// calcInterpolant() +//----------------------------------------------------------------------------- +F32 LLSmoothInterpolation::calcInterpolant(F32 time_constant) +{ +	return llclamp(1.f - powf(2.f, -sTimeDelta / time_constant), 0.f, 1.f);  } diff --git a/indra/llcommon/llcriticaldamp.h b/indra/llcommon/llcriticaldamp.h index 52f052ae25..ab5d4ba6e2 100755 --- a/indra/llcommon/llcriticaldamp.h +++ b/indra/llcommon/llcriticaldamp.h @@ -28,26 +28,46 @@  #ifndef LL_LLCRITICALDAMP_H  #define LL_LLCRITICALDAMP_H -#include <map> +#include <vector>  #include "llframetimer.h" +#include "llunit.h" -class LL_COMMON_API LLCriticalDamp  +class LL_COMMON_API LLSmoothInterpolation   {  public: -	LLCriticalDamp(); +	LLSmoothInterpolation();  	// MANIPULATORS  	static void updateInterpolants();  	// ACCESSORS -	static F32 getInterpolant(const F32 time_constant, BOOL use_cache = TRUE); +	static F32 getInterpolant(LLUnit<LLUnits::Seconds, F32> time_constant, bool use_cache = true); -protected:	 +	template<typename T>  +	static T lerp(T a, T b, LLUnit<LLUnits::Seconds, F32> time_constant, bool use_cache = true) +	{ +		F32 interpolant = getInterpolant(time_constant, use_cache); +		return ((a * (1.f - interpolant))  +				+ (b * interpolant)); +	} + +protected: +	static F32 calcInterpolant(F32 time_constant); + +	struct CompareTimeConstants;  	static LLFrameTimer sInternalTimer;	// frame timer for calculating deltas -	static std::map<F32, F32> 	sInterpolants; +	struct Interpolant +	{ +		F32 mTimeScale; +		F32 mInterpolant; +	}; +	typedef std::vector<Interpolant> interpolant_vec_t; +	static interpolant_vec_t 	sInterpolants;  	static F32					sTimeDelta;  }; +typedef LLSmoothInterpolation LLCriticalDamp; +  #endif  // LL_LLCRITICALDAMP_H diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 030ef6a3c7..2efe39e158 100755 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -39,6 +39,7 @@  #include "lltimer.h"  #include "llstring.h" +#include "llfasttimer.h"  static const F64 DATE_EPOCH = 0.0; @@ -48,18 +49,15 @@ static const F64 LL_APR_USEC_PER_SEC = 1000000.0;  LLDate::LLDate() : mSecondsSinceEpoch(DATE_EPOCH) -{ -} +{}  LLDate::LLDate(const LLDate& date) :  	mSecondsSinceEpoch(date.mSecondsSinceEpoch) -{ -} +{} -LLDate::LLDate(F64 seconds_since_epoch) : -	mSecondsSinceEpoch(seconds_since_epoch) -{ -} +LLDate::LLDate(LLUnit<LLUnits::Seconds, F64> seconds_since_epoch) : +	mSecondsSinceEpoch(seconds_since_epoch.value()) +{}  LLDate::LLDate(const std::string& iso8601_date)  { diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index 7ff8b550ad..b62a846147 100755 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h @@ -33,6 +33,7 @@  #include <string>  #include "stdtypes.h" +#include "llunit.h"  /**    * @class LLDate @@ -56,9 +57,9 @@ public:  	/**   	 * @brief Construct a date from a seconds since epoch value.  	 * -	 * @pararm seconds_since_epoch The number of seconds since UTC epoch. +	 * @param seconds_since_epoch The number of seconds since UTC epoch.  	 */ -	LLDate(F64 seconds_since_epoch); +	LLDate(LLUnit<LLUnits::Seconds, F64> seconds_since_epoch);  	/**   	 * @brief Construct a date from a string representation diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index 5a4b8325f4..d57b9dccff 100755 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h @@ -244,5 +244,8 @@ inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs)  	rhs = tmp;  } +#define LL_GLUE_IMPL(x, y) x##y +#define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y) +  #endif // LL_LLDEFS_H diff --git a/indra/llcommon/lldeleteutils.h b/indra/llcommon/lldeleteutils.h deleted file mode 100755 index f250dc3028..0000000000 --- a/indra/llcommon/lldeleteutils.h +++ /dev/null @@ -1,47 +0,0 @@ -/**  - * @file lldeleteutils.h - * @brief Utility functions to simplify some common pointer-munging idioms. - * - * $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_DELETE_UTILS_H -#define LL_DELETE_UTILS_H - -// Simple utility functions to eventually replace the common 2-line -// idiom scattered throughout the viewer codebase.  Note that where -// possible we would rather be using smart pointers of some sort. - -template <class T> -inline void deleteAndClear(T*& ptr) -{ -	delete ptr; -	ptr = NULL; -} - -template <class T> -inline void deleteAndClearArray(T*& array_ptr) -{ -	delete[] array_ptr; -	array_ptr = NULL; -} - -#endif diff --git a/indra/llcommon/lldepthstack.h b/indra/llcommon/lldepthstack.h index d9db54efc7..ac435a30fa 100755 --- a/indra/llcommon/lldepthstack.h +++ b/indra/llcommon/lldepthstack.h @@ -27,17 +27,20 @@  #ifndef LL_LLDEPTHSTACK_H  #define LL_LLDEPTHSTACK_H -#include "linked_lists.h" +#include "llstl.h"  template <class DATA_TYPE> class LLDepthStack  {  private: -	LLLinkedList<DATA_TYPE> mStack; +	std::deque<DATA_TYPE*>	mStack;  	U32						mCurrentDepth;  	U32						mMaxDepth;  public: -	LLDepthStack() : mCurrentDepth(0), mMaxDepth(0) {} +	LLDepthStack()  +	:	mCurrentDepth(0), mMaxDepth(0)  +	{} +  	~LLDepthStack()	{}  	void setDepth(U32 depth) @@ -54,24 +57,27 @@ public:  	{   		if (mCurrentDepth < mMaxDepth)  		{ -			mStack.addData(data);  +			mStack.push_back(data);   			mCurrentDepth++;  		}  		else  		{  			// the last item falls off stack and is deleted -			mStack.getLastData(); -			mStack.deleteCurrentData();	 -			mStack.addData(data); +			if (!mStack.empty()) +			{ +				mStack.pop_front(); +			} +			mStack.push_back(data);  		}  	}  	DATA_TYPE *pop()  	{  -		DATA_TYPE *tempp = mStack.getFirstData();  -		if (tempp) +		DATA_TYPE *tempp = NULL; +		if (!mStack.empty())  		{ -			mStack.removeCurrentData();  +			tempp = mStack.back(); +			mStack.pop_back();   			mCurrentDepth--;  		}  		return tempp;  @@ -79,20 +85,20 @@ public:  	DATA_TYPE *check()  	{  -		DATA_TYPE *tempp = mStack.getFirstData();  -		return tempp;  +		return mStack.empty() ? NULL : mStack.back();  	}  	void deleteAllData()  	{   		mCurrentDepth = 0; -		mStack.deleteAllData();  +		std::for_each(mStack.begin(), mStack.end(), DeletePointer()); +		mStack.clear();   	}  	void removeAllNodes()  	{   		mCurrentDepth = 0; -		mStack.removeAllNodes();  +		mStack.clear();   	}  }; diff --git a/indra/llcommon/lldlinked.h b/indra/llcommon/lldlinked.h deleted file mode 100755 index 3f7c197be7..0000000000 --- a/indra/llcommon/lldlinked.h +++ /dev/null @@ -1,93 +0,0 @@ -/**  - * @file lldlinked.h - * @brief Declaration of the LLDLinked class. - * - * $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$ - */ -#ifndef LL_LLDLINKED_H -#define LL_LLDLINKED_H - -template <class Type> class LLDLinked -{ -	LLDLinked* mNextp; -	LLDLinked* mPrevp; -public: - -	Type*   getNext()  { return (Type*)mNextp; } -	Type*   getPrev()  { return (Type*)mPrevp; } -	Type*   getFirst() { return (Type*)mNextp; } - -	void    init() -	{ -		mNextp = mPrevp = NULL; -	} - -	void    unlink() -	{ -		if (mPrevp) mPrevp->mNextp = mNextp; -		if (mNextp) mNextp->mPrevp = mPrevp; -	} - -	 LLDLinked() { mNextp = mPrevp = NULL; } -	virtual ~LLDLinked() { unlink(); } - -	virtual void    deleteAll() -	{ -		Type *curp = getFirst(); -		while(curp) -		{ -			Type *nextp = curp->getNext(); -			curp->unlink(); -			delete curp; -			curp = nextp; -		} -	} - -	void relink(Type &after) -	{ -		LLDLinked *afterp = (LLDLinked*)&after; -		afterp->mPrevp = this; -		mNextp = afterp; -	} - -	virtual void    append(Type& after) -	{ -		LLDLinked *afterp = (LLDLinked*)&after; -		afterp->mPrevp    = this; -		afterp->mNextp    = mNextp; -		if (mNextp) mNextp->mPrevp = afterp; -		mNextp            = afterp; -	} - -	virtual void    insert(Type& before) -	{ -		LLDLinked *beforep = (LLDLinked*)&before; -		beforep->mNextp    = this; -		beforep->mPrevp    = mPrevp; -		if (mPrevp) mPrevp->mNextp = beforep; -		mPrevp             = beforep; -	} - -	virtual void    put(Type& obj) { append(obj); } -}; - -#endif diff --git a/indra/llcommon/lldqueueptr.h b/indra/llcommon/lldqueueptr.h deleted file mode 100755 index 9fe08191e1..0000000000 --- a/indra/llcommon/lldqueueptr.h +++ /dev/null @@ -1,352 +0,0 @@ -/**  - * @file lldqueueptr.h - * @brief LLDynamicQueuePtr declaration - * - * $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$ - */ -#ifndef LL_LLDQUEUEPTR_H -#define LL_LLDQUEUEPTR_H - -template <class Type>  -class LLDynamicQueuePtr -{ -public: -	enum -	{ -		OKAY = 0, -		FAIL = -1 -	}; -	 -	LLDynamicQueuePtr(const S32 size=8); -	~LLDynamicQueuePtr(); - -	void init(); -	void destroy(); -	void reset(); -	void reallocate(U32 newsize); - -	// ACCESSORS -	const Type& get(const S32 index) const;					// no bounds checking -	Type&       get(const S32 index);						// no bounds checking -	const Type& operator []	(const S32 index) const			{ return get(index); } -	Type&       operator []	(const S32 index)				{ return get(index); } -	S32			find(const Type &obj) const; - -	S32			count() const								{ return (mLastObj >= mFirstObj ? mLastObj - mFirstObj : mLastObj + mMaxObj - mFirstObj); } -	S32			getMax() const								{ return mMaxObj; } -	S32			getFirst() const       { return mFirstObj; } -	S32			getLast () const       { return mLastObj; } - -	// MANIPULATE -	S32         push(const Type &obj);					// add to end of Queue, returns index from start -	S32			pull(      Type &obj);			        // pull from Queue, returns index from start - -	S32			remove   (S32 index);				    // remove by index -	S32			removeObj(const Type &obj);				// remove by object - -protected: -	S32           mFirstObj, mLastObj, mMaxObj; -	Type*		  mMemory; - -public: - -	void print() -	{ -		/* -		Convert this to llinfos if it's intended to be used - djs 08/30/02 - -		printf("Printing from %d to %d (of %d): ",mFirstObj, mLastObj, mMaxObj); - -		if (mFirstObj <= mLastObj) -		{ -			for (S32 i=mFirstObj;i<mLastObj;i++) -			{ -				printf("%d ",mMemory[i]); -			} -		} -		else -		{ -			for (S32 i=mFirstObj;i<mMaxObj;i++) -			{ -				printf("%d ",mMemory[i]); -			} -			for (i=0;i<mLastObj;i++) -			{ -				printf("%d ",mMemory[i]); -			} -		} -		printf("\n"); -		*/ -	} - -}; - - -//-------------------------------------------------------- -// LLDynamicQueuePtrPtr implementation -//-------------------------------------------------------- - - -template <class Type> -inline LLDynamicQueuePtr<Type>::LLDynamicQueuePtr(const S32 size) -{ -	init(); -	reallocate(size); -} - -template <class Type> -inline LLDynamicQueuePtr<Type>::~LLDynamicQueuePtr() -{ -	destroy(); -} - -template <class Type> -inline void LLDynamicQueuePtr<Type>::init() -{  -	mFirstObj    = 0; -	mLastObj     = 0; -	mMaxObj      = 0; -	mMemory      = NULL; -} - -template <class Type> -inline void LLDynamicQueuePtr<Type>::reallocate(U32 newsize) -{  -	if (newsize) -	{ -		if (mFirstObj > mLastObj && newsize > mMaxObj) -		{ -			Type* new_memory = new Type[newsize]; - -			llassert(new_memory); - -			S32 _count = count(); -			S32 i, m = 0; -			for (i=mFirstObj; i < mMaxObj; i++) -			{ -				new_memory[m++] = mMemory[i]; -			} -			for (i=0; i <=mLastObj; i++) -			{ -				new_memory[m++] = mMemory[i]; -			} - -			delete[] mMemory; -			mMemory = new_memory; - -			mFirstObj = 0; -			mLastObj  = _count; -		} -		else -		{ -			Type* new_memory = new Type[newsize]; - -			llassert(new_memory); - -			S32 i, m = 0; -			for (i=0; i < mLastObj; i++) -			{ -				new_memory[m++] = mMemory[i]; -			} -			delete[] mMemory; -			mMemory = new_memory; -		} -	} -	else if (mMemory) -	{ -		delete[] mMemory; -		mMemory = NULL; -	} - -	mMaxObj = newsize; -} - -template <class Type> -inline void LLDynamicQueuePtr<Type>::destroy() -{ -	reset(); -	delete[] mMemory; -	mMemory = NULL; -} - - -template <class Type> -void LLDynamicQueuePtr<Type>::reset()	    -{  -	for (S32 i=0; i < mMaxObj; i++) -	{ -		get(i) = NULL; // unrefs for pointers -	} - -	mFirstObj    = 0; -	mLastObj     = 0; -} - - -template <class Type> -inline S32 LLDynamicQueuePtr<Type>::find(const Type &obj) const -{ -	S32 i; -	if (mFirstObj <= mLastObj) -	{ -		for ( i = mFirstObj; i < mLastObj; i++ ) -		{ -			if (mMemory[i] == obj) -			{ -				return i; -			} -		} -	} -	else -	{ -		for ( i = mFirstObj; i < mMaxObj; i++ ) -		{ -			if (mMemory[i] == obj) -			{ -				return i; -			} -		} -		for ( i = 0; i < mLastObj; i++ ) -		{ -			if (mMemory[i] == obj) -			{ -				return i; -			} -		} -	} - -	return FAIL; -} - -template <class Type> -inline S32 LLDynamicQueuePtr<Type>::remove(S32 i) -{ -	if (mFirstObj > mLastObj) -	{ -		if (i >= mFirstObj && i < mMaxObj) -		{ -			while( i > mFirstObj) -			{ -				mMemory[i] = mMemory[i-1]; -				i--; -			} -			mMemory[mFirstObj] = NULL; -			mFirstObj++; -			if (mFirstObj >= mMaxObj) mFirstObj = 0; - -			return count(); -		} -		else if (i < mLastObj && i >= 0) -		{ -			while(i < mLastObj) -			{ -				mMemory[i] = mMemory[i+1]; -				i++; -			} -			mMemory[mLastObj] = NULL; -			mLastObj--; -			if (mLastObj < 0) mLastObj = mMaxObj-1; - -			return count(); -		} -	} -	else if (i <= mLastObj && i >= mFirstObj) -	{ -		while(i < mLastObj) -		{ -			mMemory[i] = mMemory[i+1]; -			i++; -		} -		mMemory[mLastObj] = NULL; -		mLastObj--; -		if (mLastObj < 0) mLastObj = mMaxObj-1; - -		return count(); -	} - -	 -	return FAIL; -} - -template <class Type> -inline S32 LLDynamicQueuePtr<Type>::removeObj(const Type& obj) -{ -	S32 ind = find(obj); -	if (ind >= 0) -	{ -		return remove(ind); -	} -	return FAIL; -} - -template <class Type> -inline S32	LLDynamicQueuePtr<Type>::push(const Type &obj)  -{ -	if (mMaxObj - count() <= 1) -	{ -		reallocate(mMaxObj * 2); -	} - -	mMemory[mLastObj++] = obj; - -	if (mLastObj >= mMaxObj)  -	{ -		mLastObj = 0; -	} - -	return count(); -} - -template <class Type> -inline S32	LLDynamicQueuePtr<Type>::pull(Type &obj)  -{ -	obj = NULL; - -	if (count() < 1) return -1; - -	obj = mMemory[mFirstObj]; -	mMemory[mFirstObj] = NULL; - -	mFirstObj++; - -	if (mFirstObj >= mMaxObj)  -	{ -		mFirstObj = 0; -	} - -	return count(); -} - -template <class Type> -inline const Type& LLDynamicQueuePtr<Type>::get(const S32 i) const -{ -	return mMemory[i]; -} - -template <class Type> -inline Type& LLDynamicQueuePtr<Type>::get(const S32 i) -{ -	return mMemory[i]; -} - - -#endif // LL_LLDQUEUEPTR_H diff --git a/indra/llcommon/llenum.h b/indra/llcommon/llenum.h deleted file mode 100755 index f57b2bc0b5..0000000000 --- a/indra/llcommon/llenum.h +++ /dev/null @@ -1,78 +0,0 @@ -/**  - * @file llenum.h - * @author Tom Yedwab - * @brief Utility class for storing enum value <-> string lookup. - * - * $LicenseInfo:firstyear=2006&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_LLENUM_H -#define LL_LLENUM_H - -class LLEnum -{ -public: -	typedef std::pair<const std::string, const U32> enum_t; -	enum -	{ -		UNDEFINED = 0xffffffff, -	}; - -	LLEnum(const enum_t values_array[], const U32 length) -	{ -		for (U32 i=0; i<length; ++i) -		{ -			mEnumMap.insert(values_array[i]); -			if (values_array[i].second >= mEnumArray.size()) -			{ -				mEnumArray.resize(values_array[i].second+1); -			} -			mEnumArray[values_array[i].second] = values_array[i].first; -		} -	} - -	U32 operator[](std::string str) -	{ -		std::map<const std::string, const U32>::iterator itor; -		itor = mEnumMap.find(str); -		if (itor != mEnumMap.end()) -		{ -			return itor->second; -		} -		return UNDEFINED; -	} - -	const std::string operator[](U32 index) -	{ -		if (index < mEnumArray.size()) -		{ -			return mEnumArray[index]; -		} -		return ""; -	} - -private: -	std::map<const std::string, const U32> mEnumMap; -	std::vector<std::string> mEnumArray; -}; - -#endif // LL_LLENUM_H diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h index 37cee579cd..097a533b1a 100755 --- a/indra/llcommon/llerrorlegacy.h +++ b/indra/llcommon/llerrorlegacy.h @@ -29,6 +29,7 @@  #define LL_LLERRORLEGACY_H  #include "llpreprocessor.h" +#include <boost/static_assert.hpp>  /*  	LEGACY -- DO NOT USE THIS STUFF ANYMORE @@ -111,6 +112,14 @@ const int LL_ERR_PRICE_MISMATCH = -23018;  #define llverify(func)			do {if (func) {}} while(0)  #endif +#ifdef LL_WINDOWS +#define llstatic_assert(func, msg) static_assert(func, msg) +#define llstatic_assert_template(type, func, msg) static_assert(func, msg) +#else +#define llstatic_assert(func, msg) BOOST_STATIC_ASSERT(func) +#define llstatic_assert_template(type, func, msg) BOOST_STATIC_ASSERT(sizeof(type) != 0 && func); +#endif +  // handy compile-time assert - enforce those template parameters!   #define cassert(expn) typedef char __C_ASSERT__[(expn)?1:-1]   /* Flawfinder: ignore */  	//XXX: used in two places in llcommon/llskipmap.h diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp index 0855180dcd..1c928b3db8 100755 --- a/indra/llcommon/llevents.cpp +++ b/indra/llcommon/llevents.cpp @@ -41,7 +41,6 @@  #include <algorithm>  // std headers  #include <typeinfo> -#include <cassert>  #include <cmath>  #include <cctype>  // external library headers diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 9b15804e97..dfc72bd2ce 100755 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -32,8 +32,13 @@  #include "llsingleton.h"  #include "lltreeiterators.h"  #include "llsdserialize.h" +#include "llunit.h" +#include "llsd.h" +#include "lltracerecording.h" +#include "lltracethreadrecorder.h"  #include <boost/bind.hpp> +#include <queue>  #if LL_WINDOWS @@ -49,37 +54,36 @@  #error "architecture not supported"  #endif +namespace LLTrace +{ +  //////////////////////////////////////////////////////////////////////////////  // statics -S32 LLFastTimer::sCurFrameIndex = -1; -S32 LLFastTimer::sLastFrameIndex = -1; -U64 LLFastTimer::sLastFrameTime = LLFastTimer::getCPUClockCount64(); -bool LLFastTimer::sPauseHistory = 0; -bool LLFastTimer::sResetHistory = 0; -LLFastTimer::CurTimerData LLFastTimer::sCurTimerData; -BOOL LLFastTimer::sLog = FALSE; -std::string LLFastTimer::sLogName = ""; -BOOL LLFastTimer::sMetricLog = FALSE; -LLMutex* LLFastTimer::sLogLock = NULL; -std::queue<LLSD> LLFastTimer::sLogQueue; +bool        TimeBlock::sLog		     = false; +std::string TimeBlock::sLogName         = ""; +bool        TimeBlock::sMetricLog       = false;  #if LL_LINUX || LL_SOLARIS -U64 LLFastTimer::sClockResolution = 1000000000; // Nanosecond resolution +U64         TimeBlock::sClockResolution = 1000000000; // Nanosecond resolution  #else -U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution +U64         TimeBlock::sClockResolution = 1000000; // Microsecond resolution  #endif +static LLMutex*			sLogLock = NULL; +static std::queue<LLSD> sLogQueue; + +  // FIXME: move these declarations to the relevant modules  // helper functions -typedef LLTreeDFSPostIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_bottom_up_iterator_t; +typedef LLTreeDFSPostIter<TimeBlock, TimeBlock::child_const_iter> timer_tree_bottom_up_iterator_t; -static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::NamedTimer& id)  +static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(TimeBlock& id)   {   	return timer_tree_bottom_up_iterator_t(&id,  -							boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),  -							boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1)); +							boost::bind(boost::mem_fn(&TimeBlock::beginChildren), _1),  +							boost::bind(boost::mem_fn(&TimeBlock::endChildren), _1));  }  static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()  @@ -87,14 +91,14 @@ static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up()  	return timer_tree_bottom_up_iterator_t();   } -typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_dfs_iterator_t; +typedef LLTreeDFSIter<TimeBlock, TimeBlock::child_const_iter> timer_tree_dfs_iterator_t; -static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)  +static timer_tree_dfs_iterator_t begin_timer_tree(TimeBlock& id)   {   	return timer_tree_dfs_iterator_t(&id,  -		boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),  -							boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1)); +		boost::bind(boost::mem_fn(&TimeBlock::beginChildren), _1),  +							boost::bind(boost::mem_fn(&TimeBlock::endChildren), _1));  }  static timer_tree_dfs_iterator_t end_timer_tree()  @@ -102,90 +106,48 @@ static timer_tree_dfs_iterator_t end_timer_tree()  	return timer_tree_dfs_iterator_t();   } -// factory class that creates NamedTimers via static DeclareTimer objects -class NamedTimerFactory : public LLSingleton<NamedTimerFactory> -{ -public: -	NamedTimerFactory() -	:	mTimerRoot(NULL) -	{} -	/*virtual */ void initSingleton() +// sort child timers by name +struct SortTimerByName +{ +	bool operator()(const TimeBlock* i1, const TimeBlock* i2)  	{ -		mTimerRoot = new LLFastTimer::NamedTimer("root"); -		mRootFrameState.setNamedTimer(mTimerRoot); -		mTimerRoot->setFrameState(&mRootFrameState); -		mTimerRoot->mParent = mTimerRoot; -		mTimerRoot->setCollapsed(false); -		mRootFrameState.mParent = &mRootFrameState; +		return i1->getName() < i2->getName();  	} +}; -	~NamedTimerFactory() +TimeBlock& TimeBlock::getRootTimeBlock()  	{ -		std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer()); - -		delete mTimerRoot; +	static TimeBlock root_timer("root", true, NULL); +	return root_timer;  	} -	LLFastTimer::NamedTimer& createNamedTimer(const std::string& name, LLFastTimer::FrameState* state) +void TimeBlock::pushLog(LLSD log)  	{ -		LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name); -		timer->setFrameState(state); -		timer->setParent(mTimerRoot); -		mTimers.insert(std::make_pair(name, timer)); +	LLMutexLock lock(sLogLock); -		return *timer; +	sLogQueue.push(log);  	} -	LLFastTimer::NamedTimer* getTimerByName(const std::string& name) -	{ -		timer_map_t::iterator found_it = mTimers.find(name); -		if (found_it != mTimers.end()) -		{ -			return found_it->second; -		} -		return NULL; -	} - -	LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; } - -	typedef std::multimap<std::string, LLFastTimer::NamedTimer*> timer_map_t; -	timer_map_t::iterator beginTimers() { return mTimers.begin(); } -	timer_map_t::iterator endTimers() { return mTimers.end(); } -	S32 timerCount() { return mTimers.size(); } - -private: -	timer_map_t mTimers; - -	LLFastTimer::NamedTimer*		mTimerRoot; -	LLFastTimer::FrameState			mRootFrameState; -}; - -LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open ) -:	mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState)) +void TimeBlock::setLogLock(LLMutex* lock)  { -	mTimer.setCollapsed(!open); +	sLogLock = lock;  } -LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name) -:	mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState)) -{ -}  //static  #if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) -U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer +U64 TimeBlock::countsPerSecond()  { -	return sClockResolution >> 8; +	return sClockResolution;  }  #else // windows or x86-mac or x86-linux or x86-solaris -U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer +U64 TimeBlock::countsPerSecond()  {  #if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS  	//getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz -	static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0); +	static LLUnit<LLUnits::Hertz, U64> sCPUClockFrequency = LLProcessorInfo().getCPUFrequency(); -	// we drop the low-order byte in our timers, so report a lower frequency  #else  	// If we're not using RDTSC, each fasttimer tick is just a performance counter tick.  	// Not redefining the clock frequency itself (in llprocessor.cpp/calculate_cpu_frequency()) @@ -198,269 +160,189 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer  		firstcall = false;  	}  #endif -	return sCPUClockFrequency >> 8; +	return sCPUClockFrequency.value();  }  #endif -LLFastTimer::FrameState::FrameState() -:	mActiveCount(0), -	mCalls(0), -	mSelfTimeCounter(0), -	mParent(NULL), -	mLastCaller(NULL), -	mMoveUpTree(false) -{} - - -LLFastTimer::NamedTimer::NamedTimer(const std::string& name) -:	mName(name), -	mCollapsed(true), -	mParent(NULL), -	mTotalTimeCounter(0), -	mCountAverage(0), -	mCallAverage(0), -	mNeedsSorting(false), -	mFrameState(NULL) -{ -	mCountHistory = new U32[HISTORY_NUM]; -	memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM); -	mCallHistory = new U32[HISTORY_NUM]; -	memset(mCallHistory, 0, sizeof(U32) * HISTORY_NUM); -} - -LLFastTimer::NamedTimer::~NamedTimer() -{ -	delete[] mCountHistory; -	delete[] mCallHistory; -} - -std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx) -{ -	F64 ms_multiplier = 1000.0 / (F64)LLFastTimer::countsPerSecond(); -	if (history_idx < 0) -	{ -		// by default, show average number of call -		return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getCountAverage() * ms_multiplier), (S32)getCallAverage()); -	} -	else -	{ -		return llformat("%s (%d ms, %d calls)", getName().c_str(), (S32)(getHistoricalCount(history_idx) * ms_multiplier), (S32)getHistoricalCalls(history_idx)); -	} -} - -void LLFastTimer::NamedTimer::setParent(NamedTimer* parent) -{ -	llassert_always(parent != this); -	llassert_always(parent != NULL); - -	if (mParent) -	{ -		// subtract our accumulated from previous parent -		for (S32 i = 0; i < HISTORY_NUM; i++) -		{ -			mParent->mCountHistory[i] -= mCountHistory[i]; -		} - -		// subtract average timing from previous parent -		mParent->mCountAverage -= mCountAverage; - -		std::vector<NamedTimer*>& children = mParent->getChildren(); -		std::vector<NamedTimer*>::iterator found_it = std::find(children.begin(), children.end(), this); -		if (found_it != children.end()) -		{ -			children.erase(found_it); -		} -	} - -	mParent = parent; -	if (parent) -	{ -		getFrameState().mParent = &parent->getFrameState(); -		parent->getChildren().push_back(this); -		parent->mNeedsSorting = true; -	} -} - -S32 LLFastTimer::NamedTimer::getDepth() +TimeBlock::TimeBlock(const char* name, bool open, TimeBlock* parent) +:	TraceType<TimeBlockAccumulator>(name), +	mCollapsed(true)  { -	S32 depth = 0; -	NamedTimer* timerp = mParent; -	while(timerp) -	{ -		depth++; -		if (timerp->getParent() == timerp) break; -		timerp = timerp->mParent; -	} -	return depth; +	setCollapsed(!open);  } -// static -void LLFastTimer::NamedTimer::processTimes() +TimeBlockTreeNode& TimeBlock::getTreeNode() const  { -	if (sCurFrameIndex < 0) return; - -	buildHierarchy(); -	accumulateTimings(); +	TimeBlockTreeNode* nodep = LLTrace::get_thread_recorder()->getTimeBlockTreeNode(getIndex()); +	llassert(nodep); +	return *nodep;  } -// sort child timers by name -struct SortTimerByName -{ -	bool operator()(const LLFastTimer::NamedTimer* i1, const LLFastTimer::NamedTimer* i2) -	{ -		return i1->getName() < i2->getName(); -	} -}; +static LLFastTimer::DeclareTimer FTM_PROCESS_TIMES("Process FastTimer Times"); +// not thread safe, so only call on main thread  //static -void LLFastTimer::NamedTimer::buildHierarchy() +void TimeBlock::processTimes()  { -	if (sCurFrameIndex < 0 ) return; +	LLFastTimer _(FTM_PROCESS_TIMES); +	get_clock_count(); // good place to calculate clock frequency +	U64 cur_time = getCPUClockCount64();  	// set up initial tree +	for (LLInstanceTracker<TimeBlock>::instance_iter begin_it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances(), it = begin_it;  +		it != end_it;  +		++it)  	{ -		for (instance_iter it = beginInstances(); it != endInstances(); ++it) +		TimeBlock& timer = *it; +		if (&timer == &TimeBlock::getRootTimeBlock()) continue; +			 +		// bootstrap tree construction by attaching to last timer to be on stack +		// when this timer was called +		if (timer.getParent() == &TimeBlock::getRootTimeBlock())  		{ -			NamedTimer& timer = *it; -			if (&timer == NamedTimerFactory::instance().getRootTimer()) continue; +			TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator(); -			// bootstrap tree construction by attaching to last timer to be on stack -			// when this timer was called -			if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer()) +			if (accumulator->mLastCaller)  			{ -				timer.setParent(timer.getFrameState().mLastCaller->mTimer); -				// no need to push up tree on first use, flag can be set spuriously -				timer.getFrameState().mMoveUpTree = false; +				timer.setParent(accumulator->mLastCaller); +				accumulator->mParent = accumulator->mLastCaller;  			} +				// no need to push up tree on first use, flag can be set spuriously +			accumulator->mMoveUpTree = false;  		}  	} -	// bump timers up tree if they've been flagged as being in the wrong place +	// bump timers up tree if they have been flagged as being in the wrong place  	// do this in a bottom up order to promote descendants first before promoting ancestors  	// this preserves partial order derived from current frame's observations -	for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer()); +	for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(TimeBlock::getRootTimeBlock());  		it != end_timer_tree_bottom_up();  		++it)  	{ -		NamedTimer* timerp = *it; -		// skip root timer -		if (timerp == NamedTimerFactory::instance().getRootTimer()) continue; +		TimeBlock* timerp = *it; -		if (timerp->getFrameState().mMoveUpTree) +		// sort timers by time last called, so call graph makes sense +		TimeBlockTreeNode& tree_node = timerp->getTreeNode(); +		if (tree_node.mNeedsSorting)  		{ -			// since ancestors have already been visited, reparenting won't affect tree traversal -			//step up tree, bringing our descendants with us -			LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << -				" to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL; -			timerp->setParent(timerp->getParent()->getParent()); -			timerp->getFrameState().mMoveUpTree = false; - -			// don't bubble up any ancestors until descendants are done bubbling up -			it.skipAncestors(); +			std::sort(tree_node.mChildren.begin(), tree_node.mChildren.end(), SortTimerByName());  		} -	} -	// sort timers by time last called, so call graph makes sense -	for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer()); -		it != end_timer_tree(); -		++it) -	{ -		NamedTimer* timerp = (*it); -		if (timerp->mNeedsSorting) +		// skip root timer +		if (timerp != &TimeBlock::getRootTimeBlock())  		{ -			std::sort(timerp->getChildren().begin(), timerp->getChildren().end(), SortTimerByName()); +			TimeBlockAccumulator* accumulator = timerp->getPrimaryAccumulator(); + +			if (accumulator->mMoveUpTree) +			{ +				// since ancestors have already been visited, re-parenting won't affect tree traversal +				//step up tree, bringing our descendants with us +				LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << +					" to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL; +				timerp->setParent(timerp->getParent()->getParent()); +					accumulator->mParent = timerp->getParent(); +					accumulator->mMoveUpTree = false; + +				// don't bubble up any ancestors until descendants are done bubbling up +					// as ancestors may call this timer only on certain paths, so we want to resolve +					// child-most block locations before their parents +				it.skipAncestors(); +			}  		} -		timerp->mNeedsSorting = false;  	} -} - -//static -void LLFastTimer::NamedTimer::accumulateTimings() -{ -	U32 cur_time = getCPUClockCount32();  	// walk up stack of active timers and accumulate current time while leaving timing structures active -	LLFastTimer* cur_timer = sCurTimerData.mCurTimer; -	// root defined by parent pointing to self -	CurTimerData* cur_data = &sCurTimerData; -	while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer) +	BlockTimerStackRecord* stack_record			= ThreadTimerStack::getInstance(); +	BlockTimer* cur_timer						= stack_record->mActiveTimer; +	TimeBlockAccumulator* accumulator = stack_record->mTimeBlock->getPrimaryAccumulator(); + +	while(cur_timer  +		&& cur_timer->mParentTimerData.mActiveTimer != cur_timer) // root defined by parent pointing to self  	{ -		U32 cumulative_time_delta = cur_time - cur_timer->mStartTime; -		U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime; -		cur_data->mChildTime = 0; -		cur_timer->mFrameState->mSelfTimeCounter += self_time_delta; +		U64 cumulative_time_delta = cur_time - cur_timer->mStartTime; +		accumulator->mTotalTimeCounter += cumulative_time_delta - (accumulator->mTotalTimeCounter - cur_timer->mBlockStartTotalTimeCounter); +		accumulator->mSelfTimeCounter += cumulative_time_delta - stack_record->mChildTime; +		stack_record->mChildTime = 0; +  		cur_timer->mStartTime = cur_time; +		cur_timer->mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter; -		cur_data = &cur_timer->mLastTimerData; -		cur_data->mChildTime += cumulative_time_delta; +		stack_record = &cur_timer->mParentTimerData; +		accumulator = stack_record->mTimeBlock->getPrimaryAccumulator(); +		cur_timer = stack_record->mActiveTimer; -		cur_timer = cur_timer->mLastTimerData.mCurTimer; +		stack_record->mChildTime += cumulative_time_delta;  	} -	// traverse tree in DFS post order, or bottom up -	for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer()); -		it != end_timer_tree_bottom_up(); +	// reset for next frame +	for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(), +			end_it = LLInstanceTracker<TimeBlock>::endInstances(); +		it != end_it;  		++it)  	{ -		NamedTimer* timerp = (*it); -		timerp->mTotalTimeCounter = timerp->getFrameState().mSelfTimeCounter; -		for (child_const_iter child_it = timerp->beginChildren(); child_it != timerp->endChildren(); ++child_it) +		TimeBlock& timer = *it; +		TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator(); + +		accumulator->mLastCaller = NULL; +		accumulator->mMoveUpTree = false; +	} +} + + +std::vector<TimeBlock*>::iterator TimeBlock::beginChildren()  		{ -			timerp->mTotalTimeCounter += (*child_it)->mTotalTimeCounter; +	return getTreeNode().mChildren.begin();   		} -		S32 cur_frame = sCurFrameIndex; -		if (cur_frame >= 0) +std::vector<TimeBlock*>::iterator TimeBlock::endChildren()  		{ -			// update timer history -			int hidx = cur_frame % HISTORY_NUM; +	return getTreeNode().mChildren.end(); +} -			timerp->mCountHistory[hidx] = timerp->mTotalTimeCounter; -			timerp->mCountAverage = ((U64)timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1); -			timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls; -			timerp->mCallAverage = ((U64)timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1); -		} -	} +std::vector<TimeBlock*>& TimeBlock::getChildren() +{ +	return getTreeNode().mChildren;  }  // static -void LLFastTimer::NamedTimer::resetFrame() +void TimeBlock::logStats()  { +	// get ready for next frame  	if (sLog)  	{ //output current frame counts to performance log  		static S32 call_count = 0;  		if (call_count % 100 == 0)  		{ -			LL_DEBUGS("FastTimers") << "countsPerSecond (32 bit): " << countsPerSecond() << LL_ENDL; -			LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << llendl; +			LL_DEBUGS("FastTimers") << "countsPerSecond: " << countsPerSecond() << LL_ENDL;  			LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL;  			LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL;  			LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL; -			LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << LL_ENDL; +			LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64()) / (LLUnit<LLUnits::Hertz, F64>(LLProcessorInfo().getCPUFrequency())) << LL_ENDL;  		}  		call_count++; -		F64 iclock_freq = 1000.0 / countsPerSecond(); // good place to calculate clock frequency - -		F64 total_time = 0; +		LLUnit<LLUnits::Seconds, F64> total_time(0);  		LLSD sd;  		{ -			for (instance_iter it = beginInstances(); it != endInstances(); ++it) +			for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(),  +				end_it = LLInstanceTracker<TimeBlock>::endInstances();  +				it != end_it;  +			++it)  			{ -				NamedTimer& timer = *it; -				FrameState& info = timer.getFrameState(); -				sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);	 -				sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls; +				TimeBlock& timer = *it; +				LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); +				sd[timer.getName()]["Time"] = (LLSD::Real) (frame_recording.getLastRecording().getSum(timer).value());	 +				sd[timer.getName()]["Calls"] = (LLSD::Integer) (frame_recording.getLastRecording().getSum(timer.callCount()));  				// computing total time here because getting the root timer's getCountHistory  				// doesn't work correctly on the first frame -				total_time = total_time + info.mSelfTimeCounter * iclock_freq; +				total_time += frame_recording.getLastRecording().getSum(timer);  			}  		} -		sd["Total"]["Time"] = (LLSD::Real) total_time; +		sd["Total"]["Time"] = (LLSD::Real) total_time.value();  		sd["Total"]["Calls"] = (LLSD::Integer) 1;  		{		 @@ -469,168 +351,44 @@ void LLFastTimer::NamedTimer::resetFrame()  		}  	} -	// reset for next frame -	for (instance_iter it = beginInstances(); it != endInstances(); ++it) -	{ -		NamedTimer& timer = *it; -			 -		FrameState& info = timer.getFrameState(); -		info.mSelfTimeCounter = 0; -		info.mCalls = 0; -		info.mLastCaller = NULL; -		info.mMoveUpTree = false; -		// update parent pointer in timer state struct -		if (timer.mParent) -		{ -			info.mParent = &timer.mParent->getFrameState(); -		} -	}  }  //static -void LLFastTimer::NamedTimer::reset() -{ -	resetFrame(); // reset frame data - -	// walk up stack of active timers and reset start times to current time -	// effectively zeroing out any accumulated time -	U32 cur_time = getCPUClockCount32(); - -	// root defined by parent pointing to self -	CurTimerData* cur_data = &sCurTimerData; -	LLFastTimer* cur_timer = cur_data->mCurTimer; -	while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer) -	{ -		cur_timer->mStartTime = cur_time; -		cur_data->mChildTime = 0; - -		cur_data = &cur_timer->mLastTimerData; -		cur_timer = cur_data->mCurTimer; -	} - -	// reset all history -	{ -		for (instance_iter it = beginInstances(); it != endInstances(); ++it) -		{ -			NamedTimer& timer = *it; -			if (&timer != NamedTimerFactory::instance().getRootTimer())  -			{ -				timer.setParent(NamedTimerFactory::instance().getRootTimer()); -			} -			 -			timer.mCountAverage = 0; -			timer.mCallAverage = 0; -			memset(timer.mCountHistory, 0, sizeof(U32) * HISTORY_NUM); -			memset(timer.mCallHistory, 0, sizeof(U32) * HISTORY_NUM); -		} -	} - -	sLastFrameIndex = 0; -	sCurFrameIndex = 0; -} - -U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const +void TimeBlock::dumpCurTimes()  { -	S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM; -	return mCountHistory[history_idx]; -} - -U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const -{ -	S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM; -	return mCallHistory[history_idx]; -} - -LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const -{ -	return *mFrameState; -} - -std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren() -{  -	return mChildren.begin();  -} - -std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::endChildren() -{ -	return mChildren.end(); -} - -std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren() -{ -	return mChildren; -} - -// static -LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer() -{ -        return *NamedTimerFactory::instance().getRootTimer(); -} - -//static -void LLFastTimer::nextFrame() -{ -	countsPerSecond(); // good place to calculate clock frequency -	U64 frame_time = getCPUClockCount64(); -	if ((frame_time - sLastFrameTime) >> 8 > 0xffffffff) -	{ -		llinfos << "Slow frame, fast timers inaccurate" << llendl; -	} - -	if (!sPauseHistory) -	{ -		NamedTimer::processTimes(); -		sLastFrameIndex = sCurFrameIndex++; -	} -	 -	// get ready for next frame -	NamedTimer::resetFrame(); -	sLastFrameTime = frame_time; -} - -//static -void LLFastTimer::dumpCurTimes() -{ -	// accumulate timings, etc. -	NamedTimer::processTimes(); -	 -	F64 clock_freq = (F64)countsPerSecond(); -	F64 iclock_freq = 1000.0 / clock_freq; // clock_ticks -> milliseconds +	LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); +	LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording();  	// walk over timers in depth order and output timings -	for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer()); +	for(timer_tree_dfs_iterator_t it = begin_timer_tree(TimeBlock::getRootTimeBlock());  		it != end_timer_tree();  		++it)  	{ -		NamedTimer* timerp = (*it); -		F64 total_time_ms = ((F64)timerp->getHistoricalCount(0) * iclock_freq); +		TimeBlock* timerp = (*it); +		LLUnit<LLUnits::Seconds, F64> total_time_ms = last_frame_recording.getSum(*timerp); +		U32 num_calls = last_frame_recording.getSum(timerp->callCount()); +  		// Don't bother with really brief times, keep output concise  		if (total_time_ms < 0.1) continue;  		std::ostringstream out_str; -		for (S32 i = 0; i < timerp->getDepth(); i++) +		TimeBlock* parent_timerp = timerp; +		while(parent_timerp && parent_timerp != parent_timerp->getParent())  		{  			out_str << "\t"; +			parent_timerp = parent_timerp->getParent();  		} -  		out_str << timerp->getName() << " "  -			<< std::setprecision(3) << total_time_ms << " ms, " -			<< timerp->getHistoricalCalls(0) << " calls"; +			<< std::setprecision(3) << total_time_ms.as<LLUnits::Milliseconds>().value() << " ms, " +			<< num_calls << " calls";  		llinfos << out_str.str() << llendl;  	}  }  //static  -void LLFastTimer::reset() -{ -	NamedTimer::reset(); -} - - -//static -void LLFastTimer::writeLog(std::ostream& os) +void TimeBlock::writeLog(std::ostream& os)  {  	while (!sLogQueue.empty())  	{ @@ -641,22 +399,62 @@ void LLFastTimer::writeLog(std::ostream& os)  	}  } -//static -const LLFastTimer::NamedTimer* LLFastTimer::getTimerByName(const std::string& name) +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TimeBlockAccumulator +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +TimeBlockAccumulator::TimeBlockAccumulator()  +:	mTotalTimeCounter(0), +	mSelfTimeCounter(0), +	mStartTotalTimeCounter(0), +	mCalls(0), +	mLastCaller(NULL), +	mActiveCount(0), +	mMoveUpTree(false), +	mParent(NULL) +{} + +void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other, bool append )  { -	return NamedTimerFactory::instance().getTimerByName(name); +	// we can't merge two unrelated time block samples, as that will screw with the nested timings +	// due to the call hierarchy of each thread +	llassert(append); +	mTotalTimeCounter += other.mTotalTimeCounter - other.mStartTotalTimeCounter; +	mSelfTimeCounter += other.mSelfTimeCounter; +	mCalls += other.mCalls; +	mLastCaller = other.mLastCaller; +	mActiveCount = other.mActiveCount; +	mMoveUpTree = other.mMoveUpTree; +	mParent = other.mParent;  } -LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state) -:	mFrameState(state) +void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other )  { -	U32 start_time = getCPUClockCount32(); -	mStartTime = start_time; -	mFrameState->mActiveCount++; -	LLFastTimer::sCurTimerData.mCurTimer = this; -	LLFastTimer::sCurTimerData.mFrameState = mFrameState; -	LLFastTimer::sCurTimerData.mChildTime = 0; -	mLastTimerData = LLFastTimer::sCurTimerData; +	mCalls = 0; +	mSelfTimeCounter = 0; + +	if (other) +	{ +		mStartTotalTimeCounter = other->mTotalTimeCounter; +		mTotalTimeCounter = mStartTotalTimeCounter; + +		mLastCaller = other->mLastCaller; +		mActiveCount = other->mActiveCount; +		mMoveUpTree = other->mMoveUpTree; +		mParent = other->mParent; +	} +	else +{ +		mStartTotalTimeCounter = mTotalTimeCounter; +	} +} + +LLUnit<LLUnits::Seconds, F64> BlockTimer::getElapsedTime() +{ +	U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime; + +	return (F64)total_time / (F64)TimeBlock::countsPerSecond();  } +} // namespace LLTrace diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 81c4b78775..20514d1638 100755 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -28,216 +28,98 @@  #define LL_FASTTIMER_H  #include "llinstancetracker.h" +#include "lltrace.h"  #define FAST_TIMER_ON 1 -#define DEBUG_FAST_TIMER_THREADS 1 +#define LL_FASTTIMER_USE_RDTSC 1  class LLMutex; -#include <queue> -#include "llsd.h" - -#define LL_FASTTIMER_USE_RDTSC 1 - +namespace LLTrace +{ -LL_COMMON_API void assert_main_thread(); +struct BlockTimerStackRecord +{ +	class BlockTimer*	mActiveTimer; +	class TimeBlock*	mTimeBlock; +	U64					mChildTime; +}; -class LL_COMMON_API LLFastTimer +class ThreadTimerStack  +:	public BlockTimerStackRecord,  +	public LLThreadLocalSingleton<ThreadTimerStack>  { -public: -	class NamedTimer; +	friend class LLThreadLocalSingleton<ThreadTimerStack>; +	ThreadTimerStack()  +	{} -	struct LL_COMMON_API FrameState -	{ -		FrameState(); -		void setNamedTimer(NamedTimer* timerp) { mTimer = timerp; } - -		U32 				mSelfTimeCounter; -		U32 				mCalls; -		FrameState*			mParent;		// info for caller timer -		FrameState*			mLastCaller;	// used to bootstrap tree construction -		NamedTimer*			mTimer; -		U16					mActiveCount;	// number of timers with this ID active on stack -		bool				mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame -	}; - -	// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances -	class LL_COMMON_API NamedTimer -	:	public LLInstanceTracker<NamedTimer> +public: +	ThreadTimerStack& operator=(const BlockTimerStackRecord& other)  	{ -		friend class DeclareTimer; -	public: -		~NamedTimer(); - -		enum { HISTORY_NUM = 300 }; - -		const std::string& getName() const { return mName; } -		NamedTimer* getParent() const { return mParent; } -		void setParent(NamedTimer* parent); -		S32 getDepth(); -		std::string getToolTip(S32 history_index = -1); - -		typedef std::vector<NamedTimer*>::const_iterator child_const_iter; -		child_const_iter beginChildren(); -		child_const_iter endChildren(); -		std::vector<NamedTimer*>& getChildren(); - -		void setCollapsed(bool collapsed) { mCollapsed = collapsed; } -		bool getCollapsed() const { return mCollapsed; } - -		U32 getCountAverage() const { return mCountAverage; } -		U32 getCallAverage() const { return mCallAverage; } - -		U32 getHistoricalCount(S32 history_index = 0) const; -		U32 getHistoricalCalls(S32 history_index = 0) const; - -		static NamedTimer& getRootNamedTimer(); - -		void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); } -		FrameState& getFrameState() const; - -	private: -		friend class LLFastTimer; -		friend class NamedTimerFactory; - -		// -		// methods -		// -		NamedTimer(const std::string& name); -		// recursive call to gather total time from children -		static void accumulateTimings(); - -		// updates cumulative times and hierarchy, -		// can be called multiple times in a frame, at any point -		static void processTimes(); - -		static void buildHierarchy(); -		static void resetFrame(); -		static void reset(); - -		// -		// members -		// -		FrameState*		mFrameState; +		BlockTimerStackRecord::operator=(other); +		return *this; +	} +}; -		std::string	mName; +class BlockTimer +{ +public: +	friend class TimeBlock; +	typedef BlockTimer self_t; +	typedef class TimeBlock DeclareTimer; -		U32 		mTotalTimeCounter; +	BlockTimer(TimeBlock& timer); +	~BlockTimer(); -		U32 		mCountAverage; -		U32			mCallAverage; +	LLUnit<LLUnits::Seconds, F64> getElapsedTime(); -		U32*		mCountHistory; -		U32*		mCallHistory; +private: -		// tree structure -		NamedTimer*					mParent;				// NamedTimer of caller(parent) -		std::vector<NamedTimer*>	mChildren; -		bool						mCollapsed;				// don't show children -		bool						mNeedsSorting;			// sort children whenever child added -	}; +	U64						mStartTime; +	U64						mBlockStartTotalTimeCounter; +	BlockTimerStackRecord	mParentTimerData; +}; -	// used to statically declare a new named timer -	class LL_COMMON_API DeclareTimer -	:	public LLInstanceTracker<DeclareTimer> -	{ -		friend class LLFastTimer; -	public: -		DeclareTimer(const std::string& name, bool open); -		DeclareTimer(const std::string& name); +// stores a "named" timer instance to be reused via multiple BlockTimer stack instances +class TimeBlock  +:	public TraceType<TimeBlockAccumulator>, +	public LLInstanceTracker<TimeBlock> +{ +public: +	TimeBlock(const char* name, bool open = false, TimeBlock* parent = &getRootTimeBlock()); -		NamedTimer& getNamedTimer() { return mTimer; } +	TimeBlockTreeNode& getTreeNode() const; +	TimeBlock* getParent() const { return getTreeNode().getParent(); } +	void setParent(TimeBlock* parent) { getTreeNode().setParent(parent); } -	private: -		FrameState		mFrameState; -		NamedTimer&		mTimer; -	}; +	typedef std::vector<TimeBlock*>::iterator child_iter; +	typedef std::vector<TimeBlock*>::const_iterator child_const_iter; +	child_iter beginChildren(); +	child_iter endChildren(); +	std::vector<TimeBlock*>& getChildren(); -public: -	LLFastTimer(LLFastTimer::FrameState* state); +	void setCollapsed(bool collapsed)	{ mCollapsed = collapsed; } +	bool getCollapsed() const			{ return mCollapsed; } -	LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer) -	:	mFrameState(&timer.mFrameState) +	TraceType<TimeBlockAccumulator::CallCountFacet>& callCount()   	{ -#if FAST_TIMER_ON -		LLFastTimer::FrameState* frame_state = mFrameState; -		mStartTime = getCPUClockCount32(); - -		frame_state->mActiveCount++; -		frame_state->mCalls++; -		// keep current parent as long as it is active when we are -		frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); - -		LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData; -		mLastTimerData = *cur_timer_data; -		cur_timer_data->mCurTimer = this; -		cur_timer_data->mFrameState = frame_state; -		cur_timer_data->mChildTime = 0; -#endif -#if DEBUG_FAST_TIMER_THREADS -#if !LL_RELEASE -		assert_main_thread(); -#endif -#endif +		return static_cast<TraceType<TimeBlockAccumulator::CallCountFacet>&>(*(TraceType<TimeBlockAccumulator>*)this);  	} -	LL_FORCE_INLINE ~LLFastTimer() +	TraceType<TimeBlockAccumulator::SelfTimeFacet>& selfTime()   	{ -#if FAST_TIMER_ON -		LLFastTimer::FrameState* frame_state = mFrameState; -		U32 total_time = getCPUClockCount32() - mStartTime; - -		frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; -		frame_state->mActiveCount--; - -		// store last caller to bootstrap tree creation -		// do this in the destructor in case of recursion to get topmost caller -		frame_state->mLastCaller = mLastTimerData.mFrameState; - -		// we are only tracking self time, so subtract our total time delta from parents -		mLastTimerData.mChildTime += total_time; - -		LLFastTimer::sCurTimerData = mLastTimerData; -#endif +		return static_cast<TraceType<TimeBlockAccumulator::SelfTimeFacet>&>(*(TraceType<TimeBlockAccumulator>*)this);  	} -public: -	static LLMutex*			sLogLock; -	static std::queue<LLSD> sLogQueue; -	static BOOL				sLog; -	static BOOL				sMetricLog; -	static std::string		sLogName; -	static bool 			sPauseHistory; -	static bool 			sResetHistory; - -	// call this once a frame to reset timers -	static void nextFrame(); +	static TimeBlock& getRootTimeBlock(); +	static void pushLog(LLSD sd); +	static void setLogLock(LLMutex* mutex); +	static void writeLog(std::ostream& os);  	// dumps current cumulative frame stats to log  	// call nextFrame() to reset timers  	static void dumpCurTimes(); -	// call this to reset timer hierarchy, averages, etc. -	static void reset(); - -	static U64 countsPerSecond(); -	static S32 getLastFrameIndex() { return sLastFrameIndex; } -	static S32 getCurFrameIndex() { return sCurFrameIndex; } - -	static void writeLog(std::ostream& os); -	static const NamedTimer* getTimerByName(const std::string& name); - -	struct CurTimerData -	{ -		LLFastTimer*	mCurTimer; -		FrameState*		mFrameState; -		U32				mChildTime; -	}; -	static CurTimerData		sCurTimerData; - -private: - -  	//////////////////////////////////////////////////////////////////////////////  	//  	// Important note: These implementations must be FAST! @@ -260,14 +142,14 @@ private:  	//#undef _interlockedbittestandset  	//#undef _interlockedbittestandreset -	//inline U32 LLFastTimer::getCPUClockCount32() +	//inline U32 TimeBlock::getCPUClockCount32()  	//{  	//	U64 time_stamp = __rdtsc();  	//	return (U32)(time_stamp >> 8);  	//}  	//  	//// return full timer value, *not* shifted by 8 bits -	//inline U64 LLFastTimer::getCPUClockCount64() +	//inline U64 TimeBlock::getCPUClockCount64()  	//{  	//	return __rdtsc();  	//} @@ -307,7 +189,7 @@ private:  	}  #else -	//LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp +	//U64 get_clock_count(); // in lltimer.cpp  	// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures.  	static U32 getCPUClockCount32()  	{ @@ -374,18 +256,71 @@ private:  #endif -	static U64 sClockResolution; +	static U64 countsPerSecond(); -	static S32				sCurFrameIndex; -	static S32				sLastFrameIndex; -	static U64				sLastFrameTime; +	// updates cumulative times and hierarchy, +	// can be called multiple times in a frame, at any point +	static void processTimes(); -	U32							mStartTime; -	LLFastTimer::FrameState*	mFrameState; -	LLFastTimer::CurTimerData	mLastTimerData; +	// call this once a frame to periodically log timers +	static void logStats(); +	bool						mCollapsed;				// don't show children + +	// statics +	static std::string							sLogName; +	static bool									sMetricLog, +												sLog;	 +	static U64									sClockResolution;  }; -typedef class LLFastTimer LLFastTimer; +LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer) +{ +#if FAST_TIMER_ON +	BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists(); +	TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator(); +	accumulator->mActiveCount++; +	mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter; +	// keep current parent as long as it is active when we are +	accumulator->mMoveUpTree |= (accumulator->mParent->getPrimaryAccumulator()->mActiveCount == 0); + +	// store top of stack +	mParentTimerData = *cur_timer_data; +	// push new information +	cur_timer_data->mActiveTimer = this; +	cur_timer_data->mTimeBlock = &timer; +	cur_timer_data->mChildTime = 0; + +	mStartTime = TimeBlock::getCPUClockCount64(); +#endif +} + +LL_FORCE_INLINE BlockTimer::~BlockTimer() +{ +#if FAST_TIMER_ON +	U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime; +	BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists(); +	TimeBlockAccumulator* accumulator = cur_timer_data->mTimeBlock->getPrimaryAccumulator(); + +	accumulator->mCalls++; +	accumulator->mTotalTimeCounter += total_time - (accumulator->mTotalTimeCounter - mBlockStartTotalTimeCounter); +	accumulator->mSelfTimeCounter += total_time - cur_timer_data->mChildTime; +	accumulator->mActiveCount--; + +	// store last caller to bootstrap tree creation +	// do this in the destructor in case of recursion to get topmost caller +	accumulator->mLastCaller = mParentTimerData.mTimeBlock; + +	// we are only tracking self time, so subtract our total time delta from parents +	mParentTimerData.mChildTime += total_time; + +	//pop stack +	*cur_timer_data = mParentTimerData; +#endif +} + +} + +typedef LLTrace::BlockTimer LLFastTimer;   #endif // LL_LLFASTTIMER_H diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index 864b6e6975..40a57c2ae4 100755 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -28,7 +28,7 @@   */  #if LL_WINDOWS -#include <windows.h> +#include "llwin32headerslean.h"  #include <stdlib.h>                 // Windows errno  #else  #include <errno.h> @@ -848,7 +848,7 @@ llifstream::llifstream() : _M_filebuf(),  #endif  // explicit -llifstream::llifstream(const std::string& _Filename,  +llifstream::llifstream(const std::string& _Filename,  		ios_base::openmode _Mode) : _M_filebuf(),  #if LL_WINDOWS  	std::istream(&_M_filebuf) diff --git a/indra/llcommon/llfindlocale.cpp b/indra/llcommon/llfindlocale.cpp index cd7c0c7c09..f019bd0c64 100755 --- a/indra/llcommon/llfindlocale.cpp +++ b/indra/llcommon/llfindlocale.cpp @@ -33,7 +33,7 @@  #include <ctype.h>  #ifdef WIN32 -#include <windows.h> +#include "llwin32headers.h"  #include <winnt.h>  #endif diff --git a/indra/llcommon/llindexedqueue.h b/indra/llcommon/llindexedqueue.h deleted file mode 100755 index aa2675d87d..0000000000 --- a/indra/llcommon/llindexedqueue.h +++ /dev/null @@ -1,155 +0,0 @@ -/**  - * @file llindexedqueue.h - * @brief An indexed FIFO queue, where only one element with each key - * can be in the queue. - * - * $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$ - */ - -#ifndef LL_LLINDEXEDQUEUE_H -#define LL_LLINDEXEDQUEUE_H - -// An indexed FIFO queue, where only one element with each key can be in the queue. -// This is ONLY used in the interest list, you'll probably want to review this code -// carefully if you want to use it elsewhere - Doug - -template <typename Type>  -class LLIndexedQueue -{ -protected: -	typedef std::deque<Type> type_deque; -	type_deque mQueue; -	std::set<Type> mKeySet; - -public: -	LLIndexedQueue() {} - -	// move_if_there is an O(n) operation -	bool push_back(const Type &value, bool move_if_there = false) -	{ -		if (mKeySet.find(value) != mKeySet.end()) -		{ -			// Already on the queue -			if (move_if_there) -			{ -				// Remove the existing entry. -				typename type_deque::iterator it; -				for (it = mQueue.begin(); it != mQueue.end(); ++it) -				{ -					if (*it == value) -					{ -						break; -					} -				} - -				// This HAS to succeed, otherwise there's a serious bug in the keyset implementation -				// (although this isn't thread safe, at all) - -				mQueue.erase(it); -			} -			else -			{ -				// We're not moving it, leave it alone -				return false; -			} -		} -		else -		{ -			// Doesn't exist, add it to the key set -			mKeySet.insert(value); -		} - -		mQueue.push_back(value); - -		// We succeeded in adding the new element. -		return true; -	} - -	bool push_front(const Type &value, bool move_if_there = false) -	{ -		if (mKeySet.find(value) != mKeySet.end()) -		{ -			// Already on the queue -			if (move_if_there) -			{ -				// Remove the existing entry. -				typename type_deque::iterator it; -				for (it = mQueue.begin(); it != mQueue.end(); ++it) -				{ -					if (*it == value) -					{ -						break; -					} -				} - -				// This HAS to succeed, otherwise there's a serious bug in the keyset implementation -				// (although this isn't thread safe, at all) - -				mQueue.erase(it); -			} -			else -			{ -				// We're not moving it, leave it alone -				return false; -			} -		} -		else -		{ -			// Doesn't exist, add it to the key set -			mKeySet.insert(value); -		} - -		mQueue.push_front(value); -		return true; -	} - -	void pop() -	{ -		Type value = mQueue.front(); -		mKeySet.erase(value); -		mQueue.pop_front(); -	} - -	Type &front() -	{ -		return mQueue.front(); -	} - -	S32 size() const -	{ -		return mQueue.size(); -	} - -	bool empty() const -	{ -		return mQueue.empty(); -	} - -	void clear() -	{ -		// Clear out all elements on the queue -		mQueue.clear(); -		mKeySet.clear(); -	} -}; - -#endif // LL_LLINDEXEDQUEUE_H diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp index 89c831d296..dbd4eba7a0 100755 --- a/indra/llcommon/llinitparam.cpp +++ b/indra/llcommon/llinitparam.cpp @@ -28,10 +28,17 @@  #include "linden_common.h"  #include "llinitparam.h" +#include "llformat.h"  namespace LLInitParam  { + +	predicate_rule_t default_parse_rules()  +	{  +		return ll_make_predicate(PROVIDED) && !ll_make_predicate(EMPTY); +	} +  	//  	// Param  	// @@ -196,6 +203,9 @@ namespace LLInitParam  	bool BaseBlock::validateBlock(bool emit_errors) const  	{ +		// only validate block when it hasn't already passed validation with current data +		if (!mValidated) +		{  		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();  		for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)  		{ @@ -209,11 +219,18 @@ namespace LLInitParam  				return false;  			}  		} -		return true; +			mValidated = true; +		} +		return mValidated;  	} -	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const +	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const LLInitParam::BaseBlock* diff_block) const  	{ +		bool serialized = false; +		if (!predicate_rule.check(ll_make_predicate(PROVIDED, isProvided()))) +		{ +			return false; +		}  		// named param is one like LLView::Params::follows  		// unnamed param is like LLView::Params::rect - implicit  		const BlockDescriptor& block_data = mostDerivedBlockDescriptor(); @@ -225,10 +242,10 @@ namespace LLInitParam  			param_handle_t param_handle = (*it)->mParamHandle;  			const Param* param = getParamFromHandle(param_handle);  			ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc; -			if (serialize_func) +			if (serialize_func && predicate_rule.check(ll_make_predicate(PROVIDED, param->anyProvided())))  			{  				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL; -				serialize_func(*param, parser, name_stack, diff_param); +				serialized |= serialize_func(*param, parser, name_stack, predicate_rule, diff_param);  			}  		} @@ -239,7 +256,7 @@ namespace LLInitParam  			param_handle_t param_handle = it->second->mParamHandle;  			const Param* param = getParamFromHandle(param_handle);  			ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc; -			if (serialize_func && param->anyProvided()) +			if (serialize_func && predicate_rule.check(ll_make_predicate(PROVIDED, param->anyProvided())))  			{  				// Ensure this param has not already been serialized  				// Prevents <rect> from being serialized as its own tag. @@ -264,10 +281,17 @@ namespace LLInitParam  				name_stack.push_back(std::make_pair(it->first, !duplicate));  				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL; -				serialize_func(*param, parser, name_stack, diff_param); +				serialized |= serialize_func(*param, parser, name_stack, predicate_rule, diff_param);  				name_stack.pop_back();  			}  		} + +		if (!serialized && predicate_rule.check(ll_make_predicate(EMPTY))) +		{ +			serialized |= parser.writeValue(Flag(), name_stack); +		} +		// was anything serialized in this block? +		return serialized;  	}  	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index ae836645b9..a32557b4ac 100755 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -29,14 +29,15 @@  #define LL_LLPARAM_H  #include <vector> +#include <list>  #include <boost/function.hpp>  #include <boost/type_traits/is_convertible.hpp>  #include <boost/type_traits/is_enum.hpp>  #include <boost/unordered_map.hpp> -#include <boost/shared_ptr.hpp>  #include "llerror.h"  #include "llstl.h" +#include "llpredicate.h"  namespace LLTypeTags  { @@ -195,6 +196,8 @@ namespace LLInitParam  			return mValue;  		} +		bool isValid() const { return true; } +  	protected:  		T mValue;  	}; @@ -209,13 +212,11 @@ namespace LLInitParam  		typedef T	value_t;  		ParamValue()  -		:	T(), -			mValidated(false) +		:	T()  		{}  		ParamValue(const default_value_t& other) -		:	T(other), -			mValidated(false) +		:	T(other)  		{}  		void setValue(const value_t& val) @@ -232,9 +233,6 @@ namespace LLInitParam  		{  			return *this;  		} - -	protected: -		mutable bool 	mValidated; // lazy validation flag  	}; @@ -497,25 +495,25 @@ namespace LLInitParam  		virtual ~Parser();  		template <typename T> bool readValue(T& param, typename boost::disable_if<boost::is_enum<T> >::type* dummy = 0) -			{ +		{  			parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));  			if (found_it != mParserReadFuncs->end()) -				{ +			{  				return found_it->second(*this, (void*)¶m); -				} -			 -				return false;  			} +			return false; +		} +			  		template <typename T> bool readValue(T& param, typename boost::enable_if<boost::is_enum<T> >::type* dummy = 0) -			{ +		{  			parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));  			if (found_it != mParserReadFuncs->end()) -				{ +			{  				return found_it->second(*this, (void*)¶m); -				} +			}  			else -		{ +			{  				found_it = mParserReadFuncs->find(&typeid(S32));  				if (found_it != mParserReadFuncs->end())  				{ @@ -579,6 +577,19 @@ namespace LLInitParam  	class Param; +	enum ESerializePredicates +	{ +		PROVIDED, +		REQUIRED, +		VALID, +		HAS_DEFAULT_VALUE, +		EMPTY +	}; + +	typedef LLPredicate::Rule<ESerializePredicates> predicate_rule_t; + +	predicate_rule_t default_parse_rules(); +  	// various callbacks and constraints associated with an individual param  	struct LL_COMMON_API ParamDescriptor  	{ @@ -589,7 +600,7 @@ namespace LLInitParam  		typedef bool(*merge_func_t)(Param&, const Param&, bool);  		typedef bool(*deserialize_func_t)(Param&, Parser&, Parser::name_stack_range_t&, bool); -		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param); +		typedef bool(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const predicate_rule_t rules, const Param* diff_param);  		typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);  		typedef bool(*validation_func_t)(const Param*); @@ -617,7 +628,7 @@ namespace LLInitParam  		UserData*			mUserData;  	}; -	typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr; +	typedef ParamDescriptor* ParamDescriptorPtr;  	// each derived Block class keeps a static data structure maintaining offsets to various params  	class LL_COMMON_API BlockDescriptor @@ -829,12 +840,28 @@ namespace LLInitParam  		LOG_CLASS(BaseBlock);  		friend class Param; +		BaseBlock() +		:	mValidated(false), +			mParamProvided(false) +		{} +  		virtual ~BaseBlock() {}  		bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);  		param_handle_t getHandleFromParam(const Param* param) const;  		bool validateBlock(bool emit_errors = true) const; +		bool isProvided() const +		{ +			return mParamProvided; +		} + +		bool isValid() const +		{ +			return validateBlock(false); +		} + +  		Param* getParamFromHandle(const param_handle_t param_handle)  		{  			if (param_handle == 0) return NULL; @@ -852,10 +879,19 @@ namespace LLInitParam  		void addSynonym(Param& param, const std::string& synonym);  		// Blocks can override this to do custom tracking of changes -		virtual void paramChanged(const Param& changed_param, bool user_provided) {} +		virtual void paramChanged(const Param& changed_param, bool user_provided)  +		{ +			if (user_provided) +			{ +				// a child param has been explicitly changed +				// so *some* aspect of this block is now provided +				mValidated = false; +				mParamProvided = true; +			} +		}  		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name); -		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const; +		bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule, const BaseBlock* diff_block = NULL) const;  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;  		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); } @@ -893,6 +929,9 @@ namespace LLInitParam  			return mergeBlock(block_data, source, overwrite);  		} +		mutable bool 	mValidated; // lazy validation flag +		bool			mParamProvided; +  	private:  		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;  	}; @@ -986,6 +1025,8 @@ namespace LLInitParam  		bool isProvided() const { return Param::anyProvided(); } +		bool isValid() const { return true; } +  		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{   			self_t& typed_param = static_cast<self_t&>(param); @@ -1014,10 +1055,23 @@ namespace LLInitParam  			return false;  		} -		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param) +		static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)  		{ +			bool serialized = false;  			const self_t& typed_param = static_cast<const self_t&>(param); -			if (!typed_param.isProvided()) return; +			const self_t* diff_typed_param = static_cast<const self_t*>(diff_param); + +			LLPredicate::Value<ESerializePredicates> predicate; +			if (diff_typed_param && ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue())) +			{ +				predicate.set(HAS_DEFAULT_VALUE); +			} + +			predicate.set(VALID, typed_param.isValid()); +			predicate.set(PROVIDED, typed_param.anyProvided()); +			predicate.set(EMPTY, false); + +			if (!predicate_rule.check(predicate)) return false;  			if (!name_stack.empty())  			{ @@ -1030,25 +1084,27 @@ namespace LLInitParam  			if (!key.empty())  			{ -				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key)) +				if (!diff_typed_param || !ParamCompare<std::string>::equals(diff_typed_param->getValueName(), key))  				{ -					parser.writeValue(key, name_stack); +					serialized = parser.writeValue(key, name_stack);  				}  			}  			// then try to serialize value directly -			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue())) +			else if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))  			{ -				if (!parser.writeValue(typed_param.getValue(), name_stack))  +				serialized = parser.writeValue(typed_param.getValue(), name_stack); +				if (!serialized)   				{  					std::string calculated_key = typed_param.calcValueName(typed_param.getValue());  					if (calculated_key.size()  -						&& (!diff_param  +						&& (!diff_typed_param   							|| !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)))  					{ -						parser.writeValue(calculated_key, name_stack); +						serialized = parser.writeValue(calculated_key, name_stack);  					}  				}  			} +			return serialized;  		}  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count) @@ -1113,19 +1169,19 @@ namespace LLInitParam  	};  	// parameter that is a block -	template <typename T, typename NAME_VALUE_LOOKUP> -	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>  +	template <typename BLOCK_T, typename NAME_VALUE_LOOKUP> +	class TypedParam<BLOCK_T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>   	:	public Param,  		public NAME_VALUE_LOOKUP::type_value_t  	{  	protected: -		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t; -		typedef typename param_value_t::default_value_t				default_value_t; -		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>	self_t; -		typedef typename NAME_VALUE_LOOKUP::type_value_t			named_value_t; +		typedef ParamValue<typename LLTypeTags::Sorted<BLOCK_T>::value_t>	param_value_t; +		typedef typename param_value_t::default_value_t						default_value_t; +		typedef TypedParam<BLOCK_T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>	self_t; +		typedef typename NAME_VALUE_LOOKUP::type_value_t					named_value_t;  	public:  		using named_value_t::operator(); -		typedef typename param_value_t::value_t						value_t; +		typedef typename param_value_t::value_t								value_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr), @@ -1148,11 +1204,11 @@ namespace LLInitParam  				if(named_value_t::valueNamesExist()  					&& parser.readValue(name)				  					&& named_value_t::getValueFromName(name, typed_param.getValue())) -				{ -					typed_param.setValueName(name); -					typed_param.setProvided(); -					return true; -				} +			{ +				typed_param.setValueName(name); +				typed_param.setProvided(); +				return true; +			}  			}  			if(typed_param.deserializeBlock(parser, name_stack_range, new_name)) @@ -1166,10 +1222,16 @@ namespace LLInitParam  			return false;  		} -		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param) +		static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)  		{  			const self_t& typed_param = static_cast<const self_t&>(param); -			if (!typed_param.isProvided()) return; + +			LLPredicate::Value<ESerializePredicates> predicate; + +			predicate.set(VALID, typed_param.isValid()); +			predicate.set(PROVIDED, typed_param.anyProvided()); + +			if (!predicate_rule.check(predicate)) return false;  			if (!name_stack.empty())  			{ @@ -1182,12 +1244,15 @@ namespace LLInitParam  				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))  				{  					parser.writeValue(key, name_stack); +					return true;  				}  			}  			else  			{ -				typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param)); +				return typed_param.serializeBlock(parser, name_stack, predicate_rule, static_cast<const self_t*>(diff_param));  			} +			 +			return false;  		}  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count) @@ -1209,13 +1274,12 @@ namespace LLInitParam  		// *and* the block as a whole validates  		bool isProvided() const   		{  -			// only validate block when it hasn't already passed validation with current data -			if (Param::anyProvided() && !param_value_t::mValidated) -			{ -				// a sub-block is "provided" when it has been filled in enough to be valid -				param_value_t::mValidated = param_value_t::validateBlock(false); -			} -			return Param::anyProvided() && param_value_t::mValidated; +			return Param::anyProvided() && isValid(); +		} + +		bool isValid() const +		{ +			return param_value_t::isValid();  		}  		// assign block contents to this param-that-is-a-block @@ -1223,9 +1287,6 @@ namespace LLInitParam  		{  			setValue(val);  			named_value_t::clearValueName(); -			// force revalidation of block -			// next call to isProvided() will update provision status based on validity -			param_value_t::mValidated = false;  			setProvided(flag_as_provided);  		} @@ -1242,9 +1303,6 @@ namespace LLInitParam  			if (user_provided)  			{ -				// a child param has been explicitly changed -				// so *some* aspect of this block is now provided -				param_value_t::mValidated = false;  				setProvided();  				named_value_t::clearValueName();  			} @@ -1296,13 +1354,13 @@ namespace LLInitParam  	};  	// list of non-block parameters -	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP> -	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>  +	template <typename MULTI_VALUE_T, typename NAME_VALUE_LOOKUP> +	class TypedParam<MULTI_VALUE_T, NAME_VALUE_LOOKUP, true, NOT_BLOCK>   	:	public Param  	{  	protected: -		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t; -		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t; +		typedef TypedParam<MULTI_VALUE_T, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t; +		typedef ParamValue<typename LLTypeTags::Sorted<MULTI_VALUE_T>::value_t>	param_value_t;  		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;  		typedef container_t														default_value_t;  		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t; @@ -1311,7 +1369,9 @@ namespace LLInitParam  		typedef typename param_value_t::value_t								value_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) -		:	Param(block_descriptor.mCurrentBlockPtr) +		:	Param(block_descriptor.mCurrentBlockPtr), +			mMinCount(min_count), +			mMaxCount(max_count)  		{  			std::copy(value.begin(), value.end(), std::back_inserter(mValues)); @@ -1322,7 +1382,13 @@ namespace LLInitParam  			}  		}  -		bool isProvided() const { return Param::anyProvided(); } +		bool isProvided() const { return Param::anyProvided() && isValid(); } + +		bool isValid() const  +		{  +			size_t num_elements = numValidElements(); +			return mMinCount < num_elements && num_elements < mMaxCount; +		}  		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)  		{  @@ -1337,7 +1403,7 @@ namespace LLInitParam  			}  			// no further names in stack, attempt to parse value now -			if (name_stack_range.first == name_stack_range.second) +			if (new_name_stack_range.first == new_name_stack_range.second)  			{	  				std::string name; @@ -1359,10 +1425,20 @@ namespace LLInitParam  			return false;  		} -		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param) +		static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)  		{ +			bool serialized = false;  			const self_t& typed_param = static_cast<const self_t&>(param); -			if (!typed_param.isProvided()) return; +			if (!typed_param.isProvided()) return false; + +			LLPredicate::Value<ESerializePredicates> predicate; + +			predicate.set(REQUIRED, typed_param.mMinCount > 0); +			predicate.set(VALID, typed_param.isValid()); +			predicate.set(PROVIDED, typed_param.anyProvided()); +			predicate.set(EMPTY, typed_param.mValues.empty()); + +			if (!predicate_rule.check(predicate)) return false;  			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();  				it != end_it; @@ -1378,7 +1454,11 @@ namespace LLInitParam  					if (!value_written)  					{  						std::string calculated_key = it->calcValueName(it->getValue()); -						if (!parser.writeValue(calculated_key, name_stack)) +						if (parser.writeValue(calculated_key, name_stack)) +						{ +							serialized = true; +						} +						else  						{  							break;  						} @@ -1386,19 +1466,23 @@ namespace LLInitParam  				}  				else   				{ -					if(!parser.writeValue(key, name_stack)) +					if(parser.writeValue(key, name_stack)) +					{ +						serialized = true; +					} +					else  					{  						break;  					}  				} - -				name_stack.pop_back();  			} + +			return serialized;  		}  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{ -			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL); +			parser.inspectValue<MULTI_VALUE_T>(name_stack, min_count, max_count, NULL);  			if (named_value_t::getPossibleValues())  			{  				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues()); @@ -1453,7 +1537,7 @@ namespace LLInitParam  		bool empty() const { return mValues.empty(); }  		size_t size() const { return mValues.size(); } -		U32 numValidElements() const +		size_t numValidElements() const  		{  			return mValues.size();  		} @@ -1483,6 +1567,8 @@ namespace LLInitParam  		}  		container_t		mValues; +		size_t			mMinCount, +						mMaxCount;  	private:  		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  @@ -1500,13 +1586,13 @@ namespace LLInitParam  	};  	// list of block parameters -	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP> -	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>  +	template <typename MULTI_BLOCK_T, typename NAME_VALUE_LOOKUP> +	class TypedParam<MULTI_BLOCK_T, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>   	:	public Param  	{  	protected: -		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>		self_t; -		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t; +		typedef TypedParam<MULTI_BLOCK_T, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>		self_t; +		typedef ParamValue<typename LLTypeTags::Sorted<MULTI_BLOCK_T>::value_t>	param_value_t;  		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;  		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t;  		typedef container_t														default_value_t; @@ -1516,7 +1602,9 @@ namespace LLInitParam  		typedef typename param_value_t::value_t							value_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) -		:	Param(block_descriptor.mCurrentBlockPtr) +		:	Param(block_descriptor.mCurrentBlockPtr), +			mMinCount(min_count), +			mMaxCount(max_count)  		{  			std::copy(value.begin(), value.end(), back_inserter(mValues)); @@ -1526,7 +1614,14 @@ namespace LLInitParam  			}  		}  -		bool isProvided() const { return Param::anyProvided(); } +		bool isProvided() const { return Param::anyProvided() && isValid(); } + +		bool isValid() const  +		{  +			size_t num_elements = numValidElements(); +			return mMinCount < num_elements && num_elements < mMaxCount; +		} +  		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)   		{  @@ -1549,7 +1644,7 @@ namespace LLInitParam  			}  			param_value_t& value = typed_param.mValues.back(); -			if (name_stack_range.first == name_stack_range.second) +			if (new_name_stack_range.first == new_name_stack_range.second)  			{	// try to parse a known named value  				std::string name; @@ -1559,6 +1654,10 @@ namespace LLInitParam  				{  					typed_param.mValues.back().setValueName(name);  					typed_param.setProvided(); +					if (new_array_value) +					{ +						name_stack_range.first->second = false; +					}  					return true;  				}  			} @@ -1583,10 +1682,19 @@ namespace LLInitParam  			return false;  		} -		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param) +		static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)  		{ +			bool serialized = false;  			const self_t& typed_param = static_cast<const self_t&>(param); -			if (!typed_param.isProvided()) return; +			if (!typed_param.isProvided()) return false; +			LLPredicate::Value<ESerializePredicates> predicate; + +			predicate.set(REQUIRED, typed_param.mMinCount > 0); +			predicate.set(VALID, typed_param.isValid()); +			predicate.set(PROVIDED, typed_param.anyProvided()); +			predicate.set(EMPTY, typed_param.mValues.empty()); + +			if (!predicate_rule.check(predicate)) return false;  			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();  				it != end_it; @@ -1597,17 +1705,24 @@ namespace LLInitParam  				std::string key = it->getValueName();  				if (!key.empty())  				{ -					parser.writeValue(key, name_stack); +					serialized |= parser.writeValue(key, name_stack);  				}  				// Not parsed via named values, write out value directly -				// NOTE: currently we don't worry about removing default values in Multiple +				// NOTE: currently we don't do diffing of Multiples  				else   				{ -					it->serializeBlock(parser, name_stack, NULL); +					serialized = it->serializeBlock(parser, name_stack, predicate_rule, NULL);  				}  				name_stack.pop_back();  			} + +			if (!serialized && predicate_rule.check(ll_make_predicate(EMPTY))) +			{ +				serialized |= parser.writeValue(Flag(), name_stack); +			} + +			return serialized;  		}  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count) @@ -1670,14 +1785,14 @@ namespace LLInitParam  		bool empty() const { return mValues.empty(); }  		size_t size() const { return mValues.size(); } -		U32 numValidElements() const +		size_t numValidElements() const  		{ -			U32 count = 0; +			size_t count = 0;  			for (const_iterator it = mValues.begin(), end_it = mValues.end();  				it != end_it;  				++it)  			{ -				if(it->validateBlock(false)) count++; +				if(it->isValid()) count++;  			}  			return count;  		} @@ -1709,6 +1824,8 @@ namespace LLInitParam  		}  		container_t			mValues; +		size_t				mMinCount, +							mMaxCount;  	private:  		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name )  @@ -2015,7 +2132,7 @@ namespace LLInitParam  			static bool validate(const Param* paramp)   			{ -				U32 num_valid = ((super_t*)paramp)->numValidElements(); +				size_t num_valid = ((super_t*)paramp)->numValidElements();  				return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;  			}  		}; @@ -2158,13 +2275,11 @@ namespace LLInitParam  		typedef T									default_value_t;  		ParamValue() -		:	mValue(), -			mValidated(false) +		:	mValue()  		{}  		ParamValue(const default_value_t& value) -		:	mValue(value), -			mValidated(false) +		:	mValue(value)  		{}  		void setValue(const value_t& val) @@ -2191,18 +2306,18 @@ namespace LLInitParam  			return mValue.deserializeBlock(p, name_stack_range, new_name);  		} -		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const +		bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const  		{  			const BaseBlock* base_block = diff_block  				? &(diff_block->mValue)  				: NULL; -			mValue.serializeBlock(p, name_stack, base_block); +			return mValue.serializeBlock(p, name_stack, predicate_rule, base_block);  		}  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const -			{ +		{  			return mValue.inspectBlock(p, name_stack, min_count, max_count); -			} +		}  		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)  		{ @@ -2212,9 +2327,7 @@ namespace LLInitParam  				// clear away what is there and take the new stuff as a whole  				resetToDefault();  				return mValue.mergeBlock(block_data, source.getValue(), overwrite); -		} -			 - +			}  			return mValue.mergeBlock(block_data, source.getValue(), overwrite);  		} @@ -2223,14 +2336,17 @@ namespace LLInitParam  			return mValue.validateBlock(emit_errors);  		} +		bool isValid() const +		{ +			return validateBlock(false); +		} +  		static BlockDescriptor& getBlockDescriptor()  		{  			return value_t::getBlockDescriptor();  		} -		mutable bool 	mValidated; // lazy validation flag -  	private:  		void resetToDefault()  		{ @@ -2251,15 +2367,13 @@ namespace LLInitParam  		typedef T									default_value_t;  		ParamValue() -		:	mValue(), -			mValidated(false) +		:	mValue()  		{  			mCurParam = getBlockDescriptor().mAllParams.begin();  		}  		ParamValue(const default_value_t& value) -		:	mValue(value), -			mValidated(false) +		:	mValue(value)  		{  			mCurParam = getBlockDescriptor().mAllParams.begin();  		} @@ -2284,7 +2398,7 @@ namespace LLInitParam  			if (new_name)  			{  				mCurParam = getBlockDescriptor().mAllParams.begin(); -		} +			}  			if (name_stack_range.first == name_stack_range.second   				&& mCurParam != getBlockDescriptor().mAllParams.end())  			{ @@ -2296,7 +2410,7 @@ namespace LLInitParam  				if (deserialize_func   					&& paramp   					&& deserialize_func(*paramp, p, name_stack_range, new_name)) -		{ +				{  					++mCurParam;  					return true;  				} @@ -2304,19 +2418,19 @@ namespace LLInitParam  				{  					return false;  				} -		} +			}  			else  			{  				return mValue.deserializeBlock(p, name_stack_range, new_name);  			}  		} -		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const +		bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const  		{  			const BaseBlock* base_block = diff_block  				? &(diff_block->mValue)  				: NULL; -			mValue.serializeBlock(p, name_stack, base_block); +			return mValue.serializeBlock(p, name_stack, predicate_rule, base_block);  		}  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const @@ -2334,13 +2448,16 @@ namespace LLInitParam  			return mValue.validateBlock(emit_errors);  		} +		bool isValid() const +		{ +			return validateBlock(false); +		} +  		static BlockDescriptor& getBlockDescriptor()  		{  			return value_t::getBlockDescriptor();  		} -		mutable bool 	mValidated; // lazy validation flag -  	private:  		BlockDescriptor::all_params_list_t::iterator	mCurParam; @@ -2358,16 +2475,14 @@ namespace LLInitParam  		typedef T									default_value_t;  		ParamValue() -		:	T(), -			mValidated(false) +		:	T()  		{}  		ParamValue(const default_value_t& value) -		:	T(value.getValue()), -			mValidated(false) +		:	T(value.getValue())  		{} -		mutable bool 	mValidated; // lazy validation flag +		bool isValid() const { return true; }  	};  	template<typename T, typename BLOCK_T> @@ -2380,18 +2495,15 @@ namespace LLInitParam  		typedef LazyValue<T>						default_value_t;  		ParamValue() -		:	mValue(), -			mValidated(false) +		:	mValue()  		{}  		ParamValue(const default_value_t& other) -		:	mValue(other), -			mValidated(false) +		:	mValue(other)  		{}  		ParamValue(const T& value) -		:	mValue(value), -			mValidated(false) +		:	mValue(value)  		{}  		void setValue(const value_t& val) @@ -2414,14 +2526,14 @@ namespace LLInitParam  			return mValue.get().deserializeBlock(p, name_stack_range, new_name);  		} -		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const +		bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const self_t* diff_block = NULL) const  		{ -			if (mValue.empty()) return; +			if (mValue.empty()) return false;  			const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())  											? &(diff_block->mValue.get().getValue())  											: NULL; -			mValue.get().serializeBlock(p, name_stack, base_block); +			return mValue.get().serializeBlock(p, name_stack, predicate_rule, base_block);  		}  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const @@ -2433,26 +2545,29 @@ namespace LLInitParam  		{  			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite);  		} -			 +  		bool validateBlock(bool emit_errors = true) const  		{  			return mValue.empty() || mValue.get().validateBlock(emit_errors);  		} +		bool isValid() const +		{ +			return validateBlock(false); +		} +  		static BlockDescriptor& getBlockDescriptor()  		{  			return value_t::getBlockDescriptor();  		} -		mutable bool 	mValidated; // lazy validation flag -  	private:  		LazyValue<T>	mValue;  	};  	template<typename T, typename BLOCK_T>  	class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> -		{ +	{  		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t;  	public: @@ -2460,18 +2575,15 @@ namespace LLInitParam  		typedef LazyValue<T>						default_value_t;  		ParamValue() -		:	mValue(), -			mValidated(false) +		:	mValue()  		{}  		ParamValue(const default_value_t& other) -		:	mValue(other), -			mValidated(false) +		:	mValue(other)  		{}  		ParamValue(const T& value) -		:	mValue(value), -			mValidated(false) +		:	mValue(value)  		{}  		void setValue(const value_t& val) @@ -2489,7 +2601,10 @@ namespace LLInitParam  			return mValue.get().getValue();  		} -		mutable bool 	mValidated; // lazy validation flag +		bool isValid() const +		{ +			return true; +		}  	private:  		LazyValue<T>	mValue; @@ -2504,12 +2619,10 @@ namespace LLInitParam  		typedef LLSD			default_value_t;  		ParamValue() -		:	mValidated(false)  		{}  		ParamValue(const default_value_t& other) -		:	mValue(other), -			mValidated(false) +		:	mValue(other)  		{}  		void setValue(const value_t& val) { mValue = val; } @@ -2519,16 +2632,13 @@ namespace LLInitParam  		// block param interface  		LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name); -		LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const; +		LL_COMMON_API bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const;  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const  		{  			//TODO: implement LLSD params as schema type Any  			return true;  		} -	protected: -		mutable bool 	mValidated; // lazy validation flag -  	private:  		static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack); @@ -2547,18 +2657,17 @@ namespace LLInitParam  			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative  		} EValueAge; -		typedef ParamValue<T>			derived_t; -		typedef CustomParamValue<T>				self_t; -		typedef Block<derived_t>				block_t; +		typedef TypeValues<T>			derived_t; +		typedef CustomParamValue<T>		self_t; +		typedef Block<ParamValue<T> >	block_t;  		typedef T						default_value_t; -		typedef T								value_t; +		typedef T						value_t;  		typedef void					baseblock_base_class_t;  		CustomParamValue(const default_value_t& value = T())  		:	mValue(value), -			mValueAge(VALUE_AUTHORITATIVE), -			mValidated(false) +			mValueAge(VALUE_AUTHORITATIVE)  		{}  		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name) @@ -2580,16 +2689,30 @@ namespace LLInitParam  			return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);  		} -		void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const +		bool serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const BaseBlock* diff_block = NULL) const  		{  			const derived_t& typed_param = static_cast<const derived_t&>(*this);  			const derived_t* diff_param = static_cast<const derived_t*>(diff_block); +			//std::string key = typed_param.getValueName(); + +			//// first try to write out name of name/value pair +			//if (!key.empty()) +			//{ +			//	if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key)) +			//	{ +			//		return parser.writeValue(key, name_stack); +			//	} +			//}  			// then try to serialize value directly  			if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))              { -				if (!parser.writeValue(typed_param.getValue(), name_stack))  +				if (parser.writeValue(typed_param.getValue(), name_stack))  +				{ +					return true; +				} +				else  				{  					//RN: *always* serialize provided components of BlockValue (don't pass diff_param on),  					// since these tend to be viewed as the constructor arguments for the value T.  It seems @@ -2606,14 +2729,15 @@ namespace LLInitParam  						// and serialize those params  						derived_t copy(typed_param);  						copy.updateBlockFromValue(true); -						copy.block_t::serializeBlock(parser, name_stack, NULL); +						return copy.block_t::serializeBlock(parser, name_stack, predicate_rule, NULL);  					}  					else  					{ -						block_t::serializeBlock(parser, name_stack, NULL); +						return block_t::serializeBlock(parser, name_stack, predicate_rule, NULL);  					}  				}  			} +			return false;  		}  		bool validateBlock(bool emit_errors = true) const @@ -2705,8 +2829,6 @@ namespace LLInitParam  			return block_t::mergeBlock(block_data, source, overwrite);  		} -		mutable bool 		mValidated; // lazy validation flag -  	private:  		mutable T			mValue;  		mutable EValueAge	mValueAge; diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp index 5dc3ea5d7b..7ff8324fe3 100755 --- a/indra/llcommon/llinstancetracker.cpp +++ b/indra/llcommon/llinstancetracker.cpp @@ -27,23 +27,25 @@  #include "linden_common.h"  // associated header  #include "llinstancetracker.h" +#include "llapr.h" +  // STL headers  // std headers  // external library headers  // other Linden headers -//static  -void * & LLInstanceTrackerBase::getInstances(std::type_info const & info) +void LLInstanceTrackerBase::StaticBase::incrementDepth() +{ +	apr_atomic_inc32(&sIterationNestDepth); +} + +void LLInstanceTrackerBase::StaticBase::decrementDepth()  { -	typedef std::map<std::string, void *> InstancesMap; -	static InstancesMap instances; +	apr_atomic_dec32(&sIterationNestDepth); +} -	// std::map::insert() is just what we want here. You attempt to insert a -	// (key, value) pair. If the specified key doesn't yet exist, it inserts -	// the pair and returns a std::pair of (iterator, true). If the specified -	// key DOES exist, insert() simply returns (iterator, false). One lookup -	// handles both cases. -	return instances.insert(InstancesMap::value_type(info.name(), -													 InstancesMap::mapped_type())) -		.first->second; +U32 LLInstanceTrackerBase::StaticBase::getDepth() +{ +	apr_uint32_t data = apr_atomic_read32(&sIterationNestDepth); +	return data;  } diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 1eab270e3c..c8e1d9cd84 100755 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -46,22 +46,6 @@  class LL_COMMON_API LLInstanceTrackerBase  {  protected: -	/// Get a process-unique void* pointer slot for the specified type_info -	static void * & getInstances(std::type_info const & info); - -	/// Find or create a STATICDATA instance for the specified TRACKED class. -	/// STATICDATA must be default-constructible. -	template<typename STATICDATA, class TRACKED> -	static STATICDATA& getStatic() -	{ -		void *& instances = getInstances(typeid(TRACKED)); -		if (! instances) -		{ -			instances = new STATICDATA; -		} -		return *static_cast<STATICDATA*>(instances); -	} -      /// It's not essential to derive your STATICDATA (for use with      /// getStatic()) from StaticBase; it's just that both known      /// implementations do. @@ -70,15 +54,21 @@ protected:          StaticBase():              sIterationNestDepth(0)          {} -        S32 sIterationNestDepth; + +		void incrementDepth(); +		void decrementDepth(); +		U32 getDepth(); +	private: +		U32 sIterationNestDepth;      };  };  /// This mix-in class adds support for tracking all instances of the specified class parameter T  /// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup  /// If KEY is not provided, then instances are stored in a simple set -/// @NOTE: see explicit specialization below for default KEY==T* case -template<typename T, typename KEY = T*> +/// @NOTE: see explicit specialization below for default KEY==void case +/// @NOTE: this class is not thread-safe unless used as read-only +template<typename T, typename KEY = void>  class LLInstanceTracker : public LLInstanceTrackerBase  {  	typedef LLInstanceTracker<T, KEY> MyT; @@ -87,7 +77,7 @@ class LLInstanceTracker : public LLInstanceTrackerBase  	{  		InstanceMap sMap;  	}; -	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); } +	static StaticData& getStatic() { static StaticData sData; return sData;}  	static InstanceMap& getMap_() { return getStatic().sMap; }  public: @@ -99,12 +89,12 @@ public:  		instance_iter(const typename InstanceMap::iterator& it)  		:	mIterator(it)  		{ -			++getStatic().sIterationNestDepth; +			getStatic().incrementDepth();  		}  		~instance_iter()  		{ -			--getStatic().sIterationNestDepth; +			getStatic().decrementDepth();  		} @@ -131,20 +121,20 @@ public:  		typedef boost::iterator_facade<key_iter, KEY, boost::forward_traversal_tag> super_t;  		key_iter(typename InstanceMap::iterator it) -			:	mIterator(it) +		:	mIterator(it)  		{ -			++getStatic().sIterationNestDepth; +			getStatic().incrementDepth();  		}  		key_iter(const key_iter& other) -			:	mIterator(other.mIterator) +		:	mIterator(other.mIterator)  		{ -			++getStatic().sIterationNestDepth; +			getStatic().incrementDepth();  		}  		~key_iter()  		{ -			--getStatic().sIterationNestDepth; +			getStatic().decrementDepth();  		} @@ -182,7 +172,10 @@ public:  		return instance_iter(getMap_().end());  	} -	static S32 instanceCount() { return getMap_().size(); } +	static S32 instanceCount()  +	{  +		return getMap_().size();  +	}  	static key_iter beginKeys()  	{ @@ -203,7 +196,7 @@ protected:  	virtual ~LLInstanceTracker()   	{   		// it's unsafe to delete instances of this type while all instances are being iterated over. -		llassert_always(getStatic().sIterationNestDepth == 0); +		llassert_always(getStatic().getDepth() == 0);  		remove_();		  	}  	virtual void setKey(KEY key) { remove_(); add_(key); } @@ -227,18 +220,18 @@ private:  	KEY mInstanceKey;  }; -/// explicit specialization for default case where KEY is T* +/// explicit specialization for default case where KEY is void  /// use a simple std::set<T*>  template<typename T> -class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase +class LLInstanceTracker<T, void> : public LLInstanceTrackerBase  { -	typedef LLInstanceTracker<T, T*> MyT; +	typedef LLInstanceTracker<T, void> MyT;  	typedef typename std::set<T*> InstanceSet;  	struct StaticData: public StaticBase  	{  		InstanceSet sSet;  	}; -	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); } +	static StaticData& getStatic() { static StaticData sData; return sData; }  	static InstanceSet& getSet_() { return getStatic().sSet; }  public: @@ -265,18 +258,18 @@ public:  		instance_iter(const typename InstanceSet::iterator& it)  		:	mIterator(it)  		{ -			++getStatic().sIterationNestDepth; +			getStatic().incrementDepth();  		}  		instance_iter(const instance_iter& other)  		:	mIterator(other.mIterator)  		{ -			++getStatic().sIterationNestDepth; +			getStatic().incrementDepth();  		}  		~instance_iter()  		{ -			--getStatic().sIterationNestDepth; +			getStatic().decrementDepth();  		}  	private: @@ -309,7 +302,7 @@ protected:  	virtual ~LLInstanceTracker()  	{  		// it's unsafe to delete instances of this type while all instances are being iterated over. -		llassert_always(getStatic().sIterationNestDepth == 0); +		llassert_always(getStatic().getDepth() == 0);  		getSet_().erase(static_cast<T*>(this));  	} diff --git a/indra/llcommon/lllazy.cpp b/indra/llcommon/lllazy.cpp deleted file mode 100755 index 29fa040387..0000000000 --- a/indra/llcommon/lllazy.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file   lllazy.cpp - * @author Nat Goodspeed - * @date   2009-01-28 - * @brief  Implementation for lllazy. - *  - * $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$ - */ - -// Precompiled header -#include "linden_common.h" -// associated header -#include "lllazy.h" -// STL headers -// std headers -// external library headers -// other Linden headers - -// lllazy.h is presently header-only. This file exists only because our CMake -// test macro ADD_BUILD_TEST requires it. -int dummy = 0; diff --git a/indra/llcommon/lllazy.h b/indra/llcommon/lllazy.h deleted file mode 100755 index 5f3bbce79e..0000000000 --- a/indra/llcommon/lllazy.h +++ /dev/null @@ -1,399 +0,0 @@ -/** - * @file   lllazy.h - * @author Nat Goodspeed - * @date   2009-01-22 - * @brief  Lazy instantiation of specified type. Useful in conjunction with - *         Michael Feathers's "Extract and Override Getter" ("Working - *         Effectively with Legacy Code", p. 352). - * - * Quoting his synopsis of steps on p.355: - * - * 1. Identify the object you need a getter for. - * 2. Extract all of the logic needed to create the object into a getter. - * 3. Replace all uses of the object with calls to the getter, and initialize - *    the reference that holds the object to null in all constructors. - * 4. Add the first-time logic to the getter so that the object is constructed - *    and assigned to the reference whenever the reference is null. - * 5. Subclass the class and override the getter to provide an alternative - *    object for testing. - * - * It's the second half of bullet 3 (3b, as it were) that bothers me. I find - * it all too easy to imagine adding pointer initializers to all but one - * constructor... the one not exercised by my tests. That suggested using - * (e.g.) boost::scoped_ptr<MyObject> so you don't have to worry about - * destroying it either. - * - * However, introducing additional machinery allows us to encapsulate bullet 4 - * as well. - * - * $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$ - */ - -#if ! defined(LL_LLLAZY_H) -#define LL_LLLAZY_H - -#include <boost/function.hpp> -#include <boost/scoped_ptr.hpp> -#include <boost/lambda/construct.hpp> -#include <stdexcept> - -/// LLLazyCommon simply factors out of LLLazy<T> things that don't depend on -/// its template parameter. -class LLLazyCommon -{ -public: -    /** -     * This exception is thrown if you try to replace an LLLazy<T>'s factory -     * (or T* instance) after it already has an instance in hand. Since T -     * might well be stateful, we can't know the effect of silently discarding -     * and replacing an existing instance, so we disallow it. This facility is -     * intended for testing, and in a test scenario we can definitely control -     * that. -     */ -    struct InstanceChange: public std::runtime_error -    { -        InstanceChange(const std::string& what): std::runtime_error(what) {} -    }; - -protected: -    /** -     * InstanceChange might be appropriate in a couple of different LLLazy<T> -     * methods. Factor out the common logic. -     */ -    template <typename PTR> -    static void ensureNoInstance(const PTR& ptr) -    { -        if (ptr) -        { -            // Too late: we've already instantiated the lazy object. We don't -            // know whether it's stateful or not, so it's not safe to discard -            // the existing instance in favor of a replacement. -            throw InstanceChange("Too late to replace LLLazy instance"); -        } -    } -}; - -/** - * LLLazy<T> is useful when you have an outer class Outer that you're trying - * to bring under unit test, that contains a data member difficult to - * instantiate in a test harness. Typically the data member's class Inner has - * many thorny dependencies. Feathers generally advocates "Extract and - * Override Factory Method" (p. 350). But in C++, you can't call a derived - * class override of a virtual method from the derived class constructor, - * which limits applicability of "Extract and Override Factory Method." For - * such cases Feathers presents "Extract and Override Getter" (p. 352). - * - * So we'll assume that your class Outer contains a member like this: - * @code - * Inner mInner; - * @endcode - * - * LLLazy<Inner> can be used to replace this member. You can directly declare: - * @code - * LLLazy<Inner> mInner; - * @endcode - * and change references to mInner accordingly. - * - * (Alternatively, you can add a base class of the form - * <tt>LLLazyBase<Inner></tt>. This is discussed further in the LLLazyBase<T> - * documentation.) - * - * LLLazy<T> binds a <tt>boost::scoped_ptr<T></tt> and a factory functor - * returning T*. You can either bind that functor explicitly or let it default - * to the expression <tt>new T()</tt>. - * - * As long as LLLazy<T> remains unreferenced, its T remains uninstantiated. - * The first time you use get(), <tt>operator*()</tt> or <tt>operator->()</tt> - * it will instantiate its T and thereafter behave like a pointer to it. - * - * Thus, any existing reference to <tt>mInner.member</tt> should be replaced - * with <tt>mInner->member</tt>. Any simple reference to @c mInner should be - * replaced by <tt>*mInner</tt>. - * - * (If the original declaration was a pointer initialized in Outer's - * constructor, e.g. <tt>Inner* mInner</tt>, so much the better. In that case - * you should be able to drop in <tt>LLLazy<Inner></tt> without much change.) - * - * The support for "Extract and Override Getter" lies in the fact that you can - * replace the factory functor -- or provide an explicit T*. Presumably this - * is most useful from a test subclass -- which suggests that your @c mInner - * member should be @c protected. - * - * Note that <tt>boost::lambda::new_ptr<T>()</tt> makes a dandy factory - * functor, for either the set() method or LLLazy<T>'s constructor. If your T - * requires constructor arguments, use an expression more like - * <tt>boost::lambda::bind(boost::lambda::new_ptr<T>(), arg1, arg2, ...)</tt>. - * - * Of course the point of replacing the functor is to substitute a class that, - * though referenced as Inner*, is not an Inner; presumably this is a testing - * subclass of Inner (e.g. TestInner). Thus your test subclass TestOuter for - * the containing class Outer will contain something like this: - * @code - * class TestOuter: public Outer - * { - * public: - *     TestOuter() - *     { - *         // mInner must be 'protected' rather than 'private' - *         mInner.set(boost::lambda::new_ptr<TestInner>()); - *     } - *     ... - * }; - * @endcode - */ -template <typename T> -class LLLazy: public LLLazyCommon -{ -public: -    /// Any nullary functor returning T* will work as a Factory -    typedef boost::function<T* ()> Factory; - -    /// The default LLLazy constructor uses <tt>new T()</tt> as its Factory -    LLLazy(): -        mFactory(boost::lambda::new_ptr<T>()) -    {} - -    /// Bind an explicit Factory functor -    LLLazy(const Factory& factory): -        mFactory(factory) -    {} - -    /// Reference T, instantiating it if this is the first access -    const T& get() const -    { -        if (! mInstance) -        { -            // use the bound Factory functor -            mInstance.reset(mFactory()); -        } -        return *mInstance; -    } - -    /// non-const get() -    T& get() -    { -        return const_cast<T&>(const_cast<const LLLazy<T>*>(this)->get()); -    } - -    /// operator*() is equivalent to get() -    const T& operator*() const { return get(); } -    /// operator*() is equivalent to get() -    T& operator*() { return get(); } - -    /** -     * operator->() must return (something resembling) T*. It's tempting to -     * return the underlying boost::scoped_ptr<T>, but that would require -     * breaking out the lazy-instantiation logic from get() into a common -     * private method. Assume the pointer used for operator->() access is very -     * short-lived. -     */ -    const T* operator->() const { return &get(); } -    /// non-const operator->() -    T* operator->() { return &get(); } - -    /// set(Factory). This will throw InstanceChange if mInstance has already -    /// been set. -    void set(const Factory& factory) -    { -        ensureNoInstance(mInstance); -        mFactory = factory; -    } - -    /// set(T*). This will throw InstanceChange if mInstance has already been -    /// set. -    void set(T* instance) -    { -        ensureNoInstance(mInstance); -        mInstance.reset(instance); -    } - -private: -    Factory mFactory; -    // Consider an LLLazy<T> member of a class we're accessing by const -    // reference. We want to allow even const methods to touch the LLLazy<T> -    // member. Hence the actual pointer must be mutable because such access -    // might assign it. -    mutable boost::scoped_ptr<T> mInstance; -}; - -#if (! defined(__GNUC__)) || (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) -// Not gcc at all, or a gcc more recent than gcc 3.3 -#define GCC33 0 -#else -#define GCC33 1 -#endif - -/** - * LLLazyBase<T> wraps LLLazy<T>, giving you an alternative way to replace - * <tt>Inner mInner;</tt>. Instead of coding <tt>LLLazy<Inner> mInner</tt>, - * you can add LLLazyBase<Inner> to your Outer class's bases, e.g.: - * @code - * class Outer: public LLLazyBase<Inner> - * { - *     ... - * }; - * @endcode - * - * This gives you @c public get() and @c protected set() methods without - * having to make your LLLazy<Inner> member @c protected. The tradeoff is that - * you must access the wrapped LLLazy<Inner> using get() and set() rather than - * with <tt>operator*()</tt> or <tt>operator->()</tt>. - * - * This mechanism can be used for more than one member, but only if they're of - * different types. That is, you can replace: - * @code - * DifficultClass mDifficult; - * AwkwardType    mAwkward; - * @endcode - * with: - * @code - * class Outer: public LLLazyBase<DifficultClass>, public LLLazyBase<AwkwardType> - * { - *     ... - * }; - * @endcode - * but for a situation like this: - * @code - * DifficultClass mMainDifficult, mAuxDifficult; - * @endcode - * you should directly embed LLLazy<DifficultClass> (q.v.). - * - * For multiple LLLazyBase bases, e.g. the <tt>LLLazyBase<DifficultClass>, - * LLLazyBase<AwkwardType></tt> example above, access the relevant get()/set() - * as (e.g.) <tt>LLLazyBase<DifficultClass>::get()</tt>. (This is why you - * can't have multiple LLLazyBase<T> of the same T.) For a bit of syntactic - * sugar, please see getLazy()/setLazy(). - */ -template <typename T> -class LLLazyBase -{ -public: -    /// invoke default LLLazy constructor -    LLLazyBase() {} -    /// make wrapped LLLazy bind an explicit Factory -    LLLazyBase(const typename LLLazy<T>::Factory& factory): -        mInstance(factory) -    {} - -    /// access to LLLazy::get() -    T& get() { return *mInstance; } -    /// access to LLLazy::get() -    const T& get() const { return *mInstance; } - -protected: -    // see getLazy()/setLazy() -    #if (! GCC33) -    template <typename T2, class MYCLASS> friend T2& getLazy(MYCLASS* this_); -    template <typename T2, class MYCLASS> friend const T2& getLazy(const MYCLASS* this_); -    #else // gcc 3.3 -    template <typename T2, class MYCLASS> friend T2& getLazy(const MYCLASS* this_); -    #endif // gcc 3.3 -    template <typename T2, class MYCLASS> friend void setLazy(MYCLASS* this_, T2* instance); -    template <typename T2, class MYCLASS> -    friend void setLazy(MYCLASS* this_, const typename LLLazy<T2>::Factory& factory); - -    /// access to LLLazy::set(Factory) -    void set(const typename LLLazy<T>::Factory& factory) -    { -        mInstance.set(factory); -    } - -    /// access to LLLazy::set(T*) -    void set(T* instance) -    { -        mInstance.set(instance); -    } - -private: -    LLLazy<T> mInstance; -}; - -/** - * @name getLazy()/setLazy() - * Suppose you have something like the following: - * @code - * class Outer: public LLLazyBase<DifficultClass>, public LLLazyBase<AwkwardType> - * { - *     ... - * }; - * @endcode - * - * Your methods can reference the @c DifficultClass instance using - * <tt>LLLazyBase<DifficultClass>::get()</tt>, which is admittedly a bit ugly. - * Alternatively, you can write <tt>getLazy<DifficultClass>(this)</tt>, which - * is somewhat more straightforward to read. - * - * Similarly, - * @code - * LLLazyBase<DifficultClass>::set(new TestDifficultClass()); - * @endcode - * could instead be written: - * @code - * setLazy<DifficultClass>(this, new TestDifficultClass()); - * @endcode - * - * @note - * I wanted to provide getLazy() and setLazy() without explicitly passing @c - * this. That would imply making them methods on a base class rather than free - * functions. But if <tt>LLLazyBase<T></tt> derives normally from (say) @c - * LLLazyGrandBase providing those methods, then unqualified getLazy() would - * be ambiguous: you'd have to write <tt>LLLazyBase<T>::getLazy<T>()</tt>, - * which is even uglier than <tt>LLLazyBase<T>::get()</tt>, and therefore - * pointless. You can make the compiler not care which @c LLLazyGrandBase - * instance you're talking about by making @c LLLazyGrandBase a @c virtual - * base class of @c LLLazyBase. But in that case, - * <tt>LLLazyGrandBase::getLazy<T>()</tt> can't access - * <tt>LLLazyBase<T>::get()</tt>! - * - * We want <tt>getLazy<T>()</tt> to access <tt>LLLazyBase<T>::get()</tt> as if - * in the lexical context of some subclass method. Ironically, free functions - * let us do that better than methods on a @c virtual base class -- but that - * implies passing @c this explicitly. So be it. - */ -//@{ -#if (! GCC33) -template <typename T, class MYCLASS> -T& getLazy(MYCLASS* this_) { return this_->LLLazyBase<T>::get(); } -template <typename T, class MYCLASS> -const T& getLazy(const MYCLASS* this_) { return this_->LLLazyBase<T>::get(); } -#else // gcc 3.3 -// For const-correctness, we really should have two getLazy() variants: one -// accepting const MYCLASS* and returning const T&, the other accepting -// non-const MYCLASS* and returning non-const T&. This works fine on the Mac -// (gcc 4.0.1) and Windows (MSVC 8.0), but fails on our Linux 32-bit Debian -// Sarge stations (gcc 3.3.5). Since I really don't know how to beat that aging -// compiler over the head to make it do the right thing, I'm going to have to -// move forward with the wrong thing: a single getLazy() function that accepts -// const MYCLASS* and returns non-const T&. -template <typename T, class MYCLASS> -T& getLazy(const MYCLASS* this_) { return const_cast<MYCLASS*>(this_)->LLLazyBase<T>::get(); } -#endif // gcc 3.3 -template <typename T, class MYCLASS> -void setLazy(MYCLASS* this_, T* instance) { this_->LLLazyBase<T>::set(instance); } -template <typename T, class MYCLASS> -void setLazy(MYCLASS* this_, const typename LLLazy<T>::Factory& factory) -{ -    this_->LLLazyBase<T>::set(factory); -} -//@} - -#endif /* ! defined(LL_LLLAZY_H) */ diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index 0a57ef1c48..84d2a12f65 100755 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -394,7 +394,7 @@ public:          LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN));          LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));          LLSD nop; -        F64 until(LLTimer::getElapsedSeconds() + 2); +        F64 until = (LLTimer::getElapsedSeconds() + 2).value();          while (childin.size() && LLTimer::getElapsedSeconds() < until)          {              mainloop.post(nop); diff --git a/indra/llcommon/lllocalidhashmap.h b/indra/llcommon/lllocalidhashmap.h deleted file mode 100755 index 8f4f91a560..0000000000 --- a/indra/llcommon/lllocalidhashmap.h +++ /dev/null @@ -1,895 +0,0 @@ -/**  - * @file lllocalidhashmap.h - * @brief Map specialized for dealing with local ids - * - * $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$ - */ - -#ifndef LL_LLLOCALIDHASHMAP_H -#define LL_LLLOCALIDHASHMAP_H - -#include "stdtypes.h" -#include "llerror.h" - -const S32 MAX_ITERS = 4; -// LocalID hash map - -// -// LLLocalIDHashNode -// - -template <class DATA, int SIZE> -class LLLocalIDHashNode -{ -public: -	LLLocalIDHashNode(); - -public: -	S32 mCount; -	U32	mKey[SIZE]; -	DATA mData[SIZE]; -	LLLocalIDHashNode<DATA, SIZE> *mNextNodep; -}; - - -// -// LLLocalIDHashNode implementation -// -template <class DATA, int SIZE> -LLLocalIDHashNode<DATA, SIZE>::LLLocalIDHashNode() -{ -	mCount = 0; -	mNextNodep = NULL; -} - -// -// LLLocalIDHashMapIter -// -template <class DATA_TYPE, int SIZE> -class LLLocalIDHashMap; - -template <class DATA_TYPE, int SIZE> -class LLLocalIDHashMapIter -{ -public: -	LLLocalIDHashMapIter(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp); -	~LLLocalIDHashMapIter(); - -	void setMap(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp); -	inline void first(); -	inline void next(); -	inline DATA_TYPE& current(); // *NOTE: Deprecate? Phoenix 2005-04-15 -	inline BOOL done() const; -	inline S32  currentBin() const; -	inline void setBin(S32 bin); - -	DATA_TYPE& operator*() const -	{ -		return mCurHashNodep->mData[mCurHashNodeKey]; -	} -	DATA_TYPE* operator->() const -	{ -		return &(operator*()); -	} - -	LLLocalIDHashMap<DATA_TYPE, SIZE> *mHashMapp; -	LLLocalIDHashNode<DATA_TYPE, SIZE> *mCurHashNodep; - -	S32 mCurHashMapNodeNum; -	S32 mCurHashNodeKey; - -	DATA_TYPE mNull; - -	S32 mIterID; -}; - - - -template <class DATA_TYPE, int SIZE> -class LLLocalIDHashMap -{ -public: -	friend class LLLocalIDHashMapIter<DATA_TYPE, SIZE>; - -	LLLocalIDHashMap(); // DO NOT use this unless you explicitly setNull, or the data type constructs a "null" -						// object by default -	// basic constructor including sorter -	LLLocalIDHashMap(const DATA_TYPE &null_data); -	// Hack, this should really be a const ref, but I'm not doing it that way because the sim -	// usually uses pointers. -	~LLLocalIDHashMap(); - -	inline DATA_TYPE &get(const U32 local_id); -	inline BOOL check(const U32 local_id) const; -	inline DATA_TYPE &set(const U32 local_id, const DATA_TYPE data); -	inline BOOL remove(const U32 local_id); -	void removeAll(); - -	void setNull(const DATA_TYPE data) { mNull = data; } - -	inline S32 getLength() const; // Warning, NOT O(1!) - -	void dumpIter(); -	void dumpBin(U32 bin); - -protected: -	// Only used by the iterator. -	void addIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter); -	void removeIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter); - -	// Remove the item and shift all items afterward down the list, -	// fixing up iterators as we go. -	BOOL removeWithShift(const U32 local_id); - -protected: -	LLLocalIDHashNode<DATA_TYPE, SIZE> mNodes[256]; - -	S32 mIterCount; -	LLLocalIDHashMapIter<DATA_TYPE, SIZE> *mIters[MAX_ITERS]; - -	DATA_TYPE mNull; -}; - - -// -// LLLocalIDHashMap implementation -// - -template <class DATA_TYPE, int SIZE> -LLLocalIDHashMap<DATA_TYPE, SIZE>::LLLocalIDHashMap() -:	mIterCount(0), -	mNull() -{ -	S32 i; -	for (i = 0; i < MAX_ITERS; i++) -	{ -		mIters[i] = NULL; -	} -} - -template <class DATA_TYPE, int SIZE> -LLLocalIDHashMap<DATA_TYPE, SIZE>::LLLocalIDHashMap(const DATA_TYPE &null_data) -:	mIterCount(0), -	mNull(null_data) -{ -	S32 i; -	for (i = 0; i < MAX_ITERS; i++) -	{ -		mIters[i] = NULL; -	} -} - -template <class DATA_TYPE, int SIZE> -LLLocalIDHashMap<DATA_TYPE, SIZE>::~LLLocalIDHashMap() -{ -	S32 i; -	for (i = 0; i < MAX_ITERS; i++) -	{ -		if (mIters[i]) -		{ -			mIters[i]->mHashMapp = NULL; -			mIterCount--; -		} -	} -	removeAll(); -} - -template <class DATA_TYPE, int SIZE> -void LLLocalIDHashMap<DATA_TYPE, SIZE>::removeAll() -{ -	S32 bin; -	for (bin = 0; bin < 256; bin++) -	{ -		LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin]; - -		BOOL first = TRUE; -		do // First node guaranteed to be there -		{ -			S32 i; -			const S32 count = nodep->mCount; - -			// Iterate through all members of this node -			for (i = 0; i < count; i++) -			{ -				nodep->mData[i] = mNull; -			} - -			nodep->mCount = 0; -			// Done with all objects in this node, go to the next. - -			LLLocalIDHashNode<DATA_TYPE, SIZE>* curp = nodep; -			nodep = nodep->mNextNodep; - -			// Delete the node if it's not the first node -			if (first) -			{ -				first = FALSE; -				curp->mNextNodep = NULL; -			} -			else -			{ -				delete curp; -			} -		} while (nodep); -	} -} - -template <class DATA_TYPE, int SIZE> -void LLLocalIDHashMap<DATA_TYPE, SIZE>::dumpIter() -{ -	std::cout << "Hash map with " << mIterCount << " iterators" << std::endl; - -	std::cout << "Hash Map Iterators:" << std::endl; -	S32 i; -	for (i = 0; i < MAX_ITERS; i++) -	{ -		if (mIters[i]) -		{ -			llinfos << i << " " << mIters[i]->mCurHashNodep << " " << mIters[i]->mCurHashNodeKey << llendl; -		} -		else -		{ -			llinfos << i << "null" << llendl; -		} -	} -} - -template <class DATA_TYPE, int SIZE> -void LLLocalIDHashMap<DATA_TYPE, SIZE>::dumpBin(U32 bin) -{ -	std::cout << "Dump bin " << bin << std::endl; - -	LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin]; -	S32 node = 0; -	do // First node guaranteed to be there. -	{ -		std::cout << "Bin " << bin  -			<< " node " << node -			<< " count " << nodep->mCount -			<< " contains " << std::flush; - -		S32 i; -		for (i = 0; i < nodep->mCount; i++) -		{ -			std::cout << nodep->mData[i] << " " << std::flush; -		} - -		std::cout << std::endl; - -		nodep = nodep->mNextNodep; -		node++; -	} while (nodep); -} - -template <class DATA_TYPE, int SIZE> -inline S32 LLLocalIDHashMap<DATA_TYPE, SIZE>::getLength() const -{ -	S32 count = 0; -	S32 bin; -	for (bin = 0; bin < 256; bin++) -	{ -		const LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin]; -		while (nodep) -		{ -			count += nodep->mCount; -			nodep = nodep->mNextNodep; -		} -	} -	return count; -} - -template <class DATA_TYPE, int SIZE> -inline DATA_TYPE &LLLocalIDHashMap<DATA_TYPE, SIZE>::get(const U32 local_id) -{ -	LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff]; - -	do // First node guaranteed to be there -	{ -		S32 i; -		const S32 count = nodep->mCount; - -		// Iterate through all members of this node -		for (i = 0; i < count; i++) -		{ -			if (nodep->mKey[i] == local_id) -			{ -				// We found it. -				return nodep->mData[i]; -			} -		} - -		// Done with all objects in this node, go to the next. -		nodep = nodep->mNextNodep; -	} while (nodep); - -	return mNull; -} - - -template <class DATA_TYPE, int SIZE> -inline BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::check(const U32 local_id) const -{ -	const LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff]; - -	do // First node guaranteed to be there -	{ -		S32 i; -		const S32 count = nodep->mCount; - -		// Iterate through all members of this node -		for (i = 0; i < count; i++) -		{ -			if (nodep->mKey[i] == local_id) -			{ -				// We found it. -				return TRUE; -			} -		} - -		// Done with all objects in this node, go to the next. -		nodep = nodep->mNextNodep; -	} while (nodep); - -	// Didn't find anything -	return FALSE; -} - - -template <class DATA_TYPE, int SIZE> -inline DATA_TYPE &LLLocalIDHashMap<DATA_TYPE, SIZE>::set(const U32 local_id, const DATA_TYPE data) -{ -	// Set is just like a normal find, except that if we find a match -	// we replace it with the input value. -	// If we don't find a match, we append to the end of the list. - -	LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[local_id & 0xff]; - -	while (1) -	{ -		const S32 count = nodep->mCount; - -		S32 i; -		for (i = 0; i < count; i++) -		{ -			if (nodep->mKey[i] == local_id) -			{ -				// We found a match for this key, replace the data with -				// the incoming data. -				nodep->mData[i] = data; -				return nodep->mData[i]; -			} -		} -		if (!nodep->mNextNodep) -		{ -			// We've iterated through all of the keys without finding a match -			if (i < SIZE) -			{ -				// There's still some space on this node, append -				// the key and data to it. -				nodep->mKey[i] = local_id; -				nodep->mData[i] = data; -				nodep->mCount++; - -				return nodep->mData[i]; -			} -			else -			{ -				// This node is full, append a new node to the end. -				nodep->mNextNodep = new LLLocalIDHashNode<DATA_TYPE, SIZE>; -				nodep->mNextNodep->mKey[0] = local_id; -				nodep->mNextNodep->mData[0] = data; -				nodep->mNextNodep->mCount = 1; - -				return nodep->mNextNodep->mData[0]; -			} -		} - -		// No match on this node, go to the next -		nodep = nodep->mNextNodep; -	} -} - - -template <class DATA_TYPE, int SIZE> -inline BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::remove(const U32 local_id) -{ -	// Remove is the trickiest operation. -	// What we want to do is swap the last element of the last -	// node if we find the one that we want to remove, but we have -	// to deal with deleting the node from the tail if it's empty, but -	// NOT if it's the only node left. - -	const S32 node_index = local_id & 0xff; - -	LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[node_index]; - -	// A modification of the standard search algorithm. -	do // First node guaranteed to be there -	{ -		const S32 count = nodep->mCount; - -		S32 i; -		for (i = 0; i < count; i++) -		{ -			if (nodep->mKey[i] == local_id) -			{ -				// If we're removing the item currently pointed to by one -				// or more iterators, we can just swap in the last item -				// and back the iterator(s) up by one. -				// Otherwise, we need to do a slow and safe shift of all -				// items back to one position to fill the hole and fix up  -				// all iterators we find. -				BOOL need_shift = FALSE; -				S32 cur_iter; -				if (mIterCount) -				{ -					for (cur_iter = 0; cur_iter < MAX_ITERS; cur_iter++) -					{ -						if (mIters[cur_iter]) -						{ -							// We only care if the hash map node is on the one -							// that we're working on.  If it's before, we've already -							// traversed it, if it's after, changing the order doesn't -							// matter. -							if (mIters[cur_iter]->mCurHashMapNodeNum == node_index) -							{ -								if ((mIters[cur_iter]->mCurHashNodep == nodep) -									&& (mIters[cur_iter]->mCurHashNodeKey == i)) -								{ -									// it's on the one we're deleting, we'll -									// fix the iterator quickly below. -								} -								else -								{ -									// We're trying to remove an item on this -									// iterator's chain that this -									// iterator doesn't point to!  We need to do -									// the slow remove-and-shift-down case. -									need_shift = TRUE; -								} -							} -						} -					} -				} - -				// Removing an item that isn't pointed to by all iterators -				if (need_shift) -				{ -					return removeWithShift(local_id); -				} - -				// Fix the iterators that point to this node/i pair, the -				// one we're deleting -				for (cur_iter = 0; cur_iter < MAX_ITERS; cur_iter++) -				{ -					if (mIters[cur_iter]) -					{ -						// We only care if the hash map node is on the one -						// that we're working on.  If it's before, we've already -						// traversed it, if it's after, changing the order doesn't -						// matter. -						if (mIters[cur_iter]->mCurHashMapNodeNum == node_index) -						{ -							if ((mIters[cur_iter]->mCurHashNodep == nodep) -								&& (mIters[cur_iter]->mCurHashNodeKey == i)) -							{ -								// We can handle the case where we're deleting  -								// the element we're on trivially (sort of). -								if (nodep->mCount > 1) -								{ -									// If we're not going to delete this node, -									// it's OK. -									mIters[cur_iter]->mCurHashNodeKey--; -								} -								else -								{ -									// We're going to delete this node, because this -									// is the last element on it. -									 -									// Find the next node, and then back up one. -									mIters[cur_iter]->next(); -									mIters[cur_iter]->mCurHashNodeKey--; -								} -							} -						} -					} -				} - -				// We found the node that we want to remove. -				// Find the last (and next-to-last) node, and the index of the last -				// element.  We could conceviably start from the node we're on, -				// but that makes it more complicated, this is easier. - -				LLLocalIDHashNode<DATA_TYPE, SIZE> *prevp = &mNodes[node_index]; -				LLLocalIDHashNode<DATA_TYPE, SIZE> *lastp = prevp; - -				// Find the last and next-to-last -				while (lastp->mNextNodep) -				{ -					prevp = lastp; -					lastp = lastp->mNextNodep; -				} - -				// First, swap in the last to the current location. -				nodep->mKey[i] = lastp->mKey[lastp->mCount - 1]; -				nodep->mData[i] = lastp->mData[lastp->mCount - 1]; - -				// Now, we delete the entry -				lastp->mCount--; -				lastp->mData[lastp->mCount] = mNull; - -				if (!lastp->mCount) -				{ -					// We deleted the last element! -					if (lastp != &mNodes[local_id & 0xff]) -					{ -						// Only blitz the node if it's not the head -						// Set the previous node to point to NULL, then -						// blitz the empty last node -						prevp->mNextNodep = NULL; -						delete lastp; -					} -				} - -				return TRUE; -			} -		} - -		// Iterate to the next node, we've scanned all the entries in this one. -		nodep = nodep->mNextNodep; -	} while (nodep); - -	return FALSE; -} - -template <class DATA_TYPE, int SIZE> -BOOL LLLocalIDHashMap<DATA_TYPE, SIZE>::removeWithShift(const U32 local_id) -{ -	const S32 node_index = local_id & 0xFF; -	LLLocalIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[node_index]; -	LLLocalIDHashNode<DATA_TYPE, SIZE>* prevp = NULL; -	BOOL found = FALSE; - -	do // First node guaranteed to be there -	{ -		const S32 count = nodep->mCount; -		S32 i; -		for (i = 0; i < count; i++) -		{ -			if (nodep->mKey[i] == local_id) -			{ -				// Found the item.  Start shifting items from later -				// in the list over this item. -				found = TRUE; -			} - -			if (found) -			{ -				// If there is an iterator on this node, we need to  -				// back it up. -				S32 cur_iter; -				for (cur_iter = 0; cur_iter <MAX_ITERS; cur_iter++) -				{ -					LLLocalIDHashMapIter<DATA_TYPE, SIZE>* iter; -					iter = mIters[cur_iter]; -					// If an iterator is on this node,i pair, then back it up. -					if (iter -						&& iter->mCurHashMapNodeNum == node_index -						&& iter->mCurHashNodep == nodep -						&& iter->mCurHashNodeKey == i) -					{ -						if (i > 0) -						{ -							// Don't need to move iterator nodep, since  -							// we're in the same node. -							iter->mCurHashNodeKey--; -						} -						else if (prevp) -						{ -							// need to go the previous node, last item -							iter->mCurHashNodep = prevp; -							iter->mCurHashNodeKey = prevp->mCount - 1; -						} -						else -						{ -							// we're on the first item in the list, but -							// need to go back anyhow. - -							// BUG: If this deletion empties the list,  -							// iter->done() will be wrong until -							// iter->next() is called. -							iter->mCurHashNodeKey = -1; -						} -					} -				} - -				// Copy data from the next position into this position. -				if (i < count-1) -				{ -					// we're not on the last item in the node, -					// so we can copy within the node -					nodep->mKey[i] = nodep->mKey[i+1]; -					nodep->mData[i] = nodep->mData[i+1]; -				} -				else if (nodep->mNextNodep) -				{ -					// we're on the last item in the node, -					// but there's a next node we can copy from -					nodep->mKey[i] = nodep->mNextNodep->mKey[0]; -					nodep->mData[i] = nodep->mNextNodep->mData[0]; -				} -				else -				{ -					// We're on the last position in the list. -					// No one to copy from.  Replace with nothing. -					nodep->mKey[i] = 0; -					nodep->mData[i] = mNull; -				} -			} -		} - -		// Last node in chain, so delete the last node -		if (found -			&& !nodep->mNextNodep) -		{ -			// delete the last item off the last node -			nodep->mCount--; - -			if (nodep->mCount == 0) -			{ -				// We deleted the last element! -				if (nodep != &mNodes[node_index]) -				{ -					// Always have a prevp if we're not the head. -					llassert(prevp); - -					// Only blitz the node if it's not the head -					// Set the previous node to point to NULL, then -					// blitz the empty last node -					prevp->mNextNodep = NULL; -					delete nodep; -					nodep = NULL; -				} -			} - -			// Deleted last item in chain, so we're done. -			return found; -		} - -		prevp = nodep; -		nodep = nodep->mNextNodep; -	} while (nodep); - -	return found; -} - -template <class DATA_TYPE, int SIZE> -void LLLocalIDHashMap<DATA_TYPE, SIZE>::removeIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter) -{ -	S32 i; -	for (i = 0; i < MAX_ITERS; i++) -	{ -		if (mIters[i] == iter) -		{ -			mIters[i] = NULL; -			mIterCount--; -			return; -		} -	} -	llerrs << "Iterator " << iter << " not found for removal in hash map!" << llendl; -} - -template <class DATA_TYPE, int SIZE> -void LLLocalIDHashMap<DATA_TYPE, SIZE>::addIter(LLLocalIDHashMapIter<DATA_TYPE, SIZE> *iter) -{ -	S32 i; -	for (i = 0; i < MAX_ITERS; i++) -	{ -		if (mIters[i] == NULL) -		{ -			mIters[i] = iter; -			mIterCount++; -			return; -		} -	} -	llerrs << "More than " << MAX_ITERS << " iterating over a map simultaneously!" << llendl; -} - - - -// -// LLLocalIDHashMapIter Implementation -// -template <class DATA_TYPE, int SIZE> -LLLocalIDHashMapIter<DATA_TYPE, SIZE>::LLLocalIDHashMapIter(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp) -{ -	mHashMapp = NULL; -	setMap(hash_mapp); -} - -template <class DATA_TYPE, int SIZE> -LLLocalIDHashMapIter<DATA_TYPE, SIZE>::~LLLocalIDHashMapIter() -{ -	if (mHashMapp) -	{ -		mHashMapp->removeIter(this); -	} -} - -template <class DATA_TYPE, int SIZE> -void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::setMap(LLLocalIDHashMap<DATA_TYPE, SIZE> *hash_mapp) -{ -	if (mHashMapp) -	{ -		mHashMapp->removeIter(this); -	} -	mHashMapp = hash_mapp; -	if (mHashMapp) -	{ -		mHashMapp->addIter(this); -	} - -	mCurHashNodep = NULL; -	mCurHashMapNodeNum = -1; -	mCurHashNodeKey = 0; -} - -template <class DATA_TYPE, int SIZE> -inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::first() -{ -	// Iterate through until we find the first non-empty node; -	S32 i; -	for (i = 0; i < 256; i++) -	{ -		if (mHashMapp->mNodes[i].mCount) -		{ - -			mCurHashNodep = &mHashMapp->mNodes[i]; -			mCurHashMapNodeNum = i; -			mCurHashNodeKey = 0; -			//return mCurHashNodep->mData[0]; -			return; -		} -	} - -	// Completely empty! -	mCurHashNodep = NULL; -	//return mNull; -	return; -} - -template <class DATA_TYPE, int SIZE> -inline BOOL LLLocalIDHashMapIter<DATA_TYPE, SIZE>::done() const -{ -	return mCurHashNodep ? FALSE : TRUE; -} - -template <class DATA_TYPE, int SIZE> -inline S32 LLLocalIDHashMapIter<DATA_TYPE, SIZE>::currentBin() const -{ -	if (  (mCurHashMapNodeNum > 255) -		||(mCurHashMapNodeNum < 0)) -	{ -		return 0; -	} -	else -	{ -		return mCurHashMapNodeNum; -	} -} - -template <class DATA_TYPE, int SIZE> -inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::setBin(S32 bin) -{ -	// Iterate through until we find the first non-empty node; -	S32 i; -	bin = llclamp(bin, 0, 255); -	for (i = bin; i < 256; i++) -	{ -		if (mHashMapp->mNodes[i].mCount) -		{ - -			mCurHashNodep = &mHashMapp->mNodes[i]; -			mCurHashMapNodeNum = i; -			mCurHashNodeKey = 0; -			return; -		} -	} -	for (i = 0; i < bin; i++) -	{ -		if (mHashMapp->mNodes[i].mCount) -		{ - -			mCurHashNodep = &mHashMapp->mNodes[i]; -			mCurHashMapNodeNum = i; -			mCurHashNodeKey = 0; -			return; -		} -	} -	// Completely empty! -	mCurHashNodep = NULL; -} - -template <class DATA_TYPE, int SIZE> -inline DATA_TYPE &LLLocalIDHashMapIter<DATA_TYPE, SIZE>::current() -{ -	if (!mCurHashNodep) -	{ -		return mNull; -	} -	return mCurHashNodep->mData[mCurHashNodeKey]; -} - -template <class DATA_TYPE, int SIZE> -inline void LLLocalIDHashMapIter<DATA_TYPE, SIZE>::next() -{ -	// No current entry, this iterator is done -	if (!mCurHashNodep) -	{ -		//return mNull; -		return; -	} - -	// Go to the next element -	mCurHashNodeKey++; -	if (mCurHashNodeKey < mCurHashNodep->mCount) -	{ -		// We're not done with this node, return the current element -		//return mCurHashNodep->mData[mCurHashNodeKey]; -		return; -	} - -	// Done with this node, move to the next -	mCurHashNodep = mCurHashNodep->mNextNodep; -	if (mCurHashNodep) -	{ -		// Return the first element -		mCurHashNodeKey = 0; -		//return mCurHashNodep->mData[0]; -		return; -	} - -	// Find the next non-empty node (keyed on the first byte) -	mCurHashMapNodeNum++; - -	S32 i; -	for (i = mCurHashMapNodeNum; i < 256; i++) -	{ -		if (mHashMapp->mNodes[i].mCount) -		{ -			// We found one that wasn't empty -			mCurHashNodep = &mHashMapp->mNodes[i]; -			mCurHashMapNodeNum = i; -			mCurHashNodeKey = 0; -			//return mCurHashNodep->mData[0]; -			return; -		} -	} - -	// OK, we're done, nothing else to iterate -	mCurHashNodep = NULL; -	mHashMapp->mIterCount--; // Decrement since we're safe to do removes now -	//return mNull; -	return; -} - -#endif // LL_LLLOCALIDHASHMAP_H diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index 1409c55d1c..ed80af36d8 100755 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -76,7 +76,6 @@ documentation and/or software.  #include "llmd5.h" -#include <cassert>  #include <iostream>		// cerr  // how many bytes to grab at a time when checking files diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 70ad10ad55..c6b02df939 100755 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -32,7 +32,6 @@  //#endif  #if defined(LL_WINDOWS) -//# include <windows.h>  # include <psapi.h>  #elif defined(LL_DARWIN)  # include <sys/types.h> diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index e725bdd9fa..95500753e4 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -27,6 +27,9 @@  #define LLMEMORY_H  #include "linden_common.h" +#if !LL_WINDOWS +#include <stdint.h> +#endif  class LLMutex ; @@ -36,6 +39,20 @@ class LLMutex ;  #define LL_CHECK_MEMORY  #endif +#if LL_WINDOWS +#define LL_ALIGN_OF __alignof +#else +#define LL_ALIGN_OF __align_of__ +#endif + +#if LL_WINDOWS +#define LL_DEFAULT_HEAP_ALIGN 8 +#elif LL_DARWIN +#define LL_DEFAULT_HEAP_ALIGN 16 +#elif LL_LINUX +#define LL_DEFAULT_HEAP_ALIGN 8 +#endif +  inline void* ll_aligned_malloc( size_t size, int align )  {  	void* mem = malloc( size + (align - 1) + sizeof(void*) ); diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 731e58bd20..fd89cb818a 100755 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -29,9 +29,9 @@  #include "indra_constants.h"  #include "llerror.h"  #include "llsdserialize.h" -#include "llstat.h"  #include "lltreeiterators.h"  #include "llmetricperformancetester.h" +#include "llfasttimer.h"  //----------------------------------------------------------------------------------------------  // LLMetricPerformanceTesterBasic : static methods and testers management @@ -91,7 +91,7 @@ LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::s  // Return TRUE if this metric is requested or if the general default "catch all" metric is requested  BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name)  { -	return (LLFastTimer::sMetricLog && ((LLFastTimer::sLogName == name) || (LLFastTimer::sLogName == DEFAULT_METRIC_NAME))); +	return (LLTrace::TimeBlock::sMetricLog && ((LLTrace::TimeBlock::sLogName == name) || (LLTrace::TimeBlock::sLogName == DEFAULT_METRIC_NAME)));  }  /*static*/  @@ -194,8 +194,7 @@ void LLMetricPerformanceTesterBasic::preOutputTestResults(LLSD* sd)  void LLMetricPerformanceTesterBasic::postOutputTestResults(LLSD* sd)  { -	LLMutexLock lock(LLFastTimer::sLogLock); -	LLFastTimer::sLogQueue.push((*sd)); +	LLTrace::TimeBlock::pushLog(*sd);  }  void LLMetricPerformanceTesterBasic::outputTestResults()  diff --git a/indra/llcommon/llmortician.h b/indra/llcommon/llmortician.h index 319955ef93..9517e2db5e 100755 --- a/indra/llcommon/llmortician.h +++ b/indra/llcommon/llmortician.h @@ -28,6 +28,7 @@  #define LLMORTICIAN_H  #include "stdtypes.h" +#include <list>  class LL_COMMON_API LLMortician   { diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp new file mode 100644 index 0000000000..ad0287c6d5 --- /dev/null +++ b/indra/llcommon/llmutex.cpp @@ -0,0 +1,179 @@ +/**  + * @file llmutex.cpp + * + * $LicenseInfo:firstyear=2004&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 "linden_common.h" +#include "llapr.h" + +#include "apr_portable.h" + +#include "llmutex.h" +#include "llthread.h" + +//============================================================================ + +LLMutex::LLMutex(apr_pool_t *poolp) : +	mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD) +{ +	//if (poolp) +	//{ +	//	mIsLocalPool = FALSE; +	//	mAPRPoolp = poolp; +	//} +	//else +	{ +		mIsLocalPool = TRUE; +		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread +	} +	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); +} + + +LLMutex::~LLMutex() +{ +#if MUTEX_DEBUG +	//bad assertion, the subclass LLSignal might be "locked", and that's OK +	//llassert_always(!isLocked()); // better not be locked! +#endif +	if (ll_apr_is_initialized()) +	{ +		apr_thread_mutex_destroy(mAPRMutexp); +		if (mIsLocalPool) +		{ +			apr_pool_destroy(mAPRPoolp); +		} +	} +	mAPRMutexp = NULL; +} + + +void LLMutex::lock() +{ +	if(isSelfLocked()) +	{ //redundant lock +		mCount++; +		return; +	} +	 +	apr_thread_mutex_lock(mAPRMutexp); +	 +#if MUTEX_DEBUG +	// Have to have the lock before we can access the debug info +	U32 id = LLThread::currentID(); +	if (mIsLocked[id] != FALSE) +		llerrs << "Already locked in Thread: " << id << llendl; +	mIsLocked[id] = TRUE; +#endif + +	mLockingThread = LLThread::currentID(); +} + +void LLMutex::unlock() +{ +	if (mCount > 0) +	{ //not the root unlock +		mCount--; +		return; +	} +	 +#if MUTEX_DEBUG +	// Access the debug info while we have the lock +	U32 id = LLThread::currentID(); +	if (mIsLocked[id] != TRUE) +		llerrs << "Not locked in Thread: " << id << llendl;	 +	mIsLocked[id] = FALSE; +#endif + +	mLockingThread = NO_THREAD; +	apr_thread_mutex_unlock(mAPRMutexp); +} + +bool LLMutex::isLocked() +{ +	apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp); +	if (APR_STATUS_IS_EBUSY(status)) +	{ +		return true; +	} +	else +	{ +		apr_thread_mutex_unlock(mAPRMutexp); +		return false; +	} +} + +bool LLMutex::isSelfLocked() +{ +	return mLockingThread == LLThread::currentID(); +} + +U32 LLMutex::lockingThread() const +{ +	return mLockingThread; +} + +//============================================================================ + +LLCondition::LLCondition(apr_pool_t *poolp) : +	LLMutex(poolp) +{ +	// base class (LLMutex) has already ensured that mAPRPoolp is set up. + +	apr_thread_cond_create(&mAPRCondp, mAPRPoolp); +} + + +LLCondition::~LLCondition() +{ +	apr_thread_cond_destroy(mAPRCondp); +	mAPRCondp = NULL; +} + + +void LLCondition::wait() +{ +	if (!isLocked()) +	{ //mAPRMutexp MUST be locked before calling apr_thread_cond_wait +		apr_thread_mutex_lock(mAPRMutexp); +#if MUTEX_DEBUG +		// avoid asserts on destruction in non-release builds +		U32 id = LLThread::currentID(); +		mIsLocked[id] = TRUE; +#endif +	} +	apr_thread_cond_wait(mAPRCondp, mAPRMutexp); +} + +void LLCondition::signal() +{ +	apr_thread_cond_signal(mAPRCondp); +} + +void LLCondition::broadcast() +{ +	apr_thread_cond_broadcast(mAPRCondp); +} + + +//============================================================================ diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h new file mode 100644 index 0000000000..cbde4c47a9 --- /dev/null +++ b/indra/llcommon/llmutex.h @@ -0,0 +1,101 @@ +/**  + * @file llmutex.h + * @brief Base classes for mutex and condition handling. + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLMUTEX_H +#define LL_LLMUTEX_H + +#include "llapr.h" +#include "apr_thread_cond.h" + +//============================================================================ + +#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) + +class LL_COMMON_API LLMutex +{ +public: +	typedef enum +	{ +		NO_THREAD = 0xFFFFFFFF +	} e_locking_thread; + +	LLMutex(apr_pool_t *apr_poolp = NULL); // NULL pool constructs a new pool for the mutex +	virtual ~LLMutex(); +	 +	void lock();		// blocks +	void unlock(); +	bool isLocked(); 	// non-blocking, but does do a lock/unlock so not free +	bool isSelfLocked(); //return true if locked in a same thread +	U32 lockingThread() const; //get ID of locking thread +	 +protected: +	apr_thread_mutex_t *mAPRMutexp; +	mutable U32			mCount; +	mutable U32			mLockingThread; +	 +	apr_pool_t			*mAPRPoolp; +	BOOL				mIsLocalPool; +	 +#if MUTEX_DEBUG +	std::map<U32, BOOL> mIsLocked; +#endif +}; + +// Actually a condition/mutex pair (since each condition needs to be associated with a mutex). +class LL_COMMON_API LLCondition : public LLMutex +{ +public: +	LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. +	~LLCondition(); +	 +	void wait();		// blocks +	void signal(); +	void broadcast(); +	 +protected: +	apr_thread_cond_t *mAPRCondp; +}; + +class LLMutexLock +{ +public: +	LLMutexLock(LLMutex* mutex) +	{ +		mMutex = mutex; +		 +		if(mMutex) +			mMutex->lock(); +	} +	~LLMutexLock() +	{ +		if(mMutex) +			mMutex->unlock(); +	} +private: +	LLMutex* mMutex; +}; + +#endif // LL_LLTHREAD_H diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h index 88c09c8dca..e640ffd595 100755 --- a/indra/llcommon/llpointer.h +++ b/indra/llcommon/llpointer.h @@ -97,24 +97,13 @@ public:  	LLPointer<Type>& operator =(Type* ptr)                     	{  -		if( mPointer != ptr ) -		{ -			unref();  -			mPointer = ptr;  -			ref(); -		} - +		assign(ptr);  		return *this;   	}  	LLPointer<Type>& operator =(const LLPointer<Type>& ptr)    	{  -		if( mPointer != ptr.mPointer ) -		{ -			unref();  -			mPointer = ptr.mPointer; -			ref(); -		} +		assign(ptr);  		return *this;   	} @@ -122,12 +111,7 @@ public:  	template<typename Subclass>  	LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)    	{  -		if( mPointer != ptr.get() ) -		{ -			unref();  -			mPointer = ptr.get(); -			ref(); -		} +		assign(ptr.get());  		return *this;   	} @@ -144,6 +128,16 @@ protected:  	void ref();                               	void unref();  #else + +	void assign(const LLPointer<Type>& ptr) +	{ +		if( mPointer != ptr.mPointer ) +		{ +			unref();  +			mPointer = ptr.mPointer; +			ref(); +		} +	}  	void ref()                               	{   		if (mPointer) @@ -156,9 +150,9 @@ protected:  	{  		if (mPointer)  		{ -			Type *tempp = mPointer; +			Type *temp = mPointer;  			mPointer = NULL; -			tempp->unref(); +			temp->unref();  			if (mPointer != NULL)  			{  				llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl; @@ -171,4 +165,40 @@ protected:  	Type*	mPointer;  }; +template<typename Type> +class LLCopyOnWritePointer : public LLPointer<Type> +{ +public: +	typedef LLCopyOnWritePointer<Type> self_t; +    typedef LLPointer<Type> pointer_t; +     +	LLCopyOnWritePointer()  +	{} + +	LLCopyOnWritePointer(Type* ptr)  +	:	LLPointer<Type>(ptr) +	{} + +	LLCopyOnWritePointer(LLPointer<Type>& ptr) +	:	LLPointer<Type>(ptr) +	{} + +	Type* write() +	{ +		makeUnique(); +		return pointer_t::mPointer; +	} + +	void makeUnique() +	{ +		if (pointer_t::notNull() && pointer_t::mPointer->getNumRefs() > 1) +		{ +			*(pointer_t*)(this) = new Type(*pointer_t::mPointer); +		} +	} + +	const Type*	operator->() const	{ return pointer_t::mPointer; } +	const Type&	operator*() const	{ return *pointer_t::mPointer; } +}; +  #endif diff --git a/indra/llui/llfunctorregistry.cpp b/indra/llcommon/llpredicate.cpp index 8003324973..1278948e24 100755..100644 --- a/indra/llui/llfunctorregistry.cpp +++ b/indra/llcommon/llpredicate.cpp @@ -1,7 +1,6 @@ -/** - * @file llfunctorregistry.cpp - * @author Kent Quirk - * @brief Maintains a registry of named callback functors taking a single LLSD parameter +/**  + * @file llpredicate.cpp + * @brief abstraction for filtering objects by predicates, with arbitrary boolean expressions   *   * $LicenseInfo:firstyear=2008&license=viewerlgpl$   * Second Life Viewer Source Code @@ -23,11 +22,20 @@   *    * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$ - **/ - + */  #include "linden_common.h" -#include "llfunctorregistry.h" -// This is a default functor always resident in the system. -// It's used whenever a functor isn't found in the registry, so that -// we at least log the data relating to the user response. +#include "llpredicate.h" + +namespace LLPredicate +{ +	const U32 cPredicateFlagsFromEnum[5] =  +	{ +		0xAAAAaaaa, // 10101010101010101010101010101010 +		0xCCCCcccc, // 11001100110011001100110011001100 +		0xF0F0F0F0, // 11110000111100001111000011110000 +		0xFF00FF00, // 11111111000000001111111100000000 +		0xFFFF0000  // 11111111111111110000000000000000  +	}; +} + diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h new file mode 100644 index 0000000000..a0e970a799 --- /dev/null +++ b/indra/llcommon/llpredicate.h @@ -0,0 +1,210 @@ +/**  + * @file llpredicate.h + * @brief abstraction for filtering objects by predicates, with arbitrary boolean expressions + * + * $LicenseInfo:firstyear=2008&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_LLPREDICATE_H +#define LL_LLPREDICATE_H + +#include "llerror.h" + +namespace LLPredicate +{ +	template<typename ENUM> class Rule; + +	extern const U32 cPredicateFlagsFromEnum[5]; + +	template<typename ENUM> +	class Value +	{ +	public: +		typedef U32 predicate_flag_t; +		static const S32 cMaxEnum = 5; + +		Value(ENUM e, bool predicate_value = true) +		:	mPredicateFlags(predicate_value ? cPredicateFlagsFromEnum[e] : ~cPredicateFlagsFromEnum[e]) +		{ +			llassert(0 <= e && e < cMaxEnum); +		} + +		Value() +		:	mPredicateFlags(0xFFFFffff) +		{} + +		Value operator!() const +		{ +			Value new_value; +			new_value.mPredicateFlags = ~mPredicateFlags; +			return new_value; +		} + +		Value operator &&(const Value other) const +		{ +			Value new_value; +			new_value.mPredicateFlags = mPredicateFlags & other.mPredicateFlags; +			return new_value; +		} + +		Value operator ||(const Value other) const +		{ +			Value new_value; +			new_value.mPredicateFlags = mPredicateFlags | other.mPredicateFlags; +			return new_value; +		} + +		void set(ENUM e, bool value = true) +		{ +			llassert(0 <= e && e < cMaxEnum); +			predicate_flag_t flags_to_modify; +			predicate_flag_t mask = cPredicateFlagsFromEnum[e]; +			if (value) +			{	// add predicate "e" to flags that don't contain it already +				flags_to_modify = (mPredicateFlags & ~mask); +				// clear flags not containing e +				mPredicateFlags &= mask; +				// add back flags shifted to contain e +				mPredicateFlags |= flags_to_modify << (0x1 << e); +			} +			else +			{	// remove predicate "e" from flags that contain it +				flags_to_modify = (mPredicateFlags & mask); +				// clear flags containing e +				mPredicateFlags &= ~mask; +				// add back flags shifted to not contain e +				mPredicateFlags |= flags_to_modify >> (0x1 << e); +			} +		} + +		void forget(ENUM e) +		{ +			set(e, true); +			U32 flags_with_predicate = mPredicateFlags; +			set(e, false); +			// ambiguous value is result of adding and removing predicate at the same time! +			mPredicateFlags |= flags_with_predicate; +		} + +		bool allSet() const +		{ +			return mPredicateFlags == ~0; +		} + +		bool noneSet() const +		{ +			return mPredicateFlags == 0; +		} + +		bool someSet() const +		{ +			return mPredicateFlags != 0; +		} + +	private: +		predicate_flag_t mPredicateFlags; +	}; + +	template<typename ENUM> +	class Rule +	{ +	public: +		Rule(ENUM value) +		:	mRule(value) +		{} + +		Rule(const Value<ENUM> other) +		:	mRule(other) +		{} + +		Rule() +		{} + +		void require(ENUM e) +		{ +			mRule.set(e, require); +		} + +		void allow(ENUM e) +		{ +			mRule.forget(e); +		} + +		bool check(const Value<ENUM> value) const +		{ +			return (mRule && value).someSet(); +		} + +		bool requires(const Value<ENUM> value) const +		{ +			return (mRule && value).someSet() && (!mRule && value).noneSet(); +		} + +		bool isAmbivalent(const Value<ENUM> value) const +		{ +			return (mRule && value).someSet() && (!mRule && value).someSet(); +		} + +		bool acceptsAll() const +		{ +			return mRule.allSet(); +		} + +		bool acceptsNone() const +		{ +			return mRule.noneSet(); +		} + +		Rule operator!() const +		{ +			Rule new_rule; +			new_rule.mRule = !mRule; +			return new_rule; +		} + +		Rule operator &&(const Rule other) const +		{ +			Rule new_rule; +			new_rule.mRule = mRule && other.mRule; +			return new_rule; +		} + +		Rule operator ||(const Rule other) const +		{ +			Rule new_rule; +			new_rule.mRule = mRule || other.mRule; +			return new_rule; +		} + +	private: +		Value<ENUM> mRule; +	}; +} + +template<typename ENUM> +LLPredicate::Value<ENUM> ll_make_predicate(ENUM e, bool predicate_value = true) +{ +	 return LLPredicate::Value<ENUM>(e, predicate_value); +} + + +#endif // LL_LLPREDICATE_H diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index d711ce2f74..43ccadc412 100755 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h @@ -29,6 +29,7 @@  #include "llinitparam.h"  #include "llsdparam.h" +#include "llwin32headerslean.h"  #include "apr_thread_proc.h"  #include <boost/shared_ptr.hpp>  #include <boost/ptr_container/ptr_vector.hpp> @@ -38,8 +39,7 @@  #include <stdexcept>  #if LL_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include <windows.h>                // HANDLE (eye roll) +#include "llwin32headerslean.h"	// for HANDLE  #elif LL_LINUX  #if defined(Status)  #undef Status diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index fd8f603d21..5ddfa6fcef 100755 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -32,9 +32,7 @@  //#include <memory>  #if LL_WINDOWS -#	define WIN32_LEAN_AND_MEAN -#	include <winsock2.h> -#	include <windows.h> +#	include "llwin32headerslean.h"  #	define _interlockedbittestandset _renamed_interlockedbittestandset  #	define _interlockedbittestandreset _renamed_interlockedbittestandreset  #	include <intrin.h> @@ -877,7 +875,7 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL)  LLProcessorInfo::~LLProcessorInfo() {} -F64 LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } +LLUnitImplicit<LLUnits::Megahertz, F64> LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); }  bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); }  bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); }  bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index 6364d3c8bb..fbd427f484 100755 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -27,6 +27,8 @@  #ifndef LLPROCESSOR_H  #define LLPROCESSOR_H +#include "llunit.h" +  class LLProcessorInfoImpl;  class LL_COMMON_API LLProcessorInfo @@ -35,7 +37,7 @@ public:  	LLProcessorInfo();    	~LLProcessorInfo(); -	F64 getCPUFrequency() const; +	LLUnitImplicit<LLUnits::Megahertz, F64> getCPUFrequency() const;  	bool hasSSE() const;  	bool hasSSE2() const;  	bool hasAltivec() const; diff --git a/indra/llcommon/llptrskiplist.h b/indra/llcommon/llptrskiplist.h deleted file mode 100755 index 67c7cde352..0000000000 --- a/indra/llcommon/llptrskiplist.h +++ /dev/null @@ -1,724 +0,0 @@ -/**  - * @file llptrskiplist.h - * @brief Skip list implementation. - * - * $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$ - */ - -#ifndef LL_LLPTRSKIPLIST_H -#define LL_LLPTRSKIPLIST_H - -#include "llerror.h" -#include "llrand.h" -//#include "vmath.h" -#include "llrand.h" - -///////////////////////////////////////////// -// -//	LLPtrSkipList implementation - skip list for pointers to objects -// - -template <class DATA_TYPE, S32 BINARY_DEPTH = 8> -class LLPtrSkipList -{ -public: -	friend class LLPtrSkipNode; - -	// basic constructor -	LLPtrSkipList(); -	// basic constructor including sorter -	LLPtrSkipList(BOOL	(*insert_first)(DATA_TYPE *first, DATA_TYPE *second),  -				  BOOL	(*equals)(DATA_TYPE *first, DATA_TYPE *second)); -	~LLPtrSkipList(); - -	inline void setInsertFirst(BOOL (*insert_first)(const DATA_TYPE *first, const DATA_TYPE *second)); -	inline void setEquals(BOOL (*equals)(const DATA_TYPE *first, const DATA_TYPE *second)); - -	inline BOOL addData(DATA_TYPE *data); - -	inline BOOL checkData(const DATA_TYPE *data); - -	inline S32 getLength();	// returns number of items in the list - NOT constant time! - -	inline BOOL removeData(const DATA_TYPE *data); - -	// note that b_sort is ignored -	inline BOOL moveData(const DATA_TYPE *data, LLPtrSkipList *newlist, BOOL b_sort); - -	inline BOOL moveCurrentData(LLPtrSkipList *newlist, BOOL b_sort); - -	// resort -- use when the value we're sorting by changes -	/* IW 12/6/02 - This doesn't work! -	   Instead, remove the data BEFORE you change it -	   Then re-insert it after you change it -	BOOL resortData(DATA_TYPE *data) -	*/ - -	// remove all nodes from the list but do not delete data -	inline void removeAllNodes(); - -	inline BOOL deleteData(const DATA_TYPE *data); - -	// remove all nodes from the list and delete data -	inline void deleteAllData(); - -	// place mCurrentp on first node -	inline void resetList(); - -	// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -	inline DATA_TYPE	*getCurrentData(); - -	// same as getCurrentData() but a more intuitive name for the operation -	inline DATA_TYPE	*getNextData(); - -	// remove the Node at mCurentOperatingp -	// leave mCurrentp and mCurentOperatingp on the next entry -	inline void removeCurrentData(); - -	// delete the Node at mCurentOperatingp -	// leave mCurrentp and mCurentOperatingp on the next entry -	inline void deleteCurrentData(); - -	// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -	inline DATA_TYPE	*getFirstData(); - -	// TRUE if nodes are not in sorted order -	inline BOOL corrupt(); - -protected: -	class LLPtrSkipNode -	{ -	public: -		LLPtrSkipNode() -		:	mData(NULL) -		{ -			S32 i; -			for (i = 0; i < BINARY_DEPTH; i++) -			{ -				mForward[i] = NULL; -			} -		} - -		LLPtrSkipNode(DATA_TYPE *data) -			: mData(data) -		{ -			S32 i; -			for (i = 0; i < BINARY_DEPTH; i++) -			{ -				mForward[i] = NULL; -			} -		} - -		~LLPtrSkipNode() -		{ -			if (mData) -			{ -				llerror("Attempting to call LLPtrSkipNode destructor with a non-null mDatap!", 1); -			} -		} - -		// delete associated data and NULLs out pointer -		void deleteData() -		{ -			delete mData; -			mData = NULL; -		} - -		// NULLs out pointer -		void removeData() -		{ -			mData = NULL; -		} - -		DATA_TYPE					*mData; -		LLPtrSkipNode				*mForward[BINARY_DEPTH]; -	}; - -	static BOOL					defaultEquals(const DATA_TYPE *first, const DATA_TYPE *second) -	{ -		return first == second; -	} - - -	LLPtrSkipNode				mHead; -	LLPtrSkipNode				*mUpdate[BINARY_DEPTH]; -	LLPtrSkipNode				*mCurrentp; -	LLPtrSkipNode				*mCurrentOperatingp; -	S32							mLevel; -	BOOL						(*mInsertFirst)(const DATA_TYPE *first, const DATA_TYPE *second); -	BOOL						(*mEquals)(const DATA_TYPE *first, const DATA_TYPE *second); -}; - - -// basic constructor -template <class DATA_TYPE, S32 BINARY_DEPTH>  -LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::LLPtrSkipList() -	: mInsertFirst(NULL), mEquals(defaultEquals) -{ -	if (BINARY_DEPTH < 2) -	{ -		llerrs << "Trying to create skip list with too little depth, " -			"must be 2 or greater" << llendl; -	} -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mUpdate[i] = NULL; -	} -	mLevel = 1; -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -// basic constructor including sorter -template <class DATA_TYPE, S32 BINARY_DEPTH>  -LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::LLPtrSkipList(BOOL	(*insert_first)(DATA_TYPE *first, DATA_TYPE *second),  -													  BOOL	(*equals)(DATA_TYPE *first, DATA_TYPE *second))  -	:mInsertFirst(insert_first), mEquals(equals) -{ -	if (BINARY_DEPTH < 2) -	{ -		llerrs << "Trying to create skip list with too little depth, " -			"must be 2 or greater" << llendl; -	} -	mLevel = 1; -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::~LLPtrSkipList() -{ -	removeAllNodes(); -} - -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::setInsertFirst(BOOL (*insert_first)(const DATA_TYPE *first, const DATA_TYPE *second)) -{ -	mInsertFirst = insert_first; -} - -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::setEquals(BOOL (*equals)(const DATA_TYPE *first, const DATA_TYPE *second)) -{ -	mEquals = equals; -} - -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::addData(DATA_TYPE *data) -{ -	S32				level; -	LLPtrSkipNode	*current = &mHead; -	LLPtrSkipNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mData, data))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mData < data)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} - -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	// now add the new node -	S32 newlevel; -	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) -	{ -		if (ll_frand() < 0.5f) -			break; -	} - -	LLPtrSkipNode *snode = new LLPtrSkipNode(data); - -	if (newlevel > mLevel) -	{ -		mHead.mForward[mLevel] = NULL; -		mUpdate[mLevel] = &mHead; -		mLevel = newlevel; -	} - -	for (level = 0; level < newlevel; level++) -	{ -		snode->mForward[level] = mUpdate[level]->mForward[level]; -		mUpdate[level]->mForward[level] = snode; -	} -	return TRUE; -} - -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::checkData(const DATA_TYPE *data) -{ -	S32			level; -	LLPtrSkipNode	*current = &mHead; -	LLPtrSkipNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mData, data))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mData < data)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} - -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; -	 -	if (current) -	{ -		return mEquals(current->mData, data); -	} -	else -	{ -		return FALSE; -	} -} - -// returns number of items in the list -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline S32 LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getLength() -{ -	U32	length = 0; -	for (LLPtrSkipNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0]) -	{ -		length++; -	} -	return length; -} - -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeData(const DATA_TYPE *data) -{ -	S32			level; -	LLPtrSkipNode	*current = &mHead; -	LLPtrSkipNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mData, data))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mData < data)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} - -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (!current) -	{ -		// empty list or beyond the end! -		return FALSE; -	} - -	// is this the one we want? -	if (!mEquals(current->mData, data)) -	{ -		// nope! -			return FALSE; -	} -	else -	{ -		// yes it is!  change pointers as required -		for (level = 0; level < mLevel; level++) -		{ -			if (mUpdate[level]->mForward[level] != current) -			{ -				// cool, we've fixed all the pointers! -				break; -			} -			mUpdate[level]->mForward[level] = current->mForward[level]; -		} - -		// clean up cuurent -		current->removeData(); -		delete current; - -		// clean up mHead -		while (  (mLevel > 1) -			   &&(!mHead.mForward[mLevel - 1])) -		{ -			mLevel--; -		} -	} -	return TRUE; -} - -// note that b_sort is ignored -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::moveData(const DATA_TYPE *data, LLPtrSkipList *newlist, BOOL b_sort) -{ -	BOOL removed = removeData(data); -	BOOL added = newlist->addData(data); -	return removed && added; -} - -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::moveCurrentData(LLPtrSkipList *newlist, BOOL b_sort) -{ -	if (mCurrentOperatingp) -	{ -		mCurrentp = mCurrentOperatingp->mForward[0];	 -		BOOL removed = removeData(mCurrentOperatingp); -		BOOL added = newlist->addData(mCurrentOperatingp); -		mCurrentOperatingp = mCurrentp; -		return removed && added; -	} -	return FALSE; -} - -// resort -- use when the value we're sorting by changes -/* IW 12/6/02 - This doesn't work! -   Instead, remove the data BEFORE you change it -   Then re-insert it after you change it -BOOL resortData(DATA_TYPE *data) -{ -	removeData(data); -	addData(data); -} -*/ - -// remove all nodes from the list but do not delete data -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeAllNodes() -{ -	LLPtrSkipNode *temp; -	// reset mCurrentp -	mCurrentp = *(mHead.mForward); - -	while (mCurrentp) -	{ -		temp = mCurrentp->mForward[0]; -		mCurrentp->removeData(); -		delete mCurrentp; -		mCurrentp = temp; -	} - -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} - -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteData(const DATA_TYPE *data) -{ -	S32			level; -	LLPtrSkipNode	*current = &mHead; -	LLPtrSkipNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mData, data))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mData < data)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} - -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (!current) -	{ -		// empty list or beyond the end! -		return FALSE; -	} - -	// is this the one we want? -	if (!mEquals(current->mData, data)) -	{ -		// nope! -		return FALSE; -	} -	else -	{ -		// do we need to fix current or currentop? -		if (current == mCurrentp) -		{ -			mCurrentp = current->mForward[0]; -		} - -		if (current == mCurrentOperatingp) -		{ -			mCurrentOperatingp = current->mForward[0]; -		} - -		// yes it is!  change pointers as required -		for (level = 0; level < mLevel; level++) -		{ -			if (mUpdate[level]->mForward[level] != current) -			{ -				// cool, we've fixed all the pointers! -				break; -			} -			mUpdate[level]->mForward[level] = current->mForward[level]; -		} - -		// clean up cuurent -		current->deleteData(); -		delete current; - -		// clean up mHead -		while (  (mLevel > 1) -			   &&(!mHead.mForward[mLevel - 1])) -		{ -			mLevel--; -		} -	} -	return TRUE; -} - -// remove all nodes from the list and delete data -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteAllData() -{ -	LLPtrSkipNode *temp; -	// reset mCurrentp -	mCurrentp = *(mHead.mForward); - -	while (mCurrentp) -	{ -		temp = mCurrentp->mForward[0]; -		mCurrentp->deleteData(); -		delete mCurrentp; -		mCurrentp = temp; -	} - -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} - -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -// place mCurrentp on first node -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::resetList() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getCurrentData() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = *mCurrentp->mForward; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL;		// causes compile warning -		return 0; 			// equivalent, but no warning -	} -} - -// same as getCurrentData() but a more intuitive name for the operation -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getNextData() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = *mCurrentp->mForward; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL;		// causes compile warning -		return 0; 			// equivalent, but no warning -	} -} - -// remove the Node at mCurentOperatingp -// leave mCurrentp and mCurentOperatingp on the next entry -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::removeCurrentData() -{ -	if (mCurrentOperatingp) -	{ -		removeData(mCurrentOperatingp->mData); -	} -} - -// delete the Node at mCurentOperatingp -// leave mCurrentp and mCurentOperatingp on the next entry -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline void LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::deleteCurrentData() -{ -	if (mCurrentOperatingp) -	{ -		deleteData(mCurrentOperatingp->mData); -	} -} - -// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline DATA_TYPE *LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::getFirstData() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL;		// causes compile warning -		return 0; 			// equivalent, but no warning -	} -} - -template <class DATA_TYPE, S32 BINARY_DEPTH>  -inline BOOL LLPtrSkipList<DATA_TYPE, BINARY_DEPTH>::corrupt() -{ -	LLPtrSkipNode *previous = mHead.mForward[0]; - -	// Empty lists are not corrupt. -	if (!previous) return FALSE; - -	LLPtrSkipNode *current = previous->mForward[0]; -	while(current) -	{ -		if (!mInsertFirst(previous->mData, current->mData)) -		{ -			// prev shouldn't be in front of cur! -			return TRUE; -		} -		current = current->mForward[0]; -	} -	return FALSE; -} - -#endif diff --git a/indra/llcommon/llptrskipmap.h b/indra/llcommon/llptrskipmap.h deleted file mode 100755 index 94bc71ec55..0000000000 --- a/indra/llcommon/llptrskipmap.h +++ /dev/null @@ -1,1239 +0,0 @@ -/**  - * @file llptrskipmap.h - * @brief Just like a LLSkipMap, but since it's pointers, you can call - * deleteAllData - * - * $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$ - */ -#ifndef LL_LLPTRSKIPMAP_H -#define LL_LLPTRSKIPMAP_H - -#include "llerror.h" -#include "llrand.h" - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH = 8>  -class LLPtrSkipMapNode -{ -public: -	LLPtrSkipMapNode() -	{ -		S32 i; -		for (i = 0; i < BINARY_DEPTH; i++) -		{ -			mForward[i] = NULL; -		} - -		U8  *zero = (U8 *)&mIndex; - -		for (i = 0; i < (S32)sizeof(INDEX_T); i++) -		{ -			*(zero + i) = 0; -		} - -		zero = (U8 *)&mData; - -		for (i = 0; i < (S32)sizeof(DATA_T); i++) -		{ -			*(zero + i) = 0; -		} -	} - -	LLPtrSkipMapNode(const INDEX_T &index) -	:	mIndex(index) -	{ - -		S32 i; -		for (i = 0; i < BINARY_DEPTH; i++) -		{ -			mForward[i] = NULL; -		} - -		U8 *zero = (U8 *)&mData; - -		for (i = 0; i < (S32)sizeof(DATA_T); i++) -		{ -			*(zero + i) = 0; -		} -	} - -	LLPtrSkipMapNode(const INDEX_T &index, DATA_T datap) -	:	mIndex(index) -	{ - -		S32 i; -		for (i = 0; i < BINARY_DEPTH; i++) -		{ -			mForward[i] = NULL; -		} - -		mData = datap; -	} - -	~LLPtrSkipMapNode() -	{ -	} - -	// delete associated data and NULLs out pointer -	void deleteData() -	{ -		delete mData; -		mData = 0; -	} - -	// NULLs out pointer -	void removeData() -	{ -		mData = 0; -	} - -	INDEX_T					mIndex; -	DATA_T					mData; -	LLPtrSkipMapNode				*mForward[BINARY_DEPTH]; - -private: -	// Disallow copying of LLPtrSkipMapNodes by not implementing these methods. -	LLPtrSkipMapNode(const LLPtrSkipMapNode &); -	LLPtrSkipMapNode &operator=(const LLPtrSkipMapNode &rhs); -}; - -//--------------------------------------------------------------------------- - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH = 8>  -class LLPtrSkipMap -{ -public: -	typedef BOOL (*compare)(const DATA_T& first, const DATA_T& second); -	typedef compare insert_func; -	typedef compare equals_func; - -	void init(); - -	// basic constructor -	LLPtrSkipMap(); - -	// basic constructor including sorter -	LLPtrSkipMap(insert_func insert_first, equals_func equals); - -	~LLPtrSkipMap(); - -	void setInsertFirst(insert_func insert_first); -	void setEquals(equals_func equals); - -	DATA_T &addData(const INDEX_T &index, DATA_T datap); -	DATA_T &addData(const INDEX_T &index); -	DATA_T &getData(const INDEX_T &index); -	DATA_T &operator[](const INDEX_T &index); - -	// If index present, returns data. -	// If index not present, adds <index,NULL> and returns NULL. -	DATA_T &getData(const INDEX_T &index, BOOL &b_new_entry); - -	// returns data entry before and after index -	BOOL getInterval(const INDEX_T &index, INDEX_T &index_before, INDEX_T &index_after, -		DATA_T &data_before, DATA_T &data_after	); - -	// Returns TRUE if data present in map. -	BOOL checkData(const INDEX_T &index); - -	// Returns TRUE if key is present in map. This is useful if you -	// are potentially storing NULL pointers in the map -	BOOL checkKey(const INDEX_T &index); - -	// If there, returns the data. -	// If not, returns NULL. -	// Never adds entries to the map. -	DATA_T getIfThere(const INDEX_T &index); - -	INDEX_T reverseLookup(const DATA_T datap); - -	// returns number of items in the list -	S32 getLength(); // WARNING!  getLength is O(n), not O(1)! - -	BOOL removeData(const INDEX_T &index); -	BOOL deleteData(const INDEX_T &index); - -	// remove all nodes from the list but do not delete data -	void removeAllData(); -	void deleteAllData(); - -	// place mCurrentp on first node -	void resetList(); - -	// return the data currently pointed to -	DATA_T	getCurrentDataWithoutIncrement(); - -	// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -	DATA_T	getCurrentData(); - -	// same as getCurrentData() but a more intuitive name for the operation -	DATA_T	getNextData(); - -	INDEX_T	getNextKey(); - -	// return the key currently pointed to -	INDEX_T	getCurrentKeyWithoutIncrement(); - -	// remove the Node at mCurentOperatingp -	// leave mCurrentp and mCurentOperatingp on the next entry -	void removeCurrentData(); - -	void deleteCurrentData(); - -	// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -	DATA_T	getFirstData(); - -	INDEX_T	getFirstKey(); - -	static BOOL	defaultEquals(const INDEX_T &first, const INDEX_T &second) -	{ -		return first == second; -	} - -private: -	// don't generate implicit copy constructor or copy assignment -	LLPtrSkipMap(const LLPtrSkipMap &); -	LLPtrSkipMap &operator=(const LLPtrSkipMap &); - -private: -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*mUpdate[BINARY_DEPTH]; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*mCurrentp; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*mCurrentOperatingp; -	S32							mLevel; -	BOOL						(*mInsertFirst)(const INDEX_T &first, const INDEX_T &second); -	BOOL						(*mEquals)(const INDEX_T &first, const INDEX_T &second); -	S32							mNumberOfSteps; -}; - -////////////////////////////////////////////////// -// -// LLPtrSkipMap implementation -// -// - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::LLPtrSkipMap() -	:	mInsertFirst(NULL), -		mEquals(defaultEquals), -		mNumberOfSteps(0) -{ -	if (BINARY_DEPTH < 2) -	{ -		llerrs << "Trying to create skip list with too little depth, " -			"must be 2 or greater" << llendl; -	} -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mUpdate[i] = NULL; -	} -	mLevel = 1; -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::LLPtrSkipMap(insert_func insert_first,  -																 equals_func equals)  -:	mInsertFirst(insert_first), -	mEquals(equals), -	mNumberOfSteps(0) -{ -	if (BINARY_DEPTH < 2) -	{ -		llerrs << "Trying to create skip list with too little depth, " -			"must be 2 or greater" << llendl; -	} -	mLevel = 1; -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::~LLPtrSkipMap() -{ -	removeAllData(); -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::setInsertFirst(insert_func insert_first) -{ -	mInsertFirst = insert_first; -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::setEquals(equals_func equals) -{ -	mEquals = equals; -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_T &index, DATA_T datap) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	// replace the existing data if a node is already there -	if (  (current) -		&&(mEquals(current->mIndex, index))) -	{ -		current->mData = datap; -		return current->mData; -	} - -	// now add the new node -	S32 newlevel; -	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) -	{ -		if (ll_frand() < 0.5f) -		{ -			break; -		} -	} - -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode  -		= new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index, datap); - -	if (newlevel > mLevel) -	{ -		mHead.mForward[mLevel] = NULL; -		mUpdate[mLevel] = &mHead; -		mLevel = newlevel; -	} - -	for (level = 0; level < newlevel; level++) -	{ -		snode->mForward[level] = mUpdate[level]->mForward[level]; -		mUpdate[level]->mForward[level] = snode; -	} -	return snode->mData; -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::addData(const INDEX_T &index) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	// now add the new node -	S32 newlevel; -	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) -	{ -		if (ll_frand() < 0.5f) -			break; -	} - -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode  -		= new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index); - -	if (newlevel > mLevel) -	{ -		mHead.mForward[mLevel] = NULL; -		mUpdate[mLevel] = &mHead; -		mLevel = newlevel; -	} - -	for (level = 0; level < newlevel; level++) -	{ -		snode->mForward[level] = mUpdate[level]->mForward[level]; -		mUpdate[level]->mForward[level] = snode; -	} -	return snode->mData; -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_T &index) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	mNumberOfSteps = 0; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; -	mNumberOfSteps++; - -	if (  (current) -		&&(mEquals(current->mIndex, index))) -	{ -		 -		return current->mData; -	} -	 -	// now add the new node -	S32 newlevel; -	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) -	{ -		if (ll_frand() < 0.5f) -			break; -	} - -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *snode  -		= new LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>(index); - -	if (newlevel > mLevel) -	{ -		mHead.mForward[mLevel] = NULL; -		mUpdate[mLevel] = &mHead; -		mLevel = newlevel; -	} - -	for (level = 0; level < newlevel; level++) -	{ -		snode->mForward[level] = mUpdate[level]->mForward[level]; -		mUpdate[level]->mForward[level] = snode; -	} -	 -	return snode->mData; -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getInterval(const INDEX_T &index,  -																	 INDEX_T &index_before,  -																	 INDEX_T &index_after,  -																	 DATA_T &data_before,  -																	 DATA_T &data_after) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	mNumberOfSteps = 0; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	 -	BOOL both_found = TRUE; - -	if (current != &mHead) -	{ -		index_before = current->mIndex; -		data_before = current->mData; -	} -	else -	{ -		data_before = 0; -		index_before = 0; -		both_found = FALSE; -	} - -	// we're now just in front of where we want to be . . . take one step forward -	mNumberOfSteps++; -	current = *current->mForward; - -	if (current) -	{ -		data_after = current->mData; -		index_after = current->mIndex; -	} -	else -	{ -		data_after = 0; -		index_after = 0; -		both_found = FALSE; -	} - -	return both_found; -} - - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::operator[](const INDEX_T &index) -{ -	 -	return getData(index); -} - -// If index present, returns data. -// If index not present, adds <index,NULL> and returns NULL. -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T &LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getData(const INDEX_T &index, BOOL &b_new_entry) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	mNumberOfSteps = 0; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	mNumberOfSteps++; -	current = *current->mForward; - -	if (  (current) -		&&(mEquals(current->mIndex, index))) -	{ -		 -		return current->mData; -	} -	b_new_entry = TRUE; -	addData(index); -	 -	return current->mData; -} - -// Returns TRUE if data present in map. -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::checkData(const INDEX_T &index) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (current) -	{ -		// Gets rid of some compiler ambiguity for the LLPointer<> templated class. -		if (current->mData) -		{ -			return mEquals(current->mIndex, index); -		} -	} - -	return FALSE; -} - -// Returns TRUE if key is present in map. This is useful if you -// are potentially storing NULL pointers in the map -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::checkKey(const INDEX_T &index) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (current) -	{ -		return mEquals(current->mIndex, index); -	} - -	return FALSE; -} - -// If there, returns the data. -// If not, returns NULL. -// Never adds entries to the map. -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getIfThere(const INDEX_T &index) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	mNumberOfSteps = 0; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	mNumberOfSteps++; -	current = *current->mForward; - -	if (current) -	{ -		if (mEquals(current->mIndex, index)) -		{ -			return current->mData; -		} -	} - -	// Avoid Linux compiler warning on returning NULL. -	return (DATA_T)0; -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::reverseLookup(const DATA_T datap) -{ -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; - -	while (current) -	{ -		if (datap == current->mData) -		{ -			 -			return current->mIndex; -		} -		current = *current->mForward; -	} - -	// not found! return NULL -	return INDEX_T(); -} - -// returns number of items in the list -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline S32 LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getLength() -{ -	U32	length = 0; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>* temp; -	for (temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0]) -	{ -		length++; -	} -	 -	return length; -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeData(const INDEX_T &index) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (!current) -	{ -		// empty list or beyond the end! -		 -		return FALSE; -	} - -	// is this the one we want? -	if (!mEquals(current->mIndex, index)) -	{ -		// nope! -		 -		return FALSE; -	} -	else -	{ -		// do we need to fix current or currentop? -		if (current == mCurrentp) -		{ -			mCurrentp = *current->mForward; -		} - -		if (current == mCurrentOperatingp) -		{ -			mCurrentOperatingp = *current->mForward; -		} -		// yes it is!  change pointers as required -		for (level = 0; level < mLevel; level++) -		{ -			if (*((*(mUpdate + level))->mForward + level) != current) -			{ -				// cool, we've fixed all the pointers! -				break; -			} -			*((*(mUpdate + level))->mForward + level) = *(current->mForward + level); -		} - -		// clean up cuurent -		current->removeData(); -		delete current; - -		// clean up mHead -		while (  (mLevel > 1) -			   &&(!*(mHead.mForward + mLevel - 1))) -		{ -			mLevel--; -		} -	} -	 -	return TRUE; -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline BOOL LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteData(const INDEX_T &index) -{ -	S32			level; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*current = &mHead; -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH>	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (!current) -	{ -		// empty list or beyond the end! -		 -		return FALSE; -	} - -	// is this the one we want? -	if (!mEquals(current->mIndex, index)) -	{ -		// nope! -		 -		return FALSE; -	} -	else -	{ -		// do we need to fix current or currentop? -		if (current == mCurrentp) -		{ -			mCurrentp = *current->mForward; -		} - -		if (current == mCurrentOperatingp) -		{ -			mCurrentOperatingp = *current->mForward; -		} -		// yes it is!  change pointers as required -		for (level = 0; level < mLevel; level++) -		{ -			if (*((*(mUpdate + level))->mForward + level) != current) -			{ -				// cool, we've fixed all the pointers! -				break; -			} -			*((*(mUpdate + level))->mForward + level) = *(current->mForward + level); -		} - -		// clean up cuurent -		current->deleteData(); -		delete current; - -		// clean up mHead -		while (  (mLevel > 1) -			   &&(!*(mHead.mForward + mLevel - 1))) -		{ -			mLevel--; -		} -	} -	 -	return TRUE; -} - -// remove all nodes from the list but do not delete data -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeAllData() -{ -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; -	// reset mCurrentp -	mCurrentp = *(mHead.mForward); - -	while (mCurrentp) -	{ -		temp = mCurrentp->mForward[0]; -		mCurrentp->removeData(); -		delete mCurrentp; -		mCurrentp = temp; -	} - -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} - -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteAllData() -{ -	LLPtrSkipMapNode<INDEX_T, DATA_T, BINARY_DEPTH> *temp; -	// reset mCurrentp -	mCurrentp = *(mHead.mForward); - -	while (mCurrentp) -	{ -		temp = mCurrentp->mForward[0]; -		mCurrentp->deleteData(); -		delete mCurrentp; -		mCurrentp = temp; -	} - -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} - -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -// place mCurrentp on first node -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::resetList() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - - -// return the data currently pointed to -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentDataWithoutIncrement() -{ -	if (mCurrentOperatingp) -	{ -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL; 		// causes warning -		return (DATA_T)0;			// equivalent, but no warning -	} -} - -// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentData() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL; 		// causes warning -		return (DATA_T)0;			// equivalent, but no warning -	} -} - -// same as getCurrentData() but a more intuitive name for the operation -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getNextData() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL;	// causes compile warning -		return (DATA_T)0;		// equivalent, but removes warning -	} -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getNextKey() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mIndex; -	} -	else -	{ -		return mHead.mIndex; -	} -} - -// return the key currently pointed to -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getCurrentKeyWithoutIncrement() -{ -	if (mCurrentOperatingp) -	{ -		return mCurrentOperatingp->mIndex; -	} -	else -	{ -		//return NULL;	// causes compile warning -		return (INDEX_T)0;		// equivalent, but removes warning -	} -} - - -// remove the Node at mCurentOperatingp -// leave mCurrentp and mCurentOperatingp on the next entry -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::removeCurrentData() -{ -	if (mCurrentOperatingp) -	{ -		removeData(mCurrentOperatingp->mIndex); -	} -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline void LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::deleteCurrentData() -{ -	if (mCurrentOperatingp) -	{ -		deleteData(mCurrentOperatingp->mIndex); -	} -} - -// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline DATA_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getFirstData() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL;	// causes compile warning -		return (DATA_T)0;		// equivalent, but removes warning -	} -} - -template <class INDEX_T, class DATA_T, S32 BINARY_DEPTH> -inline INDEX_T LLPtrSkipMap<INDEX_T, DATA_T, BINARY_DEPTH>::getFirstKey() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mIndex; -	} -	else -	{ -		return mHead.mIndex; -	} -} - -#endif diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index abf47a0f57..4339f203db 100755 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -28,6 +28,7 @@  #include "llstl.h"  #include "lltimer.h"	// ms_sleep() +#include "lltracethreadrecorder.h"  //============================================================================ @@ -134,8 +135,8 @@ S32 LLQueuedThread::updateQueue(F32 max_time_ms)  		pending = getPending();  		if(pending > 0)  		{ -			unpause(); -		} +		unpause(); +	}  	}  	else  	{ @@ -403,6 +404,7 @@ S32 LLQueuedThread::processNextRequest()  	QueuedRequest *req;  	// Get next request from pool  	lockData(); +	  	while(1)  	{  		req = NULL; @@ -467,10 +469,11 @@ S32 LLQueuedThread::processNextRequest()  				ms_sleep(1); // sleep the thread a little  			}  		} +		 +		LLTrace::get_thread_recorder()->pushToMaster();  	}  	S32 pending = getPending(); -  	return pending;  } @@ -499,6 +502,7 @@ void LLQueuedThread::run()  		if (isQuitting())  		{ +			LLTrace::get_thread_recorder()->pushToMaster();  			endThread();  			break;  		} @@ -507,8 +511,9 @@ void LLQueuedThread::run()  		threadedUpdate(); -		int res = processNextRequest(); -		if (res == 0) +		int pending_work = processNextRequest(); + +		if (pending_work == 0)  		{  			mIdleThread = TRUE;  			ms_sleep(1); diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index bb0d60247e..c8ec0a0bc0 100755 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -29,7 +29,6 @@  #include <list> -#include <boost/type_traits.hpp>  #include "llsingleton.h"  #include "llstl.h" @@ -47,12 +46,11 @@ template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultC  class LLRegistry  {  public: -	typedef LLRegistry<KEY, VALUE, COMPARATOR>											registry_t; -	typedef typename boost::add_reference<typename boost::add_const<KEY>::type>::type	ref_const_key_t; -	typedef typename boost::add_reference<typename boost::add_const<VALUE>::type>::type	ref_const_value_t; -	typedef typename boost::add_reference<VALUE>::type									ref_value_t; -	typedef typename boost::add_pointer<typename boost::add_const<VALUE>::type>::type	ptr_const_value_t; -	typedef typename boost::add_pointer<VALUE>::type									ptr_value_t; +	typedef LLRegistry<KEY, VALUE, COMPARATOR>		registry_t; +	typedef const KEY& 								ref_const_key_t; +	typedef const VALUE&							ref_const_value_t; +	typedef const VALUE*							ptr_const_value_t; +	typedef VALUE*									ptr_value_t;  	class Registrar  	{ diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp index 9f4460a988..50815b2cc6 100755 --- a/indra/llcommon/llsdparam.cpp +++ b/indra/llcommon/llsdparam.cpp @@ -102,13 +102,13 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool  	//readSDValues(sd, block);  } -void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block) +void LLParamSDParser::writeSDImpl(LLSD& sd, const LLInitParam::BaseBlock& block, const LLInitParam::predicate_rule_t rules, const LLInitParam::BaseBlock* diff_block)  {  	mNameStack.clear();  	mWriteRootSD = &sd;  	name_stack_t name_stack; -	block.serializeBlock(*this, name_stack); +	block.serializeBlock(*this, name_stack, rules, diff_block);  }  /*virtual*/ std::string LLParamSDParser::getCurrentElementName() @@ -299,6 +299,7 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd)  	LLInitParam::Parser::name_stack_t stack = LLInitParam::Parser::name_stack_t();  	readSDValues(cb, sd, stack);  } +  namespace LLInitParam  {  	// LLSD specialization @@ -329,13 +330,14 @@ namespace LLInitParam  		p.writeValue<LLSD::String>(sd.asString(), name_stack);  	} -	void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const +	bool ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack_range, const predicate_rule_t predicate_rule, const BaseBlock* diff_block) const  	{  		// attempt to write LLSD out directly -		if (!p.writeValue<LLSD>(mValue, name_stack)) +		if (!p.writeValue<LLSD>(mValue, name_stack_range))  		{  			// otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc) -			LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack); +			LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack_range);  		} +		return true;  	}  } diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h index 6ef5debd7b..7cfc265c62 100755 --- a/indra/llcommon/llsdparam.h +++ b/indra/llcommon/llsdparam.h @@ -30,6 +30,7 @@  #include "llinitparam.h"  #include "boost/function.hpp" +#include "llfasttimer.h"  struct LL_COMMON_API LLParamSDParserUtilities  { @@ -50,11 +51,28 @@ typedef LLInitParam::Parser parser_t;  public:  	LLParamSDParser();  	void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false); -	void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block); +	template<typename BLOCK> +	void writeSD(LLSD& sd,  +		const BLOCK& block,  +		const LLInitParam::predicate_rule_t rules = LLInitParam::default_parse_rules(), +		const LLInitParam::BaseBlock* diff_block = NULL) +	{ +		if (!diff_block  +			&& !rules.isAmbivalent(LLInitParam::HAS_DEFAULT_VALUE)) +		{ +			diff_block = &LLInitParam::defaultValue<BLOCK>(); +		} +		writeSDImpl(sd, block, rules, diff_block); +	}  	/*virtual*/ std::string getCurrentElementName();  private: +	void writeSDImpl(LLSD& sd,  +		const LLInitParam::BaseBlock& block,  +		const LLInitParam::predicate_rule_t, +		const LLInitParam::BaseBlock* diff_block); +  	void submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack);  	template<typename T> diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index eb8e2c9456..9b49e52377 100755 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -28,5 +28,4 @@  #include "llsingleton.h" -std::map<std::string, void *> * LLSingletonRegistry::sSingletonMap = NULL; diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 49d99f2cd0..b9cb8e3d41 100755 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -30,38 +30,6 @@  #include <typeinfo>  #include <boost/noncopyable.hpp> -/// @brief A global registry of all singletons to prevent duplicate allocations -/// across shared library boundaries -class LL_COMMON_API LLSingletonRegistry { -	private: -		typedef std::map<std::string, void *> TypeMap; -		static TypeMap * sSingletonMap; - -		static void checkInit() -		{ -			if(sSingletonMap == NULL) -			{ -				sSingletonMap = new TypeMap(); -			} -		} - -	public: -		template<typename T> static void * & get() -		{ -			std::string name(typeid(T).name()); - -			checkInit(); - -			// the first entry of the pair returned by insert will be either the existing -			// iterator matching our key, or the newly inserted NULL initialized entry -			// see "Insert element" in http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html -			TypeMap::iterator result = -				sSingletonMap->insert(std::make_pair(name, (void*)NULL)).first; - -			return result->second; -		} -}; -  // LLSingleton implements the getInstance() method part of the Singleton  // pattern. It can't make the derived class constructors protected, though, so  // you have to do that yourself. @@ -99,22 +67,30 @@ private:  		INITIALIZED,  		DELETED  	} EInitState; +     +    static DERIVED_TYPE* constructSingleton() +    { +        return new DERIVED_TYPE(); +    }  	// stores pointer to singleton instance -	// and tracks initialization state of singleton -	struct SingletonInstanceData +	struct SingletonLifetimeManager  	{ -		EInitState		mInitState; -		DERIVED_TYPE*	mSingletonInstance; -		 -		SingletonInstanceData() -		:	mSingletonInstance(NULL), -			mInitState(UNINITIALIZED) -		{} - -		~SingletonInstanceData() +		SingletonLifetimeManager() +		{ +			construct(); +		} + +		static void construct()  		{ -			if (mInitState != DELETED) +			sData.mInitState = CONSTRUCTING; +			sData.mInstance = constructSingleton(); +			sData.mInitState = INITIALIZING; +		} + +		~SingletonLifetimeManager() +		{ +			if (sData.mInitState != DELETED)  			{  				deleteSingleton();  			} @@ -124,9 +100,8 @@ private:  public:  	virtual ~LLSingleton()  	{ -		SingletonInstanceData& data = getData(); -		data.mSingletonInstance = NULL; -		data.mInitState = DELETED; +		sData.mInstance = NULL; +		sData.mInitState = DELETED;  	}  	/** @@ -151,50 +126,49 @@ public:  	 */  	static void deleteSingleton()  	{ -		delete getData().mSingletonInstance; -		getData().mSingletonInstance = NULL; -		getData().mInitState = DELETED; +		delete sData.mInstance; +		sData.mInstance = NULL; +		sData.mInitState = DELETED;  	} -	static SingletonInstanceData& getData() -	{ -		// this is static to cache the lookup results -		static void * & registry = LLSingletonRegistry::get<DERIVED_TYPE>(); - -		// *TODO - look into making this threadsafe -		if(NULL == registry) -		{ -			static SingletonInstanceData data; -			registry = &data; -		} - -		return *static_cast<SingletonInstanceData *>(registry); -	}  	static DERIVED_TYPE* getInstance()  	{ -		SingletonInstanceData& data = getData(); +		static SingletonLifetimeManager sLifeTimeMgr; -		if (data.mInitState == CONSTRUCTING) +		switch (sData.mInitState)  		{ +		case UNINITIALIZED: +			// should never be uninitialized at this point +			llassert(false); +			return NULL; +		case CONSTRUCTING:  			llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl; -		} - -		if (data.mInitState == DELETED) -		{ +			return NULL; +		case INITIALIZING: +			// go ahead and flag ourselves as initialized so we can be reentrant during initialization +			sData.mInitState = INITIALIZED;	 +			// initialize singleton after constructing it so that it can reference other singletons which in turn depend on it, +			// thus breaking cyclic dependencies +			sData.mInstance->initSingleton();  +			return sData.mInstance; +		case INITIALIZED: +			return sData.mInstance; +		case DELETED:  			llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl; +			SingletonLifetimeManager::construct(); +			// same as first time construction +			sData.mInitState = INITIALIZED;	 +			sData.mInstance->initSingleton();  +			return sData.mInstance;  		} -		 -		if (!data.mSingletonInstance)  -		{ -			data.mInitState = CONSTRUCTING; -			data.mSingletonInstance = new DERIVED_TYPE();  -			data.mInitState = INITIALIZING; -			data.mSingletonInstance->initSingleton();  -			data.mInitState = INITIALIZED;	 -		} -		 -		return data.mSingletonInstance; + +		return NULL; +	} + +	static DERIVED_TYPE* getIfExists() +	{ +		return sData.mInstance;  	}  	// Reference version of getInstance() @@ -208,18 +182,31 @@ public:  	// Use this to avoid accessing singletons before the can safely be constructed  	static bool instanceExists()  	{ -		return getData().mInitState == INITIALIZED; +		return sData.mInitState == INITIALIZED;  	}  	// Has this singleton already been deleted?  	// Use this to avoid accessing singletons from a static object's destructor  	static bool destroyed()  	{ -		return getData().mInitState == DELETED; +		return sData.mInitState == DELETED;  	}  private: +  	virtual void initSingleton() {} + +	struct SingletonData +	{ +		// explicitly has a default constructor so that member variables are zero initialized in BSS +		// and only changed by singleton logic, not constructor running during startup +		EInitState		mInitState; +		DERIVED_TYPE*	mInstance; +	}; +	static SingletonData sData;  }; +template<typename T> +typename LLSingleton<T>::SingletonData LLSingleton<T>::sData; +  #endif diff --git a/indra/llcommon/llskiplist.h b/indra/llcommon/llskiplist.h deleted file mode 100755 index ed132381f9..0000000000 --- a/indra/llcommon/llskiplist.h +++ /dev/null @@ -1,517 +0,0 @@ -/**  - * @file llskiplist.h - * @brief skip list implementation - * - * $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$ - */ -#ifndef LL_LLSKIPLIST_H -#define LL_LLSKIPLIST_H - -#include "llrand.h" -#include "llrand.h" - -// NOTA BENE: Insert first needs to be < NOT <= -// Binary depth must be >= 2 -template <class DATA_TYPE, S32 BINARY_DEPTH = 10> -class LLSkipList -{ -public: -	typedef BOOL (*compare)(const DATA_TYPE& first, const DATA_TYPE& second); -	typedef compare insert_func; -	typedef compare equals_func; - -	void init(); - -	// basic constructor -	LLSkipList(); - -	// basic constructor including sorter -	LLSkipList(insert_func insert_first, equals_func equals); -	~LLSkipList(); - -	inline void setInsertFirst(insert_func insert_first); -	inline void setEquals(equals_func equals); - -	inline BOOL addData(const DATA_TYPE& data); -	inline BOOL checkData(const DATA_TYPE& data); - -	// returns number of items in the list -	inline S32 getLength() const; // NOT a constant time operation, traverses entire list! - -	inline BOOL moveData(const DATA_TYPE& data, LLSkipList *newlist); - -	inline BOOL removeData(const DATA_TYPE& data); - -	// remove all nodes from the list but do not delete data -	inline void removeAllNodes(); - -	// place mCurrentp on first node -	inline void resetList(); - -	// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -	inline DATA_TYPE getCurrentData(); - -	// same as getCurrentData() but a more intuitive name for the operation -	inline DATA_TYPE getNextData(); - -	// remove the Node at mCurentOperatingp -	// leave mCurrentp and mCurentOperatingp on the next entry -	inline void removeCurrentData(); - -	// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -	inline DATA_TYPE getFirstData(); - -	class LLSkipNode -	{ -	public: -		LLSkipNode() -		:	mData(0) -		{ -			S32 i; -			for (i = 0; i < BINARY_DEPTH; i++) -			{ -				mForward[i] = NULL; -			} -		} - -		LLSkipNode(DATA_TYPE data) -			: mData(data) -		{ -			S32 i; -			for (i = 0; i < BINARY_DEPTH; i++) -			{ -				mForward[i] = NULL; -			} -		} - -		~LLSkipNode() -		{ -		} - -		DATA_TYPE					mData; -		LLSkipNode					*mForward[BINARY_DEPTH]; - -	private: -		// Disallow copying of LLSkipNodes by not implementing these methods. -		LLSkipNode(const LLSkipNode &); -		LLSkipNode &operator=(const LLSkipNode &); -	}; - -	static BOOL defaultEquals(const DATA_TYPE& first, const DATA_TYPE& second) -	{ -		return first == second; -	} - -private: -	LLSkipNode					mHead; -	LLSkipNode					*mUpdate[BINARY_DEPTH]; -	LLSkipNode					*mCurrentp; -	LLSkipNode					*mCurrentOperatingp; -	S32							mLevel; -	insert_func mInsertFirst; -	equals_func mEquals; - -private: -	// Disallow copying of LLSkipNodes by not implementing these methods. -	LLSkipList(const LLSkipList &); -	LLSkipList &operator=(const LLSkipList &); -}; - - -/////////////////////// -// -// Implementation -// - - -// Binary depth must be >= 2 -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::init() -{ -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} -	mLevel = 1; -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - - -// basic constructor -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::LLSkipList() -:	mInsertFirst(NULL),  -	mEquals(defaultEquals) -{ -	init(); -} - -// basic constructor including sorter -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::LLSkipList(insert_func insert, -													   equals_func equals) -:	mInsertFirst(insert),  -	mEquals(equals) -{ -	init(); -} - -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline LLSkipList<DATA_TYPE, BINARY_DEPTH>::~LLSkipList() -{ -	removeAllNodes(); -} - -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::setInsertFirst(insert_func insert_first) -{ -	mInsertFirst = insert_first; -} - -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::setEquals(equals_func equals) -{ -	mEquals = equals; -} - -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::addData(const DATA_TYPE& data) -{ -	S32			level; -	LLSkipNode	*current = &mHead; -	LLSkipNode	*temp; -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mData, data))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mData < data)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	// now add the new node -	S32 newlevel; -	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) -	{ -		if (ll_frand() < 0.5f) -			break; -	} - -	LLSkipNode *snode = new LLSkipNode(data); - -	if (newlevel > mLevel) -	{ -		mHead.mForward[mLevel] = NULL; -		mUpdate[mLevel] = &mHead; -		mLevel = newlevel; -	} - -	for (level = 0; level < newlevel; level++) -	{ -		snode->mForward[level] = mUpdate[level]->mForward[level]; -		mUpdate[level]->mForward[level] = snode; -	} -	return TRUE; -} - -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::checkData(const DATA_TYPE& data) -{ -	S32			level; -	LLSkipNode	*current = &mHead; -	LLSkipNode	*temp; -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mData, data))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mData < data)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - - -	if (current) -	{ -		return mEquals(current->mData, data); -	} - -	return FALSE; -} - -// returns number of items in the list -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline S32 LLSkipList<DATA_TYPE, BINARY_DEPTH>::getLength() const -{ -	U32	length = 0; -	for (LLSkipNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0]) -	{ -		length++; -	} -	return length; -} - - -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::moveData(const DATA_TYPE& data, LLSkipList *newlist) -{ -	BOOL removed = removeData(data); -	BOOL added = newlist->addData(data); -	return removed && added; -} - - -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline BOOL LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeData(const DATA_TYPE& data) -{ -	S32			level; -	LLSkipNode	*current = &mHead; -	LLSkipNode	*temp; -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mData, data))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mData < data)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - - -	if (!current) -	{ -		// empty list or beyond the end! -		return FALSE; -	} - -	// is this the one we want? -	if (!mEquals(current->mData, data)) -	{ -		// nope! -		return FALSE; -	} -	else -	{ -		// do we need to fix current or currentop? -		if (current == mCurrentp) -		{ -			mCurrentp = current->mForward[0]; -		} - -		if (current == mCurrentOperatingp) -		{ -			mCurrentOperatingp = current->mForward[0]; -		} -		// yes it is!  change pointers as required -		for (level = 0; level < mLevel; level++) -		{ -			if (mUpdate[level]->mForward[level] != current) -			{ -				// cool, we've fixed all the pointers! -				break; -			} -			mUpdate[level]->mForward[level] = current->mForward[level]; -		} - -		// clean up cuurent -		delete current; - -		// clean up mHead -		while (  (mLevel > 1) -			   &&(!mHead.mForward[mLevel - 1])) -		{ -			mLevel--; -		} -	} -	return TRUE; -} - -// remove all nodes from the list but do not delete data -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeAllNodes() -{ -	LLSkipNode *temp; -	// reset mCurrentp -	mCurrentp = *(mHead.mForward); - -	while (mCurrentp) -	{ -		temp = mCurrentp->mForward[0]; -		delete mCurrentp; -		mCurrentp = temp; -	} - -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} - -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -// place mCurrentp on first node -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::resetList() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getCurrentData() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL;		// causes compile warning -		return (DATA_TYPE)0; 			// equivalent, but no warning -	} -} - -// same as getCurrentData() but a more intuitive name for the operation -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getNextData() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL;		// causes compile warning -		return (DATA_TYPE)0; 			// equivalent, but no warning -	} -} - -// remove the Node at mCurentOperatingp -// leave mCurrentp and mCurentOperatingp on the next entry -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipList<DATA_TYPE, BINARY_DEPTH>::removeCurrentData() -{ -	if (mCurrentOperatingp) -	{ -		removeData(mCurrentOperatingp->mData); -	} -} - -// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -template <class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE LLSkipList<DATA_TYPE, BINARY_DEPTH>::getFirstData() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		//return NULL;		// causes compile warning -		return (DATA_TYPE)0; 			// equivalent, but no warning -	} -} - - -#endif diff --git a/indra/llcommon/llskipmap.h b/indra/llcommon/llskipmap.h deleted file mode 100755 index 49ff2928d1..0000000000 --- a/indra/llcommon/llskipmap.h +++ /dev/null @@ -1,1022 +0,0 @@ -/**  - * @file llskipmap.h - * @brief Associative container based on the skiplist algorithm. - * - * $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$ - */ - -#ifndef LL_LLSKIPMAP_H -#define LL_LLSKIPMAP_H - -#include "llerror.h" - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH = 8>  -class LLSkipMap -{ -public: -	// basic constructor -	LLSkipMap(); - -	// basic constructor including sorter -	LLSkipMap(BOOL	(*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second),  -			   BOOL	(*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second)); - -	~LLSkipMap(); - -	void setInsertFirst(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second)); -	void setEquals(BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second)); - -	DATA_TYPE &addData(const INDEX_TYPE &index, DATA_TYPE datap); -	DATA_TYPE &addData(const INDEX_TYPE &index); -	DATA_TYPE &getData(const INDEX_TYPE &index); -	DATA_TYPE &operator[](const INDEX_TYPE &index); - -	// If index present, returns data. -	// If index not present, adds <index,NULL> and returns NULL. -	DATA_TYPE &getData(const INDEX_TYPE &index, BOOL &b_new_entry); - -	// Returns TRUE if data present in map. -	BOOL checkData(const INDEX_TYPE &index); - -	// Returns TRUE if key is present in map. This is useful if you -	// are potentially storing NULL pointers in the map -	BOOL checkKey(const INDEX_TYPE &index); - -	// If there, returns the data. -	// If not, returns NULL. -	// Never adds entries to the map. -	DATA_TYPE getIfThere(const INDEX_TYPE &index); - -	INDEX_TYPE reverseLookup(const DATA_TYPE datap); - -	// returns number of items in the list -	S32 getLength(); // WARNING!  getLength is O(n), not O(1)! - -	BOOL removeData(const INDEX_TYPE &index); - -	// remove all nodes from the list but do not delete data -	void removeAllData(); - -	// place mCurrentp on first node -	void resetList(); - -	// return the data currently pointed to -	DATA_TYPE	getCurrentDataWithoutIncrement(); - -	// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -	DATA_TYPE	getCurrentData(); - -	// same as getCurrentData() but a more intuitive name for the operation -	DATA_TYPE	getNextData(); - -	INDEX_TYPE	getNextKey(); - -	// return the key currently pointed to -	INDEX_TYPE	getCurrentKeyWithoutIncrement(); - -	// The internal iterator is at the end of the list. -	BOOL		notDone() const; - -	// remove the Node at mCurentOperatingp -	// leave mCurrentp and mCurentOperatingp on the next entry -	void removeCurrentData(); - -	void deleteCurrentData(); - -	// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -	DATA_TYPE	getFirstData(); - -	INDEX_TYPE	getFirstKey(); - -	class LLSkipMapNode -	{ -	public: -		LLSkipMapNode() -		{ -			S32 i; -			for (i = 0; i < BINARY_DEPTH; i++) -			{ -				mForward[i] = NULL; -			} - -			U8  *zero = (U8 *)&mIndex; - -			for (i = 0; i < (S32)sizeof(INDEX_TYPE); i++) -			{ -				*(zero + i) = 0; -			} - -			zero = (U8 *)&mData; - -			for (i = 0; i < (S32)sizeof(DATA_TYPE); i++) -			{ -				*(zero + i) = 0; -			} -		} - -		LLSkipMapNode(const INDEX_TYPE &index) -		:	mIndex(index) -		{ - -			S32 i; -			for (i = 0; i < BINARY_DEPTH; i++) -			{ -				mForward[i] = NULL; -			} - -			U8 *zero = (U8 *)&mData; - -			for (i = 0; i < (S32)sizeof(DATA_TYPE); i++) -			{ -				*(zero + i) = 0; -			} -		} - -		LLSkipMapNode(const INDEX_TYPE &index, DATA_TYPE datap) -		:	mIndex(index) -		{ - -			S32 i; -			for (i = 0; i < BINARY_DEPTH; i++) -			{ -				mForward[i] = NULL; -			} - -			mData = datap; -		} - -		~LLSkipMapNode() -		{ -		} - - -		INDEX_TYPE					mIndex; -		DATA_TYPE					mData; -		LLSkipMapNode				*mForward[BINARY_DEPTH]; - -	private: -		// Disallow copying of LLSkipMapNodes by not implementing these methods. -		LLSkipMapNode(const LLSkipMapNode &); -		LLSkipMapNode &operator=(const LLSkipMapNode &rhs); -	}; - -	static BOOL	defaultEquals(const INDEX_TYPE &first, const INDEX_TYPE &second) -	{ -		return first == second; -	} - -private: -	// don't generate implicit copy constructor or copy assignment -	LLSkipMap(const LLSkipMap &); -	LLSkipMap &operator=(const LLSkipMap &); - -private: -	LLSkipMapNode				mHead; -	LLSkipMapNode				*mUpdate[BINARY_DEPTH]; -	LLSkipMapNode				*mCurrentp; -	LLSkipMapNode				*mCurrentOperatingp; -	S32							mLevel; -	BOOL						(*mInsertFirst)(const INDEX_TYPE &first, const INDEX_TYPE &second); -	BOOL						(*mEquals)(const INDEX_TYPE &first, const INDEX_TYPE &second); -	S32							mNumberOfSteps; -}; - -////////////////////////////////////////////////// -// -// LLSkipMap implementation -// - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::LLSkipMap() -	:	mInsertFirst(NULL), -		mEquals(defaultEquals) -{ -	// Skipmaps must have binary depth of at least 2 -	cassert(BINARY_DEPTH >= 2); - -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mUpdate[i] = NULL; -	} -	mLevel = 1; -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::LLSkipMap(BOOL	(*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second),  -			   BOOL	(*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second))  -	:	mInsertFirst(insert_first), -		mEquals(equals) -{ -	// Skipmaps must have binary depth of at least 2 -	cassert(BINARY_DEPTH >= 2); - -	mLevel = 1; -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::~LLSkipMap() -{ -	removeAllData(); -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::setInsertFirst(BOOL (*insert_first)(const INDEX_TYPE &first, const INDEX_TYPE &second)) -{ -	mInsertFirst = insert_first; -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::setEquals(BOOL (*equals)(const INDEX_TYPE &first, const INDEX_TYPE &second)) -{ -	mEquals = equals; -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::addData(const INDEX_TYPE &index, DATA_TYPE datap) -{ -	S32			level; -	LLSkipMapNode	*current = &mHead; -	LLSkipMapNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	// replace the existing data if a node is already there -	if (  (current) -		&&(mEquals(current->mIndex, index))) -	{ -		current->mData = datap; -		return current->mData; -	} - -	// now add the new node -	S32 newlevel; -	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) -	{ -		if (rand() & 1) -		{ -			break; -		} -	} - -	LLSkipMapNode *snode = new LLSkipMapNode(index, datap); - -	if (newlevel > mLevel) -	{ -		mHead.mForward[mLevel] = NULL; -		mUpdate[mLevel] = &mHead; -		mLevel = newlevel; -	} - -	for (level = 0; level < newlevel; level++) -	{ -		snode->mForward[level] = mUpdate[level]->mForward[level]; -		mUpdate[level]->mForward[level] = snode; -	} -	return snode->mData; -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::addData(const INDEX_TYPE &index) -{ -	S32			level; -	LLSkipMapNode	*current = &mHead; -	LLSkipMapNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	// now add the new node -	S32 newlevel; -	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) -	{ -		if (rand() & 1) -			break; -	} - -	LLSkipMapNode *snode = new LLSkipMapNode(index); - -	if (newlevel > mLevel) -	{ -		mHead.mForward[mLevel] = NULL; -		mUpdate[mLevel] = &mHead; -		mLevel = newlevel; -	} - -	for (level = 0; level < newlevel; level++) -	{ -		snode->mForward[level] = mUpdate[level]->mForward[level]; -		mUpdate[level]->mForward[level] = snode; -	} -	return snode->mData; -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getData(const INDEX_TYPE &index) -{ -	S32			level; -	LLSkipMapNode	*current = &mHead; -	LLSkipMapNode	*temp; - -	mNumberOfSteps = 0; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; -	mNumberOfSteps++; - -	if (  (current) -		&&(mEquals(current->mIndex, index))) -	{ -		 -		return current->mData; -	} -	 -	// now add the new node -	S32 newlevel; -	for (newlevel = 1; newlevel <= mLevel && newlevel < BINARY_DEPTH; newlevel++) -	{ -		if (rand() & 1) -			break; -	} - -	LLSkipMapNode *snode = new LLSkipMapNode(index); - -	if (newlevel > mLevel) -	{ -		mHead.mForward[mLevel] = NULL; -		mUpdate[mLevel] = &mHead; -		mLevel = newlevel; -	} - -	for (level = 0; level < newlevel; level++) -	{ -		snode->mForward[level] = mUpdate[level]->mForward[level]; -		mUpdate[level]->mForward[level] = snode; -	} -	 -	return snode->mData; -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::operator[](const INDEX_TYPE &index) -{ -	 -	return getData(index); -} - -// If index present, returns data. -// If index not present, adds <index,NULL> and returns NULL. -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE &LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getData(const INDEX_TYPE &index, BOOL &b_new_entry) -{ -	S32			level; -	LLSkipMapNode	*current = &mHead; -	LLSkipMapNode	*temp; - -	mNumberOfSteps = 0; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	mNumberOfSteps++; -	current = *current->mForward; - -	if (  (current) -		&&(mEquals(current->mIndex, index))) -	{ -		 -		return current->mData; -	} -	b_new_entry = TRUE; -	addData(index); -	 -	return current->mData; -} - -// Returns TRUE if data present in map. -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::checkData(const INDEX_TYPE &index) -{ -	S32			level; -	LLSkipMapNode	*current = &mHead; -	LLSkipMapNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (current) -	{ -		// Gets rid of some compiler ambiguity for the LLPointer<> templated class. -		if (current->mData) -		{ -			return mEquals(current->mIndex, index); -		} -	} - -	return FALSE; -} - -// Returns TRUE if key is present in map. This is useful if you -// are potentially storing NULL pointers in the map -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::checkKey(const INDEX_TYPE &index) -{ -	S32			level; -	LLSkipMapNode	*current = &mHead; -	LLSkipMapNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (current) -	{ -		return mEquals(current->mIndex, index); -	} - -	return FALSE; -} - -// If there, returns the data. -// If not, returns NULL. -// Never adds entries to the map. -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getIfThere(const INDEX_TYPE &index) -{ -	S32			level; -	LLSkipMapNode	*current = &mHead; -	LLSkipMapNode	*temp; - -	mNumberOfSteps = 0; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -				mNumberOfSteps++; -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	mNumberOfSteps++; -	current = *current->mForward; - -	if (current) -	{ -		if (mEquals(current->mIndex, index)) -		{ -			return current->mData; -		} -	} - -	// Avoid Linux compiler warning on returning NULL. -	return DATA_TYPE(); -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::reverseLookup(const DATA_TYPE datap) -{ -	LLSkipMapNode	*current = &mHead; - -	while (current) -	{ -		if (datap == current->mData) -		{ -			 -			return current->mIndex; -		} -		current = *current->mForward; -	} - -	// not found! return NULL -	return INDEX_TYPE(); -} - -// returns number of items in the list -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline S32 LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getLength() -{ -	U32	length = 0; -	for (LLSkipMapNode* temp = *(mHead.mForward); temp != NULL; temp = temp->mForward[0]) -	{ -		length++; -	} -	 -	return length; -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeData(const INDEX_TYPE &index) -{ -	S32			level; -	LLSkipMapNode	*current = &mHead; -	LLSkipMapNode	*temp; - -	// find the pointer one in front of the one we want -	if (mInsertFirst) -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(mInsertFirst(temp->mIndex, index))) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	else -	{ -		for (level = mLevel - 1; level >= 0; level--) -		{ -			temp = *(current->mForward + level); -			while (  (temp) -				   &&(temp->mIndex < index)) -			{ -				current = temp; -				temp = *(current->mForward + level); -			} -			*(mUpdate + level) = current; -		} -	} -	 -	// we're now just in front of where we want to be . . . take one step forward -	current = *current->mForward; - -	if (!current) -	{ -		// empty list or beyond the end! -		 -		return FALSE; -	} - -	// is this the one we want? -	if (!mEquals(current->mIndex, index)) -	{ -		// nope! -		 -		return FALSE; -	} -	else -	{ -		// do we need to fix current or currentop? -		if (current == mCurrentp) -		{ -			mCurrentp = *current->mForward; -		} - -		if (current == mCurrentOperatingp) -		{ -			mCurrentOperatingp = *current->mForward; -		} -		// yes it is!  change pointers as required -		for (level = 0; level < mLevel; level++) -		{ -			if (*((*(mUpdate + level))->mForward + level) != current) -			{ -				// cool, we've fixed all the pointers! -				break; -			} -			*((*(mUpdate + level))->mForward + level) = *(current->mForward + level); -		} - -		delete current; - -		// clean up mHead -		while (  (mLevel > 1) -			   &&(!*(mHead.mForward + mLevel - 1))) -		{ -			mLevel--; -		} -	} -	 -	return TRUE; -} - - -// remove all nodes from the list but do not delete data -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeAllData() -{ -	LLSkipMapNode *temp; -	// reset mCurrentp -	mCurrentp = *(mHead.mForward); - -	while (mCurrentp) -	{ -		temp = mCurrentp->mForward[0]; -		delete mCurrentp; -		mCurrentp = temp; -	} - -	S32 i; -	for (i = 0; i < BINARY_DEPTH; i++) -	{ -		mHead.mForward[i] = NULL; -		mUpdate[i] = NULL; -	} - -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - - -// place mCurrentp on first node -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::resetList() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -} - - -// return the data currently pointed to -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentDataWithoutIncrement() -{ -	if (mCurrentOperatingp) -	{ -		return mCurrentOperatingp->mData; -	} -	else -	{ -		return DATA_TYPE(); -	} -} - -// return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentData() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		// Basic types, like int, have default constructors that initialize -		// them to zero.  g++ 2.95 supports this.  "int()" is zero. -		// This also is nice for LLUUID() -		return DATA_TYPE(); -	} -} - -// same as getCurrentData() but a more intuitive name for the operation -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getNextData() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		// Basic types, like int, have default constructors that initialize -		// them to zero.  g++ 2.95 supports this.  "int()" is zero. -		// This also is nice for LLUUID() -		return DATA_TYPE(); -	} -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getNextKey() -{ -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mIndex; -	} -	else -	{ -		return mHead.mIndex; -	} -} - -// return the key currently pointed to -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getCurrentKeyWithoutIncrement() -{ -	if (mCurrentOperatingp) -	{ -		return mCurrentOperatingp->mIndex; -	} -	else -	{ -		// See comment for getNextData() -		return INDEX_TYPE(); -	} -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline BOOL LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::notDone() const -{ -	if (mCurrentOperatingp) -	{ -		return TRUE; -	} -	else -	{ -		return FALSE; -	} -} - - -// remove the Node at mCurentOperatingp -// leave mCurrentp and mCurentOperatingp on the next entry -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::removeCurrentData() -{ -	if (mCurrentOperatingp) -	{ -		removeData(mCurrentOperatingp->mIndex); -	} -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline void LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::deleteCurrentData() -{ -	if (mCurrentOperatingp) -	{ -		deleteData(mCurrentOperatingp->mIndex); -	} -} - -// reset the list and return the data currently pointed to, set mCurentOperatingp to that node and bump mCurrentp -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline DATA_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getFirstData() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mData; -	} -	else -	{ -		// See comment for getNextData() -		return DATA_TYPE(); -	} -} - -template <class INDEX_TYPE, class DATA_TYPE, S32 BINARY_DEPTH> -inline INDEX_TYPE LLSkipMap<INDEX_TYPE, DATA_TYPE, BINARY_DEPTH>::getFirstKey() -{ -	mCurrentp = *(mHead.mForward); -	mCurrentOperatingp = *(mHead.mForward); -	if (mCurrentp) -	{ -		mCurrentOperatingp = mCurrentp; -		mCurrentp = mCurrentp->mForward[0]; -		return mCurrentOperatingp->mIndex; -	} -	else -	{ -		return mHead.mIndex; -	} -} - -#endif diff --git a/indra/llcommon/llsortedvector.h b/indra/llcommon/llsortedvector.h deleted file mode 100755 index 391b82ee44..0000000000 --- a/indra/llcommon/llsortedvector.h +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @file   llsortedvector.h - * @author Nat Goodspeed - * @date   2012-04-08 - * @brief  LLSortedVector class wraps a vector that we maintain in sorted - *         order so we can perform binary-search lookups. - *  - * $LicenseInfo:firstyear=2012&license=viewerlgpl$ - * Copyright (c) 2012, Linden Research, Inc. - * $/LicenseInfo$ - */ - -#if ! defined(LL_LLSORTEDVECTOR_H) -#define LL_LLSORTEDVECTOR_H - -#include <vector> -#include <algorithm> - -/** - * LLSortedVector contains a std::vector<std::pair> that we keep sorted on the - * first of the pair. This makes insertion somewhat more expensive than simple - * std::vector::push_back(), but allows us to use binary search for lookups. - * It's intended for small aggregates where lookup is far more performance- - * critical than insertion; in such cases a binary search on a small, sorted - * std::vector can be more performant than a std::map lookup. - */ -template <typename KEY, typename VALUE> -class LLSortedVector -{ -public: -    typedef LLSortedVector<KEY, VALUE> self; -    typedef KEY key_type; -    typedef VALUE mapped_type; -    typedef std::pair<key_type, mapped_type> value_type; -    typedef std::vector<value_type> PairVector; -    typedef typename PairVector::iterator iterator; -    typedef typename PairVector::const_iterator const_iterator; - -    /// Empty -    LLSortedVector() {} - -    /// Fixed initial size -    LLSortedVector(std::size_t size): -        mVector(size) -    {} - -    /// Bulk load -    template <typename ITER> -    LLSortedVector(ITER begin, ITER end): -        mVector(begin, end) -    { -        // Allow caller to dump in a bunch of (pairs convertible to) -        // value_type if desired, but make sure we sort afterwards. -        std::sort(mVector.begin(), mVector.end()); -    } - -    /// insert(key, value) -    std::pair<iterator, bool> insert(const key_type& key, const mapped_type& value) -    { -        return insert(value_type(key, value)); -    } - -    /// insert(value_type) -    std::pair<iterator, bool> insert(const value_type& pair) -    { -        typedef std::pair<iterator, bool> iterbool; -        iterator found = std::lower_bound(mVector.begin(), mVector.end(), pair, -                                          less<value_type>()); -        // have to check for end() before it's even valid to dereference -        if (found == mVector.end()) -        { -            std::size_t index(mVector.size()); -            mVector.push_back(pair); -            // don't forget that push_back() invalidates 'found' -            return iterbool(mVector.begin() + index, true); -        } -        if (found->first == pair.first) -        { -            return iterbool(found, false); -        } -        // remember that insert() invalidates 'found' -- save index -        std::size_t index(found - mVector.begin()); -        mVector.insert(found, pair); -        // okay, convert from index back to iterator -        return iterbool(mVector.begin() + index, true); -    } - -    iterator begin() { return mVector.begin(); } -    iterator end()   { return mVector.end(); } -    const_iterator begin() const { return mVector.begin(); } -    const_iterator end()   const { return mVector.end(); } - -    bool empty() const { return mVector.empty(); } -    std::size_t size() const { return mVector.size(); } - -    /// find -    iterator find(const key_type& key) -    { -        iterator found = std::lower_bound(mVector.begin(), mVector.end(), -                                          value_type(key, mapped_type()), -                                          less<value_type>()); -        if (found == mVector.end() || found->first != key) -            return mVector.end(); -        return found; -    } - -    const_iterator find(const key_type& key) const -    { -        return const_cast<self*>(this)->find(key); -    } - -private: -    // Define our own 'less' comparator so we can specialize without messing -    // with std::less. -    template <typename T> -    struct less: public std::less<T> {}; - -    // Specialize 'less' for an LLSortedVector::value_type involving -    // std::type_info*. This is one of LLSortedVector's foremost use cases. We -    // specialize 'less' rather than just defining a specific comparator -    // because LLSortedVector should be usable for other key_types as well. -    template <typename T> -    struct less< std::pair<std::type_info*, T> >: -        public std::binary_function<std::pair<std::type_info*, T>, -                                    std::pair<std::type_info*, T>, -                                    bool> -    { -        bool operator()(const std::pair<std::type_info*, T>& lhs, -                        const std::pair<std::type_info*, T>& rhs) const -        { -            return lhs.first->before(*rhs.first); -        } -    }; - -    // Same as above, but with const std::type_info*. -    template <typename T> -    struct less< std::pair<const std::type_info*, T> >: -        public std::binary_function<std::pair<const std::type_info*, T>, -                                    std::pair<const std::type_info*, T>, -                                    bool> -    { -        bool operator()(const std::pair<const std::type_info*, T>& lhs, -                        const std::pair<const std::type_info*, T>& rhs) const -        { -            return lhs.first->before(*rhs.first); -        } -    }; - -    PairVector mVector; -}; - -#endif /* ! defined(LL_LLSORTEDVECTOR_H) */ diff --git a/indra/llcommon/llstack.h b/indra/llcommon/llstack.h deleted file mode 100755 index 315de6ba2d..0000000000 --- a/indra/llcommon/llstack.h +++ /dev/null @@ -1,48 +0,0 @@ -/**  - * @file llstack.h - * @brief LLStack template class - * - * $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$ - */ - -#ifndef LL_LLSTACK_H -#define LL_LLSTACK_H - -#include "linked_lists.h" - -template <class DATA_TYPE> class LLStack -{ -private: -	LLLinkedList<DATA_TYPE> mStack; - -public: -	LLStack()	{} -	~LLStack()	{} - -	void push(DATA_TYPE *data)	{ mStack.addData(data); } -	DATA_TYPE *pop()			{ DATA_TYPE *tempp = mStack.getFirstData(); mStack.removeCurrentData(); return tempp; } -	void deleteAllData()		{ mStack.deleteAllData(); } -	void removeAllNodes()		{ mStack.removeAllNodes(); } -}; - -#endif - diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp index ccd7ef91c2..e0e9056380 100755 --- a/indra/llcommon/llstacktrace.cpp +++ b/indra/llcommon/llstacktrace.cpp @@ -32,7 +32,7 @@  #include <iostream>  #include <sstream> -#include "windows.h" +#include "llwin32headerslean.h"  #include "Dbghelp.h"  typedef USHORT NTAPI RtlCaptureStackBackTrace_Function( diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp deleted file mode 100755 index 3678c8e1c1..0000000000 --- a/indra/llcommon/llstat.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/**  - * @file llstat.cpp - * - * $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 "linden_common.h" - -#include "llstat.h" -#include "lllivefile.h" -#include "llerrorcontrol.h" -#include "llframetimer.h" -#include "timing.h" -#include "llsd.h" -#include "llsdserialize.h" -#include "llstl.h" -#include "u64.h" - - -// statics -//------------------------------------------------------------------------ -LLTimer LLStat::sTimer; -LLFrameTimer LLStat::sFrameTimer; - -void LLStat::reset() -{ -	mNumValues = 0; -	mLastValue = 0.f; -	delete[] mBins; -	mBins      = new ValueEntry[mNumBins]; -	mCurBin = mNumBins-1; -	mNextBin = 0; -} - -LLStat::LLStat(std::string name, S32 num_bins, BOOL use_frame_timer) -:	mUseFrameTimer(use_frame_timer), -	mNumBins(num_bins), -	mName(name), -	mBins(NULL) -{ -	llassert(mNumBins > 0); -	mLastTime  = 0.f; - -	reset(); - -	if (!mName.empty()) -	{ -		stat_map_t::iterator iter = getStatList().find(mName); -		if (iter != getStatList().end()) -			llwarns << "LLStat with duplicate name: " << mName << llendl; -		getStatList().insert(std::make_pair(mName, this)); -	} -} - -LLStat::stat_map_t& LLStat::getStatList() -{ -	static LLStat::stat_map_t stat_list; -	return stat_list; -} - - -LLStat::~LLStat() -{ -	delete[] mBins; - -	if (!mName.empty()) -	{ -		// handle multiple entries with the same name -		stat_map_t::iterator iter = getStatList().find(mName); -		while (iter != getStatList().end() && iter->second != this) -			++iter; -		getStatList().erase(iter); -	} -} - -void LLStat::start() -{ -	if (mUseFrameTimer) -	{ -		mBins[mNextBin].mBeginTime = sFrameTimer.getElapsedSeconds(); -	} -	else -	{ -		mBins[mNextBin].mBeginTime = sTimer.getElapsedTimeF64(); -	} -} - -void LLStat::addValue(const F32 value) -{ -	if (mNumValues < mNumBins) -	{ -		mNumValues++; -	} - -	// Increment the bin counters. -	mCurBin++; -	if (mCurBin >= mNumBins) -	{ -		mCurBin = 0; -	} -	mNextBin++; -	if (mNextBin >= mNumBins) -	{ -		mNextBin = 0; -	} - -	mBins[mCurBin].mValue = value; -	if (mUseFrameTimer) -	{ -		mBins[mCurBin].mTime = sFrameTimer.getElapsedSeconds(); -	} -	else -	{ -		mBins[mCurBin].mTime = sTimer.getElapsedTimeF64(); -	} -	mBins[mCurBin].mDT = (F32)(mBins[mCurBin].mTime - mBins[mCurBin].mBeginTime); - -	//this value is used to prime the min/max calls -	mLastTime = mBins[mCurBin].mTime; -	mLastValue = value; - -	// Set the begin time for the next stat segment. -	mBins[mNextBin].mBeginTime = mBins[mCurBin].mTime; -	mBins[mNextBin].mTime = mBins[mCurBin].mTime; -	mBins[mNextBin].mDT = 0.f; -} - - -F32 LLStat::getMax() const -{ -	S32 i; -	F32 current_max = mLastValue; -	if (mNumBins == 0) -	{ -		current_max = 0.f; -	} -	else -	{ -		for (i = 0; (i < mNumBins) && (i < mNumValues); i++) -		{ -			// Skip the bin we're currently filling. -			if (i == mNextBin) -			{ -				continue; -			} -			if (mBins[i].mValue > current_max) -			{ -				current_max = mBins[i].mValue; -			} -		} -	} -	return current_max; -} - -F32 LLStat::getMean() const -{ -	S32 i; -	F32 current_mean = 0.f; -	S32 samples = 0; -	for (i = 0; (i < mNumBins) && (i < mNumValues); i++) -	{ -		// Skip the bin we're currently filling. -		if (i == mNextBin) -		{ -			continue; -		} -		current_mean += mBins[i].mValue; -		samples++; -	} - -	// There will be a wrap error at 2^32. :) -	if (samples != 0) -	{ -		current_mean /= samples; -	} -	else -	{ -		current_mean = 0.f; -	} -	return current_mean; -} - -F32 LLStat::getMin() const -{ -	S32 i; -	F32 current_min = mLastValue; - -	if (mNumBins == 0) -	{ -		current_min = 0.f; -	} -	else -	{ -		for (i = 0; (i < mNumBins) && (i < mNumValues); i++) -		{ -			// Skip the bin we're currently filling. -			if (i == mNextBin) -			{ -				continue; -			} -			if (mBins[i].mValue < current_min) -			{ -				current_min = mBins[i].mValue; -			} -		} -	} -	return current_min; -} - -F32 LLStat::getPrev(S32 age) const -{ -	S32 bin; -	bin = mCurBin - age; - -	while (bin < 0) -	{ -		bin += mNumBins; -	} - -	if (bin == mNextBin) -	{ -		// Bogus for bin we're currently working on. -		return 0.f; -	} -	return mBins[bin].mValue; -} - -F32 LLStat::getPrevPerSec(S32 age) const -{ -	S32 bin; -	bin = mCurBin - age; - -	while (bin < 0) -	{ -		bin += mNumBins; -	} - -	if (bin == mNextBin) -	{ -		// Bogus for bin we're currently working on. -		return 0.f; -	} -	return mBins[bin].mValue / mBins[bin].mDT; -} - -F32 LLStat::getCurrent() const -{ -	return mBins[mCurBin].mValue; -} - -F32 LLStat::getCurrentPerSec() const -{ -	return mBins[mCurBin].mValue / mBins[mCurBin].mDT; -} - -F32 LLStat::getMeanPerSec() const -{ -	S32 i; -	F32 value = 0.f; -	F32 dt    = 0.f; - -	for (i = 0; (i < mNumBins) && (i < mNumValues); i++) -	{ -		// Skip the bin we're currently filling. -		if (i == mNextBin) -		{ -			continue; -		} -		value += mBins[i].mValue; -		dt    += mBins[i].mDT; -	} - -	if (dt > 0.f) -	{ -		return value/dt; -	} -	else -	{ -		return 0.f; -	} -} - -F32 LLStat::getMeanDuration() const -{ -	F32 dur = 0.0f; -	S32 count = 0; -	for (S32 i=0; (i < mNumBins) && (i < mNumValues); i++) -	{ -		if (i == mNextBin) -		{ -			continue; -		} -		dur += mBins[i].mDT; -		count++; -	} - -	if (count > 0) -	{ -		dur /= F32(count); -		return dur; -	} -	else -	{ -		return 0.f; -	} -} - -F32 LLStat::getMaxPerSec() const -{ -	F32 value; - -	if (mNextBin != 0) -	{ -		value = mBins[0].mValue/mBins[0].mDT; -	} -	else if (mNumValues > 0) -	{ -		value = mBins[1].mValue/mBins[1].mDT; -	} -	else -	{ -		value = 0.f; -	} - -	for (S32 i = 0; (i < mNumBins) && (i < mNumValues); i++) -	{ -		// Skip the bin we're currently filling. -		if (i == mNextBin) -		{ -			continue; -		} -		value = llmax(value, mBins[i].mValue/mBins[i].mDT); -	} -	return value; -} - -F32 LLStat::getMinPerSec() const -{ -	S32 i; -	F32 value; -	 -	if (mNextBin != 0) -	{ -		value = mBins[0].mValue/mBins[0].mDT; -	} -	else if (mNumValues > 0) -	{ -		value = mBins[1].mValue/mBins[0].mDT; -	} -	else -	{ -		value = 0.f; -	} - -	for (i = 0; (i < mNumBins) && (i < mNumValues); i++) -	{ -		// Skip the bin we're currently filling. -		if (i == mNextBin) -		{ -			continue; -		} -		value = llmin(value, mBins[i].mValue/mBins[i].mDT); -	} -	return value; -} - -U32 LLStat::getNumValues() const -{ -	return mNumValues; -} - -S32 LLStat::getNumBins() const -{ -	return mNumBins; -} - -S32 LLStat::getNextBin() const -{ -	return mNextBin; -} - -F64 LLStat::getLastTime() const -{ -	return mLastTime; -} diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h deleted file mode 100755 index 38377a010b..0000000000 --- a/indra/llcommon/llstat.h +++ /dev/null @@ -1,116 +0,0 @@ -/**  - * @file llstat.h - * @brief Runtime statistics accumulation. - * - * $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$ - */ - -#ifndef LL_LLSTAT_H -#define LL_LLSTAT_H - -#include <map> - -#include "lltimer.h" -#include "llframetimer.h" - -class	LLSD; - -// ---------------------------------------------------------------------------- -class LL_COMMON_API LLStat -{ -private: -	typedef std::multimap<std::string, LLStat*> stat_map_t; - -	static stat_map_t& getStatList(); - -public: -	LLStat(std::string name = std::string(), S32 num_bins = 32, BOOL use_frame_timer = FALSE); -	~LLStat(); - -	void start();	// Start the timer for the current "frame", otherwise uses the time tracked from -					// the last addValue -	void reset(); -	void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT. -	void addValue(const S32 value) { addValue((F32)value); } -	void addValue(const U32 value) { addValue((F32)value); } - -	S32 getNextBin() const; -	 -	F32 getPrev(S32 age) const;				// Age is how many "addValues" previously - zero is current -	F32 getPrevPerSec(S32 age) const;		// Age is how many "addValues" previously - zero is current -	F32 getCurrent() const; -	F32 getCurrentPerSec() const; -	 -	F32 getMin() const; -	F32 getMinPerSec() const; -	F32 getMean() const; -	F32 getMeanPerSec() const; -	F32 getMeanDuration() const; -	F32 getMax() const; -	F32 getMaxPerSec() const; - -	U32 getNumValues() const; -	S32 getNumBins() const; - -	F64 getLastTime() const; -private: -	BOOL mUseFrameTimer; -	U32 mNumValues; -	U32 mNumBins; -	F32 mLastValue; -	F64 mLastTime; - -	struct ValueEntry -	{ -		ValueEntry() -		:	mValue(0.f), -			mBeginTime(0.0), -			mTime(0.0), -			mDT(0.f) -		{} -		F32 mValue; -		F64 mBeginTime; -		F64 mTime; -		F32 mDT; -	}; -	ValueEntry* mBins; -	S32 mCurBin; -	S32 mNextBin; -	 -	std::string mName; - -	static LLTimer sTimer; -	static LLFrameTimer sFrameTimer; -	 -public: -	static LLStat* getStat(const std::string& name) -	{ -		// return the first stat that matches 'name' -		stat_map_t::iterator iter = getStatList().find(name); -		if (iter != getStatList().end()) -			return iter->second; -		else -			return NULL; -	} -}; -	 -#endif // LL_STAT_ diff --git a/indra/llcommon/llstatenums.h b/indra/llcommon/llstatenums.h index 81c4085d16..ab9b6709e8 100755 --- a/indra/llcommon/llstatenums.h +++ b/indra/llcommon/llstatenums.h @@ -26,7 +26,7 @@  #ifndef LL_LLSTATENUMS_H  #define LL_LLSTATENUMS_H -enum +enum ESimStatID  {  	LL_SIM_STAT_TIME_DILATION         =  0,  	LL_SIM_STAT_FPS                   =  1, diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index d3941e1bc9..424138dad1 100755 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -31,6 +31,7 @@  #include <algorithm>  #include <map>  #include <vector> +#include <list>  #include <set>  #include <deque>  #include <typeinfo> diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 22c8681983..66c416bfdd 100755 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -28,11 +28,10 @@  #include "llstring.h"  #include "llerror.h" +#include "llfasttimer.h"  #if LL_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> +#include "llwin32headerslean.h"  #include <winnls.h> // for WideCharToMultiByte  #endif diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index f9702868c8..17893c1910 100755 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -31,8 +31,9 @@  #include <cstdio>  #include <locale>  #include <iomanip> +#include <algorithm>  #include "llsd.h" -#include "llfasttimer.h" +#include "llformat.h"  #if LL_LINUX || LL_SOLARIS  #include <wctype.h> diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 57a6de9060..95bbcbc816 100755 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -42,6 +42,7 @@  #include "llprocessor.h"  #include "llerrorcontrol.h"  #include "llevents.h" +#include "llformat.h"  #include "lltimer.h"  #include "llsdserialize.h"  #include "llsdutil.h" @@ -58,9 +59,7 @@  using namespace llsd;  #if LL_WINDOWS -#	define WIN32_LEAN_AND_MEAN -#	include <winsock2.h> -#	include <windows.h> +#	include "llwin32headerslean.h"  #   include <psapi.h>               // GetPerformanceInfo() et al.  #elif LL_DARWIN  #	include <errno.h> diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 1d56a52c32..118568d5ef 100755 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -29,8 +29,11 @@  #include "apr_portable.h"  #include "llthread.h" +#include "llmutex.h"  #include "lltimer.h" +#include "lltrace.h" +#include "lltracethreadrecorder.h"  #if LL_LINUX || LL_SOLARIS  #include <sched.h> @@ -56,12 +59,17 @@  //   //---------------------------------------------------------------------------- -#if !LL_DARWIN -U32 ll_thread_local sThreadID = 0; +#if LL_DARWIN +// statically allocated thread local storage not supported in Darwin executable formats +#elif LL_WINDOWS +U32 __declspec(thread) sThreadID = 0; +#elif LL_LINUX +U32 __thread sThreadID = 0;  #endif   U32 LLThread::sIDIter = 0; +  LL_COMMON_API void assert_main_thread()  {  	static U32 s_thread_id = LLThread::currentID(); @@ -85,6 +93,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap  {  	LLThread *threadp = (LLThread *)datap; +	LLTrace::ThreadRecorder* thread_recorder = new LLTrace::SlaveThreadRecorder(LLTrace::getUIThreadRecorder()); +  #if !LL_DARWIN  	sThreadID = threadp->mID;  #endif @@ -97,16 +107,18 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap  	// We're done with the run function, this thread is done executing now.  	threadp->mStatus = STOPPED; +	delete thread_recorder; +  	return NULL;  } -  LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :  	mPaused(FALSE),  	mName(name),  	mAPRThreadp(NULL),  	mStatus(STOPPED)  { +  	mID = ++sIDIter;  	// Thread creation probably CAN be paranoid about APR being initialized, if necessary @@ -152,7 +164,7 @@ void LLThread::shutdown()  			//llinfos << "LLThread::~LLThread() Killing thread " << mName << " Status: " << mStatus << llendl;  			// Now wait a bit for the thread to exit  			// It's unclear whether I should even bother doing this - this destructor -			// should netver get called unless we're already stopped, really... +			// should never get called unless we're already stopped, really...  			S32 counter = 0;  			const S32 MAX_WAIT = 600;  			while (counter < MAX_WAIT) @@ -282,7 +294,13 @@ void LLThread::setQuitting()  // static  U32 LLThread::currentID()  { +#if LL_DARWIN +	// statically allocated thread local storage not supported in Darwin executable formats  	return (U32)apr_os_thread_current(); +#else +	return sThreadID; +#endif +  }  // static @@ -315,155 +333,6 @@ void LLThread::wakeLocked()  //============================================================================ -LLMutex::LLMutex(apr_pool_t *poolp) : -	mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD) -{ -	//if (poolp) -	//{ -	//	mIsLocalPool = FALSE; -	//	mAPRPoolp = poolp; -	//} -	//else -	{ -		mIsLocalPool = TRUE; -		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread -	} -	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); -} - - -LLMutex::~LLMutex() -{ -#if MUTEX_DEBUG -	//bad assertion, the subclass LLSignal might be "locked", and that's OK -	//llassert_always(!isLocked()); // better not be locked! -#endif -	apr_thread_mutex_destroy(mAPRMutexp); -	mAPRMutexp = NULL; -	if (mIsLocalPool) -	{ -		apr_pool_destroy(mAPRPoolp); -	} -} - - -void LLMutex::lock() -{ -	if(isSelfLocked()) -	{ //redundant lock -		mCount++; -		return; -	} -	 -	apr_thread_mutex_lock(mAPRMutexp); -	 -#if MUTEX_DEBUG -	// Have to have the lock before we can access the debug info -	U32 id = LLThread::currentID(); -	if (mIsLocked[id] != FALSE) -		llerrs << "Already locked in Thread: " << id << llendl; -	mIsLocked[id] = TRUE; -#endif - -#if LL_DARWIN -	mLockingThread = LLThread::currentID(); -#else -	mLockingThread = sThreadID; -#endif -} - -void LLMutex::unlock() -{ -	if (mCount > 0) -	{ //not the root unlock -		mCount--; -		return; -	} -	 -#if MUTEX_DEBUG -	// Access the debug info while we have the lock -	U32 id = LLThread::currentID(); -	if (mIsLocked[id] != TRUE) -		llerrs << "Not locked in Thread: " << id << llendl;	 -	mIsLocked[id] = FALSE; -#endif - -	mLockingThread = NO_THREAD; -	apr_thread_mutex_unlock(mAPRMutexp); -} - -bool LLMutex::isLocked() -{ -	apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp); -	if (APR_STATUS_IS_EBUSY(status)) -	{ -		return true; -	} -	else -	{ -		apr_thread_mutex_unlock(mAPRMutexp); -		return false; -	} -} - -bool LLMutex::isSelfLocked() -{ -#if LL_DARWIN -	return mLockingThread == LLThread::currentID(); -#else -	return mLockingThread == sThreadID; -#endif -} - -U32 LLMutex::lockingThread() const -{ -	return mLockingThread; -} - -//============================================================================ - -LLCondition::LLCondition(apr_pool_t *poolp) : -	LLMutex(poolp) -{ -	// base class (LLMutex) has already ensured that mAPRPoolp is set up. - -	apr_thread_cond_create(&mAPRCondp, mAPRPoolp); -} - - -LLCondition::~LLCondition() -{ -	apr_thread_cond_destroy(mAPRCondp); -	mAPRCondp = NULL; -} - - -void LLCondition::wait() -{ -	if (!isLocked()) -	{ //mAPRMutexp MUST be locked before calling apr_thread_cond_wait -		apr_thread_mutex_lock(mAPRMutexp); -#if MUTEX_DEBUG -		// avoid asserts on destruction in non-release builds -		U32 id = LLThread::currentID(); -		mIsLocked[id] = TRUE; -#endif -	} -	apr_thread_cond_wait(mAPRCondp, mAPRMutexp); -} - -void LLCondition::signal() -{ -	apr_thread_cond_signal(mAPRCondp); -} - -void LLCondition::broadcast() -{ -	apr_thread_cond_broadcast(mAPRCondp); -} - -//============================================================================ -  //----------------------------------------------------------------------------  //static @@ -514,7 +383,6 @@ LLThreadSafeRefCount::~LLThreadSafeRefCount()  	}  } -  //============================================================================  LLResponder::~LLResponder() diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 0fb89c5613..4a84a14a65 100755 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -31,20 +31,14 @@  #include "llapr.h"  #include "apr_thread_cond.h"  #include "boost/intrusive_ptr.hpp" +#include "llmutex.h" -class LLThread; -class LLMutex; -class LLCondition; - -#if LL_WINDOWS -#define ll_thread_local __declspec(thread) -#else -#define ll_thread_local __thread -#endif +LL_COMMON_API void assert_main_thread();  class LL_COMMON_API LLThread  {  private: +	friend class LLMutex;  	static U32 sIDIter;  public: @@ -98,15 +92,15 @@ private:  	BOOL				mPaused;  	// static function passed to APR thread creation routine -	static void *APR_THREAD_FUNC staticRun(apr_thread_t *apr_threadp, void *datap); +	static void *APR_THREAD_FUNC staticRun(struct apr_thread_t *apr_threadp, void *datap);  protected:  	std::string			mName; -	LLCondition*		mRunCondition; +	class LLCondition*	mRunCondition;  	LLMutex*			mDataLock; -	apr_thread_t		*mAPRThreadp; -	apr_pool_t			*mAPRPoolp; +	apr_thread_t*		mAPRThreadp; +	apr_pool_t*			mAPRPoolp;  	BOOL				mIsLocalPool;  	EThreadStatus		mStatus;  	U32					mID; @@ -114,7 +108,7 @@ protected:  	//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.  	//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.  	//      otherwise it will cause severe memory leaking!!! --bao -	LLVolatileAPRPool  *mLocalAPRFilePoolp ;  +	LLVolatileAPRPool*	mLocalAPRFilePoolp ;   	void setQuitting(); @@ -140,75 +134,6 @@ protected:  	// mDataLock->unlock();  }; -//============================================================================ - -#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) - -class LL_COMMON_API LLMutex -{ -public: -	typedef enum -	{ -		NO_THREAD = 0xFFFFFFFF -	} e_locking_thread; - -	LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex -	virtual ~LLMutex(); -	 -	void lock();		// blocks -	void unlock(); -	bool isLocked(); 	// non-blocking, but does do a lock/unlock so not free -	bool isSelfLocked(); //return true if locked in a same thread -	U32 lockingThread() const; //get ID of locking thread -	 -protected: -	apr_thread_mutex_t *mAPRMutexp; -	mutable U32			mCount; -	mutable U32			mLockingThread; -	 -	apr_pool_t			*mAPRPoolp; -	BOOL				mIsLocalPool; -	 -#if MUTEX_DEBUG -	std::map<U32, BOOL> mIsLocked; -#endif -}; - -// Actually a condition/mutex pair (since each condition needs to be associated with a mutex). -class LL_COMMON_API LLCondition : public LLMutex -{ -public: -	LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. -	~LLCondition(); -	 -	void wait();		// blocks -	void signal(); -	void broadcast(); -	 -protected: -	apr_thread_cond_t *mAPRCondp; -}; - -class LLMutexLock -{ -public: -	LLMutexLock(LLMutex* mutex) -	{ -		mMutex = mutex; -		 -		if(mMutex) -			mMutex->lock(); -	} -	~LLMutexLock() -	{ -		if(mMutex) -			mMutex->unlock(); -	} -private: -	LLMutex* mMutex; -}; - -//============================================================================  void LLThread::lockData()  { diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp new file mode 100644 index 0000000000..32d94331a6 --- /dev/null +++ b/indra/llcommon/llthreadlocalstorage.cpp @@ -0,0 +1,117 @@ +/**  + * @file llthreadlocalstorage.cpp + * @author Richard + * @date 2013-1-11 + * @brief implementation of thread local storage utility classes + * + * $LicenseInfo:firstyear=2013&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 "linden_common.h" +#include "llthreadlocalstorage.h" +#include "llapr.h" + +// +//LLThreadLocalPointerBase +// +bool LLThreadLocalPointerBase::sInitialized = false; + +void LLThreadLocalPointerBase::set( void* value ) +{ +	llassert(sInitialized && mThreadKey); + +	apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey); +	if (result != APR_SUCCESS) +	{ +		ll_apr_warn_status(result); +		llerrs << "Failed to set thread local data" << llendl; +	} +} + +void* LLThreadLocalPointerBase::get() const +{ +	// llassert(sInitialized); +	void* ptr; +	apr_status_t result = +		apr_threadkey_private_get(&ptr, mThreadKey); +	if (result != APR_SUCCESS) +	{ +		ll_apr_warn_status(result); +		llerrs << "Failed to get thread local data" << llendl; +	} +	return ptr; +} + + +void LLThreadLocalPointerBase::initStorage( ) +{ +	apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); +	if (result != APR_SUCCESS) +	{ +		ll_apr_warn_status(result); +		llerrs << "Failed to allocate thread local data" << llendl; +	} +} + +void LLThreadLocalPointerBase::destroyStorage() +{ +	if (sInitialized) +	{ +		if (mThreadKey) +		{ +			apr_status_t result = apr_threadkey_private_delete(mThreadKey); +			if (result != APR_SUCCESS) +			{ +				ll_apr_warn_status(result); +				llerrs << "Failed to delete thread local data" << llendl; +			} +		} +	} +} + +void LLThreadLocalPointerBase::initAllThreadLocalStorage() +{ +	if (!sInitialized) +	{ +		for (LLInstanceTracker<LLThreadLocalPointerBase>::instance_iter it = beginInstances(), end_it = endInstances(); +			it != end_it; +			++it) +		{ +			(*it).initStorage(); +		} +		sInitialized = true; +	} +} + +void LLThreadLocalPointerBase::destroyAllThreadLocalStorage() +{ +	if (sInitialized) +	{ +		//for (LLInstanceTracker<LLThreadLocalPointerBase>::instance_iter it = beginInstances(), end_it = endInstances(); +		//	it != end_it; +		//	++it) +		//{ +		//	(*it).destroyStorage(); +		//} +		sInitialized = false; +	} +} diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h new file mode 100644 index 0000000000..a15f9185b1 --- /dev/null +++ b/indra/llcommon/llthreadlocalstorage.h @@ -0,0 +1,357 @@ +/**  + * @file llthreadlocalstorage.h + * @author Richard + * @brief Class wrappers for thread local storage + * + * $LicenseInfo:firstyear=2004&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_LLTHREADLOCALSTORAGE_H +#define LL_LLTHREADLOCALSTORAGE_H + +#include "llinstancetracker.h" + +class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase> +{ +public: +	LLThreadLocalPointerBase() +	:	mThreadKey(NULL) +	{ +		if (sInitialized) +		{ +			initStorage(); +		} +	} + +	LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other) +		:	mThreadKey(NULL) +	{ +		if (sInitialized) +		{ +			initStorage(); +		} +	} + +	~LLThreadLocalPointerBase() +	{ +		destroyStorage(); +	} + +	static void initAllThreadLocalStorage(); +	static void destroyAllThreadLocalStorage(); + +protected: +	void set(void* value); + +	void* get() const; + +	void initStorage(); +	void destroyStorage(); + +protected: +	struct apr_threadkey_t*	mThreadKey; +	static bool				sInitialized; +}; + +template <typename T> +class LLThreadLocalPointer : public LLThreadLocalPointerBase +{ +public: + +	LLThreadLocalPointer() +	{} + +	explicit LLThreadLocalPointer(T* value) +	{ +		set(value); +	} + + +	LLThreadLocalPointer(const LLThreadLocalPointer<T>& other) +	:	LLThreadLocalPointerBase(other) +	{ +		set(other.get());		 +	} + +	LL_FORCE_INLINE T* get() const +	{ +		return (T*)LLThreadLocalPointerBase::get(); +	} + +	T* operator -> () const +	{ +		return (T*)get(); +	} + +	T& operator*() const +	{ +		return *(T*)get(); +	} + +	LLThreadLocalPointer<T>& operator = (T* value) +	{ +		set((void*)value); +		return *this; +	} + +	bool operator ==(const T* other) const +	{ +		if (!sInitialized) return false; +		return get() == other; +	} + +	bool isNull() const { return !sInitialized || get() == NULL; } + +	bool notNull() const { return sInitialized && get() != NULL; } +}; + +template<typename DERIVED_TYPE> +class LLThreadLocalSingleton +{ +	typedef enum e_init_state +	{ +		UNINITIALIZED = 0, +		CONSTRUCTING, +		INITIALIZING, +		INITIALIZED, +		DELETED +	} EInitState; + +public: +	LLThreadLocalSingleton() +	{} +	 +	virtual ~LLThreadLocalSingleton() +	{ +#if LL_DARWIN +        pthread_setspecific(sInstanceKey, NULL); +#else +        sInstance = NULL; +#endif +		setInitState(DELETED); +	} + +	static void deleteSingleton() +	{ +		delete getIfExists(); +	} + +	static DERIVED_TYPE* getInstance() +	{ +        EInitState init_state = getInitState(); +		if (init_state == CONSTRUCTING) +		{ +			llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl; +		} + +		if (init_state == DELETED) +		{ +			llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl; +		} + +#if LL_DARWIN +        createTLSInstance(); +#endif +		if (!getIfExists()) +		{ +			setInitState(CONSTRUCTING); +            DERIVED_TYPE* instancep = new DERIVED_TYPE(); +#if LL_DARWIN +            S32 result = pthread_setspecific(sInstanceKey, (void*)instancep); +            if (result != 0) +            { +                llerrs << "Could not set thread local storage" << llendl; +            } +#else +			sInstance = instancep; +#endif +			setInitState(INITIALIZING); +			instancep->initSingleton(); +			setInitState(INITIALIZED); +		} + +        return getIfExists(); +	} + +	static DERIVED_TYPE* getIfExists() +	{ +#if LL_DARWIN +        return (DERIVED_TYPE*)pthread_getspecific(sInstanceKey); +#else +		return sInstance; +#endif +	} + +	// Reference version of getInstance() +	// Preferred over getInstance() as it disallows checking for NULL +	static DERIVED_TYPE& instance() +	{ +		return *getInstance(); +	} + +	// Has this singleton been created uet? +	// Use this to avoid accessing singletons before the can safely be constructed +	static bool instanceExists() +	{ +		return getInitState() == INITIALIZED; +	} + +	// Has this singleton already been deleted? +	// Use this to avoid accessing singletons from a static object's destructor +	static bool destroyed() +	{ +		return getInitState() == DELETED; +	} +private: +#if LL_DARWIN +    static void createTLSInitState() +    { +        static S32 key_created = pthread_key_create(&sInitStateKey, NULL); +        if (key_created != 0) +        { +            llerrs << "Could not create thread local storage" << llendl; +        } +    } +     +    static void createTLSInstance() +    { +        static S32 key_created = pthread_key_create(&sInstanceKey, NULL); +        if (key_created != 0) +        { +            llerrs << "Could not create thread local storage" << llendl; +        } +    } +#endif +    static EInitState getInitState() +    { +#if LL_DARWIN +        createTLSInitState(); +        return (EInitState)(int)pthread_getspecific(sInitStateKey); +#else +        return sInitState; +#endif +    } +     +    static void setInitState(EInitState state) +    { +#if LL_DARWIN +        createTLSInitState(); +        pthread_setspecific(sInitStateKey, (void*)state); +#else +        sInitState = state; +#endif +    } +	LLThreadLocalSingleton(const LLThreadLocalSingleton& other); +	virtual void initSingleton() {} + +#ifdef LL_WINDOWS +	static __declspec(thread) DERIVED_TYPE* sInstance; +	static __declspec(thread) EInitState sInitState; +#elif LL_LINUX +	static __thread DERIVED_TYPE* sInstance; +	static __thread EInitState sInitState; +#elif LL_DARWIN +    static pthread_key_t sInstanceKey; +    static pthread_key_t sInitStateKey; +#endif +}; + +#if LL_WINDOWS +template<typename DERIVED_TYPE> +__declspec(thread) DERIVED_TYPE* LLThreadLocalSingleton<DERIVED_TYPE>::sInstance = NULL; + +template<typename DERIVED_TYPE> +__declspec(thread) typename LLThreadLocalSingleton<DERIVED_TYPE>::EInitState LLThreadLocalSingleton<DERIVED_TYPE>::sInitState = LLThreadLocalSingleton<DERIVED_TYPE>::UNINITIALIZED; +#elif LL_LINUX +template<typename DERIVED_TYPE> +__thread DERIVED_TYPE* LLThreadLocalSingleton<DERIVED_TYPE>::sInstance = NULL; + +template<typename DERIVED_TYPE> +__thread typename LLThreadLocalSingleton<DERIVED_TYPE>::EInitState LLThreadLocalSingleton<DERIVED_TYPE>::sInitState = LLThreadLocalSingleton<DERIVED_TYPE>::UNINITIALIZED; +#elif LL_DARWIN +template<typename DERIVED_TYPE> +pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInstanceKey; + +template<typename DERIVED_TYPE> +pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInitStateKey; + +#endif + +template<typename DERIVED_TYPE> +class LLThreadLocalSingletonPointer +{ +public: +	LL_FORCE_INLINE static DERIVED_TYPE* getInstance() +	{ +#if LL_DARWIN +        createTLSKey(); +        return (DERIVED_TYPE*)pthread_getspecific(sInstanceKey); +#else +		return sInstance; +#endif +	} + +	static void setInstance(DERIVED_TYPE* instance) +	{ +#if LL_DARWIN +        createTLSKey(); +        pthread_setspecific(sInstanceKey, (void*)instance); +#else +		sInstance = instance; +#endif +	} + +private: + +#if LL_WINDOWS +	static __declspec(thread) DERIVED_TYPE* sInstance; +#elif LL_LINUX +	static __thread DERIVED_TYPE* sInstance; +#elif LL_DARWIN +    static void TLSError() +    { +        llerrs << "Could not create thread local storage" << llendl; +    } +    static void createTLSKey() +    { +        static S32 key_created = pthread_key_create(&sInstanceKey, NULL); +        if (key_created != 0) +        { +            llerrs << "Could not create thread local storage" << llendl; +        } +    } +    static pthread_key_t sInstanceKey; +#endif +}; + +#if LL_WINDOWS +template<typename DERIVED_TYPE> +__declspec(thread) DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; +#elif LL_LINUX +template<typename DERIVED_TYPE> +__thread DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; +#elif LL_DARWIN +template<typename DERIVED_TYPE> +pthread_key_t LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstanceKey; +#endif + +#endif // LL_LLTHREADLOCALSTORAGE_H diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 9ebc6de7f4..838155d54d 100755 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -31,11 +31,9 @@  #include "u64.h"  #if LL_WINDOWS -#	define WIN32_LEAN_AND_MEAN -#	include <winsock2.h> -#	include <windows.h> +#	include "llwin32headerslean.h"  #elif LL_LINUX || LL_SOLARIS || LL_DARWIN -#       include <errno.h> +#   include <errno.h>  #	include <sys/time.h>  #else   #	error "architecture not supported" @@ -287,14 +285,14 @@ LLTimer::~LLTimer()  }  // static -U64 LLTimer::getTotalTime() +LLUnitImplicit<LLUnits::Microseconds, U64> LLTimer::getTotalTime()  {  	// simply call into the implementation function.  	return totalTime();  }	  // static -F64 LLTimer::getTotalSeconds() +LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getTotalSeconds()  {  	return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;  } @@ -343,23 +341,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)  } -F64 LLTimer::getElapsedTimeF64() const +LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeF64() const  {  	U64 last = mLastClockCount;  	return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;  } -F32 LLTimer::getElapsedTimeF32() const +LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeF32() const  {  	return (F32)getElapsedTimeF64();  } -F64 LLTimer::getElapsedTimeAndResetF64() +LLUnitImplicit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeAndResetF64()  {  	return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;  } -F32 LLTimer::getElapsedTimeAndResetF32() +LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeAndResetF32()  {  	return (F32)getElapsedTimeAndResetF64();  } @@ -372,7 +370,7 @@ void  LLTimer::setTimerExpirySec(F32 expiration)  		+ (U64)((F32)(expiration * gClockFrequency));  } -F32 LLTimer::getRemainingTimeF32() const +LLUnitImplicit<LLUnits::Seconds, F32> LLTimer::getRemainingTimeF32() const  {  	U64 cur_ticks = get_clock_count();  	if (cur_ticks > mExpirationTicks) diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h index 513de0605d..0ba87d1e15 100755 --- a/indra/llcommon/lltimer.h +++ b/indra/llcommon/lltimer.h @@ -37,6 +37,7 @@  #include <string>  #include <list>  // units conversions +#include "llunit.h"  #ifndef USEC_PER_SEC      const U32	USEC_PER_SEC	= 1000000;  #endif @@ -55,7 +56,7 @@ public:  protected:	  	U64 mLastClockCount;  	U64 mExpirationTicks; -	BOOL mStarted; +	bool mStarted;  public:  	LLTimer(); @@ -66,16 +67,16 @@ public:  	// Return a high precision number of seconds since the start of  	// this application instance. -	static F64 getElapsedSeconds() +	static LLUnitImplicit<LLUnits::Seconds, F64> getElapsedSeconds()  	{  		return sTimer->getElapsedTimeF64();  	}  	// Return a high precision usec since epoch -	static U64 getTotalTime(); +	static LLUnitImplicit<LLUnits::Microseconds, U64> getTotalTime();  	// Return a high precision seconds since epoch -	static F64 getTotalSeconds(); +	static LLUnitImplicit<LLUnits::Seconds, F64> getTotalSeconds();  	// MANIPULATORS @@ -86,18 +87,18 @@ public:  	void setTimerExpirySec(F32 expiration);  	BOOL checkExpirationAndReset(F32 expiration);  	BOOL hasExpired() const; -	F32 getElapsedTimeAndResetF32();	// Returns elapsed time in seconds with reset -	F64 getElapsedTimeAndResetF64(); +	LLUnitImplicit<LLUnits::Seconds, F32> getElapsedTimeAndResetF32();	// Returns elapsed time in seconds with reset +	LLUnitImplicit<LLUnits::Seconds, F64> getElapsedTimeAndResetF64(); -	F32 getRemainingTimeF32() const; +	LLUnitImplicit<LLUnits::Seconds, F32> getRemainingTimeF32() const;  	static BOOL knownBadTimer();  	// ACCESSORS -	F32 getElapsedTimeF32() const;			// Returns elapsed time in seconds -	F64 getElapsedTimeF64() const;			// Returns elapsed time in seconds +	LLUnitImplicit<LLUnits::Seconds, F32> getElapsedTimeF32() const;			// Returns elapsed time in seconds +	LLUnitImplicit<LLUnits::Seconds, F64> getElapsedTimeF64() const;			// Returns elapsed time in seconds -	BOOL getStarted() const { return mStarted; } +	bool getStarted() const { return mStarted; }  	static U64 getCurrentClockCount();		// Returns the raw clockticks diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp new file mode 100644 index 0000000000..c831a1548d --- /dev/null +++ b/indra/llcommon/lltrace.cpp @@ -0,0 +1,115 @@ +/**  + * @file lltrace.cpp + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "linden_common.h" + +#include "lltrace.h" +#include "lltracerecording.h" +#include "lltracethreadrecorder.h" +#include "llfasttimer.h" + +static S32 sInitializationCount = 0; + +namespace LLTrace +{ + +static MasterThreadRecorder* gUIThreadRecorder = NULL; + +void init() +{ +	if (sInitializationCount++ == 0) +	{ +		gUIThreadRecorder = new MasterThreadRecorder(); +	} +} + +bool isInitialized() +{ +	return sInitializationCount > 0;  +} + +void cleanup() +{ +	if (--sInitializationCount == 0) +	{ +		delete gUIThreadRecorder; +		gUIThreadRecorder = NULL; +	} +} + +MasterThreadRecorder& getUIThreadRecorder() +{ +	llassert(gUIThreadRecorder != NULL); +	return *gUIThreadRecorder; +} + +LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr() +{ +	static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder; +	return s_thread_recorder; +} + +const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder() +{ +	return get_thread_recorder_ptr(); +} + +void set_thread_recorder(ThreadRecorder* recorder) +{ +	get_thread_recorder_ptr() = recorder; +} + + +TimeBlockTreeNode::TimeBlockTreeNode()  +:	mBlock(NULL), +	mParent(NULL), +	mNeedsSorting(false) +{} + +void TimeBlockTreeNode::setParent( TimeBlock* parent ) +{ +	llassert_always(parent != mBlock); +	llassert_always(parent != NULL); + +	TimeBlockTreeNode* parent_tree_node = get_thread_recorder()->getTimeBlockTreeNode(parent->getIndex()); +	if (!parent_tree_node) return; + +	if (mParent) +	{ +		std::vector<TimeBlock*>& children = mParent->getChildren(); +		std::vector<TimeBlock*>::iterator found_it = std::find(children.begin(), children.end(), mBlock); +		if (found_it != children.end()) +		{ +			children.erase(found_it); +		} +	} + +	mParent = parent; +	mBlock->getPrimaryAccumulator()->mParent = parent; +	parent_tree_node->mChildren.push_back(mBlock); +	parent_tree_node->mNeedsSorting = true; +} + +} diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h new file mode 100644 index 0000000000..343e1b16e8 --- /dev/null +++ b/indra/llcommon/lltrace.h @@ -0,0 +1,1083 @@ +/**  + * @file lltrace.h + * @brief Runtime statistics accumulation. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLTRACE_H +#define LL_LLTRACE_H + +#include "stdtypes.h" +#include "llpreprocessor.h" + +#include "llmemory.h" +#include "llrefcount.h" +#include "llunit.h" +#include "llthreadlocalstorage.h" +#include "lltimer.h" + +#include <list> + +#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::TimeBlock::Recorder LL_GLUE_TOKENS(block_time_recorder, __COUNTER__)(block_timer); + +namespace LLTrace +{ +class Recording; + +typedef LLUnit<LLUnits::Bytes, F64>			Bytes; +typedef LLUnit<LLUnits::Kibibytes, F64>		Kibibytes; +typedef LLUnit<LLUnits::Mibibytes, F64>		Mibibytes; +typedef LLUnit<LLUnits::Gibibytes, F64>		Gibibytes; +typedef LLUnit<LLUnits::Bits, F64>			Bits; +typedef LLUnit<LLUnits::Kibibits, F64>		Kibibits; +typedef LLUnit<LLUnits::Mibibits, F64>		Mibibits; +typedef LLUnit<LLUnits::Gibibits, F64>		Gibibits; + +typedef LLUnit<LLUnits::Seconds, F64>		Seconds; +typedef LLUnit<LLUnits::Milliseconds, F64>	Milliseconds; +typedef LLUnit<LLUnits::Minutes, F64>		Minutes; +typedef LLUnit<LLUnits::Hours, F64>			Hours; +typedef LLUnit<LLUnits::Milliseconds, F64>	Milliseconds; +typedef LLUnit<LLUnits::Microseconds, F64>	Microseconds; +typedef LLUnit<LLUnits::Nanoseconds, F64>	Nanoseconds; + +typedef LLUnit<LLUnits::Meters, F64>		Meters; +typedef LLUnit<LLUnits::Kilometers, F64>	Kilometers; +typedef LLUnit<LLUnits::Centimeters, F64>	Centimeters; +typedef LLUnit<LLUnits::Millimeters, F64>	Millimeters; + +void init(); +void cleanup(); +bool isInitialized(); + +const LLThreadLocalPointer<class ThreadRecorder>& get_thread_recorder(); +void set_thread_recorder(class ThreadRecorder*); + +class MasterThreadRecorder& getUIThreadRecorder(); + +template<typename ACCUMULATOR> +class AccumulatorBuffer : public LLRefCount +{ +	typedef AccumulatorBuffer<ACCUMULATOR> self_t; +	static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; +private: +	struct StaticAllocationMarker { }; + +	AccumulatorBuffer(StaticAllocationMarker m) +	:	mStorageSize(0), +		mStorage(NULL) +	{} + +public: + +	AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer()) +	:	mStorageSize(0), +		mStorage(NULL) +	{ +		resize(other.mStorageSize); +		for (S32 i = 0; i < sNextStorageSlot; i++) +		{ +			mStorage[i] = other.mStorage[i]; +		} +	} + +	~AccumulatorBuffer() +	{ +		if (isPrimary()) +		{ +			LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL); +		} +		delete[] mStorage; +	} + +	LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)  +	{  +		return mStorage[index];  +	} + +	LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const +	{  +		return mStorage[index];  +	} + +	void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other, bool append = true) +	{ +		llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot); +		for (size_t i = 0; i < sNextStorageSlot; i++) +		{ +			mStorage[i].addSamples(other.mStorage[i], append); +		} +	} + +	void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other) +	{ +		llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize > sNextStorageSlot); +		for (size_t i = 0; i < sNextStorageSlot; i++) +		{ +			mStorage[i] = other.mStorage[i]; +		} +	} + +	void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL) +	{ +		llassert(mStorageSize >= sNextStorageSlot); +		for (size_t i = 0; i < sNextStorageSlot; i++) +		{ +			mStorage[i].reset(other ? &other->mStorage[i] : NULL); +		} +	} + +	void flush() +	{ +		llassert(mStorageSize >= sNextStorageSlot); +		for (size_t i = 0; i < sNextStorageSlot; i++) +		{ +			mStorage[i].flush(); +		} +	} + +	void makePrimary() +	{ +		LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(mStorage); +	} + +	bool isPrimary() const +	{ +		return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage; +	} + +	LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage()  +	{  +		ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance(); +		return accumulator ? accumulator : sDefaultBuffer->mStorage; +	} + +	// NOTE: this is not thread-safe.  We assume that slots are reserved in the main thread before any child threads are spawned +	size_t reserveSlot() +	{ +#ifndef LL_RELEASE_FOR_DOWNLOAD +		if (LLTrace::isInitialized()) +		{ +			llerrs << "Attempting to declare trace object after program initialization.  Trace objects should be statically initialized." << llendl; +		} +#endif +		size_t next_slot = sNextStorageSlot++; +		if (next_slot >= mStorageSize) +		{ +			resize(mStorageSize + (mStorageSize >> 2)); +		} +		llassert(mStorage && next_slot < mStorageSize); +		return next_slot; +	} + +	void resize(size_t new_size) +	{ +		if (new_size <= mStorageSize) return; + +		ACCUMULATOR* old_storage = mStorage; +		mStorage = new ACCUMULATOR[new_size]; +		if (old_storage) +		{ +			for (S32 i = 0; i < mStorageSize; i++) +			{ +				mStorage[i] = old_storage[i]; +			} +		} +		mStorageSize = new_size; +		delete[] old_storage; + +		self_t* default_buffer = getDefaultBuffer(); +		if (this != default_buffer +			&& new_size > default_buffer->size()) +		{ +			//NB: this is not thread safe, but we assume that all resizing occurs during static initialization +			default_buffer->resize(new_size); +		} +	} + +	size_t size() const +	{ +		return sNextStorageSlot; +	} + +	static self_t* getDefaultBuffer() +	{ +		static bool sInitialized = false; +		if (!sInitialized) +		{ +			// this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data +			// so as not to trigger an access violation +			sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker()); +			sInitialized = true; +			sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); +		} +		return sDefaultBuffer; +	} + +private: +	ACCUMULATOR*	mStorage; +	size_t			mStorageSize; +	static size_t	sNextStorageSlot; +	static self_t*	sDefaultBuffer; +}; + +template<typename ACCUMULATOR> size_t AccumulatorBuffer<ACCUMULATOR>::sNextStorageSlot = 0; +template<typename ACCUMULATOR> AccumulatorBuffer<ACCUMULATOR>* AccumulatorBuffer<ACCUMULATOR>::sDefaultBuffer = NULL; + +template<typename ACCUMULATOR> +class TraceType  +:	 public LLInstanceTracker<TraceType<ACCUMULATOR>, std::string> +{ +public: +	TraceType(const char* name, const char* description = NULL) +	:	LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>(name), +		mName(name), +		mDescription(description ? description : ""), +		mAccumulatorIndex(AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer()->reserveSlot()) +	{} + +	LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const +	{ +		ACCUMULATOR* accumulator_storage = AccumulatorBuffer<ACCUMULATOR>::getPrimaryStorage(); +		return &accumulator_storage[mAccumulatorIndex]; +	} + +	size_t getIndex() const { return mAccumulatorIndex; } + +	virtual const char* getUnitLabel() { return ""; } + +	const std::string& getName() const { return mName; } + +protected: +	const std::string	mName; +	const std::string	mDescription; +	const size_t		mAccumulatorIndex; +}; + +class EventAccumulator +{ +public: +	typedef F64 value_t; +	typedef F64 mean_t; + +	EventAccumulator() +	:	mSum(0), +		mMin((std::numeric_limits<F64>::max)()), +		mMax((std::numeric_limits<F64>::min)()), +		mMean(0), +		mVarianceSum(0), +		mNumSamples(0), +		mLastValue(0) +	{} + +	void record(F64 value) +	{ +		mNumSamples++; +		mSum += value; +		// NOTE: both conditions will hold on first pass through +		if (value < mMin) +		{ +			mMin = value; +		} +		if (value > mMax) +		{ +			mMax = value; +		} +		F64 old_mean = mMean; +		mMean += (value - old_mean) / (F64)mNumSamples; +		mVarianceSum += (value - old_mean) * (value - mMean); +		mLastValue = value; +	} + +	void addSamples(const EventAccumulator& other, bool append) +	{ +		if (other.mNumSamples) +		{ +			mSum += other.mSum; + +			// NOTE: both conditions will hold first time through +			if (other.mMin < mMin) { mMin = other.mMin; } +			if (other.mMax > mMax) { mMax = other.mMax; } + +			// combine variance (and hence standard deviation) of 2 different sized sample groups using +			// the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm +			F64 n_1 = (F64)mNumSamples, +				n_2 = (F64)other.mNumSamples; +			F64 m_1 = mMean, +				m_2 = other.mMean; +			F64 v_1 = mVarianceSum / mNumSamples, +				v_2 = other.mVarianceSum / other.mNumSamples; +			if (n_1 == 0) +			{ +				mVarianceSum = other.mVarianceSum; +			} +			else if (n_2 == 0) +			{ +				// don't touch variance +				// mVarianceSum = mVarianceSum; +			} +			else +			{ +				mVarianceSum = (F64)mNumSamples +								* ((((n_1 - 1.f) * v_1) +									+ ((n_2 - 1.f) * v_2) +									+ (((n_1 * n_2) / (n_1 + n_2)) +										* ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) +									/ (n_1 + n_2 - 1.f)); +			} + +			F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples); +			mNumSamples += other.mNumSamples; +			mMean = mMean * weight + other.mMean * (1.f - weight); +			if (append) mLastValue = other.mLastValue; +		} +	} + +	void reset(const EventAccumulator* other) +	{ +		mNumSamples = 0; +		mSum = 0; +		mMin = std::numeric_limits<F64>::max(); +		mMax = std::numeric_limits<F64>::min(); +		mMean = 0; +		mVarianceSum = 0; +		mLastValue = other ? other->mLastValue : 0; +	} + +	void flush() {} + +	F64	getSum() const { return mSum; } +	F64	getMin() const { return mMin; } +	F64	getMax() const { return mMax; } +	F64	getLastValue() const { return mLastValue; } +	F64	getMean() const { return mMean; } +	F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } +	U32 getSampleCount() const { return mNumSamples; } + +private: +	F64	mSum, +		mMin, +		mMax, +		mLastValue; + +	F64	mMean, +		mVarianceSum; + +	U32	mNumSamples; +}; + + +class SampleAccumulator +{ +public: +	typedef F64 value_t; +	typedef F64 mean_t; + +	SampleAccumulator() +	:	mSum(0), +		mMin((std::numeric_limits<F64>::max)()), +		mMax((std::numeric_limits<F64>::min)()), +		mMean(0), +		mVarianceSum(0), +		mLastSampleTimeStamp(LLTimer::getTotalSeconds()), +		mTotalSamplingTime(0), +		mNumSamples(0), +		mLastValue(0), +		mHasValue(false) +	{} + +	void sample(F64 value) +	{ +		LLUnitImplicit<LLUnits::Seconds, F64> time_stamp = LLTimer::getTotalSeconds(); +		LLUnitImplicit<LLUnits::Seconds, F64> delta_time = time_stamp - mLastSampleTimeStamp; +		mLastSampleTimeStamp = time_stamp; + +		if (mHasValue) +		{ +			mTotalSamplingTime += delta_time; +			mSum += mLastValue * delta_time; + +			// NOTE: both conditions will hold first time through +			if (value < mMin) { mMin = value; } +			if (value > mMax) { mMax = value; } + +			F64 old_mean = mMean; +			mMean += (delta_time / mTotalSamplingTime) * (mLastValue - old_mean); +			mVarianceSum += delta_time * (mLastValue - old_mean) * (mLastValue - mMean); +		} + +		mLastValue = value; +		mNumSamples++; +		mHasValue = true; +	} + +	void addSamples(const SampleAccumulator& other, bool append) +	{ +		if (other.mTotalSamplingTime) +		{ +			mSum += other.mSum; + +			// NOTE: both conditions will hold first time through +			if (other.mMin < mMin) { mMin = other.mMin; } +			if (other.mMax > mMax) { mMax = other.mMax; } + +			// combine variance (and hence standard deviation) of 2 different sized sample groups using +			// the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm +			F64 n_1 = mTotalSamplingTime, +				n_2 = other.mTotalSamplingTime; +			F64 m_1 = mMean, +				m_2 = other.mMean; +			F64 v_1 = mVarianceSum / mTotalSamplingTime, +				v_2 = other.mVarianceSum / other.mTotalSamplingTime; +			if (n_1 == 0) +			{ +				mVarianceSum = other.mVarianceSum; +			} +			else if (n_2 == 0) +			{ +				// variance is unchanged +				// mVarianceSum = mVarianceSum; +			} +			else +			{ +				mVarianceSum =	mTotalSamplingTime +								* ((((n_1 - 1.f) * v_1) +									+ ((n_2 - 1.f) * v_2) +									+ (((n_1 * n_2) / (n_1 + n_2)) +										* ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) +									/ (n_1 + n_2 - 1.f)); +			} + +			llassert(other.mTotalSamplingTime > 0); +			F64 weight = mTotalSamplingTime / (mTotalSamplingTime + other.mTotalSamplingTime); +			mNumSamples += other.mNumSamples; +			mTotalSamplingTime += other.mTotalSamplingTime; +			mMean = (mMean * weight) + (other.mMean * (1.0 - weight)); +			if (append) +			{ +				mLastValue = other.mLastValue; +				mLastSampleTimeStamp = other.mLastSampleTimeStamp; +				mHasValue |= other.mHasValue; +			} +		} +	} + +	void reset(const SampleAccumulator* other) +	{ +		mNumSamples = 0; +		mSum = 0; +		mMin = std::numeric_limits<F64>::max(); +		mMax = std::numeric_limits<F64>::min(); +		mMean = other ? other->mLastValue : 0; +		mVarianceSum = 0; +		mLastSampleTimeStamp = LLTimer::getTotalSeconds(); +		mTotalSamplingTime = 0; +		mLastValue = other ? other->mLastValue : 0; +		mHasValue = other ? other->mHasValue : false; +	} + +	void flush() +	{ +		LLUnitImplicit<LLUnits::Seconds, F64> time_stamp = LLTimer::getTotalSeconds(); +		LLUnitImplicit<LLUnits::Seconds, F64> delta_time = time_stamp - mLastSampleTimeStamp; + +		if (mHasValue) +		{ +			mSum += mLastValue * delta_time; +			mTotalSamplingTime += delta_time; +		} +		mLastSampleTimeStamp = time_stamp; +	} + +	F64	getSum() const { return mSum; } +	F64	getMin() const { return mMin; } +	F64	getMax() const { return mMax; } +	F64	getLastValue() const { return mLastValue; } +	F64	getMean() const { return mMean; } +	F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mTotalSamplingTime); } +	U32 getSampleCount() const { return mNumSamples; } + +private: +	F64	mSum, +		mMin, +		mMax, +		mLastValue; + +	bool mHasValue; + +	F64	mMean, +		mVarianceSum; + +	LLUnitImplicit<LLUnits::Seconds, F64>	mLastSampleTimeStamp, +											mTotalSamplingTime; + +	U32	mNumSamples; +}; + +class CountAccumulator +{ +public: +	typedef F64 value_t; +	typedef F64 mean_t; + +	CountAccumulator() +	:	mSum(0), +		mNumSamples(0) +	{} + +	void add(F64 value) +	{ +		mNumSamples++; +		mSum += value; +	} + +	void addSamples(const CountAccumulator& other, bool /*append*/) +	{ +		mSum += other.mSum; +		mNumSamples += other.mNumSamples; +	} + +	void reset(const CountAccumulator* other) +	{ +		mNumSamples = 0; +		mSum = 0; +	} + +	void flush() {} + +	F64	getSum() const { return mSum; } + +	U32 getSampleCount() const { return mNumSamples; } + +private: +	F64	mSum; + +	U32	mNumSamples; +}; + +class TimeBlockAccumulator +{ +public: +	typedef LLUnit<LLUnits::Seconds, F64> value_t; +	typedef LLUnit<LLUnits::Seconds, F64> mean_t; +	typedef TimeBlockAccumulator self_t; + +	// fake classes that allows us to view different facets of underlying statistic +	struct CallCountFacet  +	{ +		typedef U32 value_t; +		typedef F32 mean_t; +	}; + +	struct SelfTimeFacet +	{ +		typedef LLUnit<LLUnits::Seconds, F64> value_t; +		typedef LLUnit<LLUnits::Seconds, F64> mean_t; +	}; + +	TimeBlockAccumulator(); +	void addSamples(const self_t& other, bool /*append*/); +	void reset(const self_t* other); +	void flush() {} + +	// +	// members +	// +	U64							mStartTotalTimeCounter, +								mTotalTimeCounter, +								mSelfTimeCounter; +	U32							mCalls; +	class TimeBlock*			mParent;		// last acknowledged parent of this time block +	class TimeBlock*			mLastCaller;	// used to bootstrap tree construction +	U16							mActiveCount;	// number of timers with this ID active on stack +	bool						mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame + +}; + +template<> +class TraceType<TimeBlockAccumulator::CallCountFacet> +:	public TraceType<TimeBlockAccumulator> +{ +public: + +	TraceType(const char* name, const char* description = "") +	:	TraceType<TimeBlockAccumulator>(name, description) +	{} +}; + +template<> +class TraceType<TimeBlockAccumulator::SelfTimeFacet> +	:	public TraceType<TimeBlockAccumulator> +{ +public: + +	TraceType(const char* name, const char* description = "") +		:	TraceType<TimeBlockAccumulator>(name, description) +	{} +}; + +class TimeBlock; +class TimeBlockTreeNode +{ +public: +	TimeBlockTreeNode(); + +	void setParent(TimeBlock* parent); +	TimeBlock* getParent() { return mParent; } + +	TimeBlock*					mBlock; +	TimeBlock*					mParent;	 +	std::vector<TimeBlock*>		mChildren; +	bool						mNeedsSorting; +}; + + +template <typename T = F64> +class EventStatHandle +:	public TraceType<EventAccumulator> +{ +public: +	typedef typename F64 storage_t; +	typedef TraceType<EventAccumulator> trace_t; + +	EventStatHandle(const char* name, const char* description = NULL) +	:	trace_t(name, description) +	{} + +	/*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel<T>::getUnitLabel(); } + +}; + +template<typename T, typename VALUE_T> +void record(EventStatHandle<T>& measurement, VALUE_T value) +{ +	T converted_value(value); +	measurement.getPrimaryAccumulator()->record(LLUnits::rawValue(converted_value)); +} + +template <typename T = F64> +class SampleStatHandle +:	public TraceType<SampleAccumulator> +{ +public: +	typedef F64 storage_t; +	typedef TraceType<SampleAccumulator> trace_t; + +	SampleStatHandle(const char* name, const char* description = NULL) +	:	trace_t(name, description) +	{} + +	/*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel<T>::getUnitLabel(); } +}; + +template<typename T, typename VALUE_T> +void sample(SampleStatHandle<T>& measurement, VALUE_T value) +{ +	T converted_value(value); +	measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value)); +} + +template <typename T = F64> +class CountStatHandle +:	public TraceType<CountAccumulator> +{ +public: +	typedef typename F64 storage_t; +	typedef TraceType<CountAccumulator> trace_t; + +	CountStatHandle(const char* name, const char* description = NULL)  +	:	trace_t(name) +	{} + +	/*virtual*/ const char* getUnitLabel() { return LLGetUnitLabel<T>::getUnitLabel(); } +}; + +template<typename T, typename VALUE_T> +void add(CountStatHandle<T>& count, VALUE_T value) +{ +	T converted_value(value); +	count.getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value)); +} + + +struct MemStatAccumulator +{ +	typedef MemStatAccumulator self_t; + +	// fake classes that allows us to view different facets of underlying statistic +	struct AllocationCountFacet  +	{ +		typedef U32 value_t; +		typedef F32 mean_t; +	}; + +	struct DeallocationCountFacet  +	{ +		typedef U32 value_t; +		typedef F32 mean_t; +	}; + +	struct ChildMemFacet +	{ +		typedef LLUnit<LLUnits::Bytes, F64> value_t; +		typedef LLUnit<LLUnits::Bytes, F64> mean_t; +	}; + +	MemStatAccumulator() +	:	mAllocatedCount(0), +		mDeallocatedCount(0) +	{} + +	void addSamples(const MemStatAccumulator& other, bool append) +	{ +		mSize.addSamples(other.mSize, append); +		mChildSize.addSamples(other.mChildSize, append); +		mAllocatedCount += other.mAllocatedCount; +		mDeallocatedCount += other.mDeallocatedCount; +	} + +	void reset(const MemStatAccumulator* other) +	{ +		mSize.reset(other ? &other->mSize : NULL); +		mChildSize.reset(other ? &other->mChildSize : NULL); +		mAllocatedCount = 0; +		mDeallocatedCount = 0; +	} + +	void flush()  +	{ +		mSize.flush(); +		mChildSize.flush(); +	} + +	SampleAccumulator	mSize, +						mChildSize; +	int					mAllocatedCount, +						mDeallocatedCount; +}; + + +template<> +class TraceType<MemStatAccumulator::AllocationCountFacet> +:	public TraceType<MemStatAccumulator> +{ +public: + +	TraceType(const char* name, const char* description = "") +	:	TraceType<MemStatAccumulator>(name, description) +	{} +}; + +template<> +class TraceType<MemStatAccumulator::DeallocationCountFacet> +:	public TraceType<MemStatAccumulator> +{ +public: + +	TraceType(const char* name, const char* description = "") +	:	TraceType<MemStatAccumulator>(name, description) +	{} +}; + +template<> +class TraceType<MemStatAccumulator::ChildMemFacet> +	:	public TraceType<MemStatAccumulator> +{ +public: + +	TraceType(const char* name, const char* description = "") +		:	TraceType<MemStatAccumulator>(name, description) +	{} +}; + +class MemStatHandle : public TraceType<MemStatAccumulator> +{ +public: +	typedef TraceType<MemStatAccumulator> trace_t; +	MemStatHandle(const char* name) +	:	trace_t(name) +	{} + +	/*virtual*/ const char* getUnitLabel() { return "B"; } + +	TraceType<MemStatAccumulator::AllocationCountFacet>& allocationCount()  +	{  +		return static_cast<TraceType<MemStatAccumulator::AllocationCountFacet>&>(*(TraceType<MemStatAccumulator>*)this); +	} + +	TraceType<MemStatAccumulator::DeallocationCountFacet>& deallocationCount()  +	{  +		return static_cast<TraceType<MemStatAccumulator::DeallocationCountFacet>&>(*(TraceType<MemStatAccumulator>*)this); +	} + +	TraceType<MemStatAccumulator::ChildMemFacet>& childMem()  +	{  +		return static_cast<TraceType<MemStatAccumulator::ChildMemFacet>&>(*(TraceType<MemStatAccumulator>*)this); +	} +}; + +// measures effective memory footprint of specified type +// specialize to cover different types + +template<typename T> +struct MemFootprint +{ +	static size_t measure(const T& value) +	{ +		return sizeof(T); +	} + +	static size_t measure() +	{ +		return sizeof(T); +	} +}; + +template<typename T> +struct MemFootprint<T*> +{ +	static size_t measure(const T* value) +	{ +		if (!value) +		{ +			return 0; +		} +		return MemFootprint<T>::measure(*value); +	} + +	static size_t measure() +	{ +		return MemFootprint<T>::measure(); +	} +}; + +template<typename T> +struct MemFootprint<std::basic_string<T> > +{ +	static size_t measure(const std::basic_string<T>& value) +	{ +		return value.capacity() * sizeof(T); +	} + +	static size_t measure() +	{ +		return sizeof(std::basic_string<T>); +	} +}; + +template<typename T> +struct MemFootprint<std::vector<T> > +{ +	static size_t measure(const std::vector<T>& value) +	{ +		return value.capacity() * MemFootprint<T>::measure(); +	} + +	static size_t measure() +	{ +		return sizeof(std::vector<T>); +	} +}; + +template<typename T> +struct MemFootprint<std::list<T> > +{ +	static size_t measure(const std::list<T>& value) +	{ +		return value.size() * (MemFootprint<T>::measure() + sizeof(void*) * 2); +	} + +	static size_t measure() +	{ +		return sizeof(std::list<T>); +	} +}; + +template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN> +class MemTrackable +{ +	template<typename TRACKED, typename TRACKED_IS_TRACKER> +	struct TrackMemImpl; + +	typedef MemTrackable<DERIVED> mem_trackable_t; + +public: +	typedef void mem_trackable_tag_t; + +	virtual ~MemTrackable() +	{ +		memDisclaim(mMemFootprint); +	} + +	void* operator new(size_t size)  +	{ +		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +		if (accumulator) +		{ +			accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); +			accumulator->mAllocatedCount++; +		} + +		return ::operator new(size); +	} + +	void operator delete(void* ptr, size_t size) +	{ +		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +		if (accumulator) +		{ +			accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); +			accumulator->mAllocatedCount--; +			accumulator->mDeallocatedCount++; +		} +		::operator delete(ptr); +	} + +	void *operator new [](size_t size) +	{ +		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +		if (accumulator) +		{ +			accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); +			accumulator->mAllocatedCount++; +		} + +		return ::operator new[](size); +	} + +	void operator delete[](void* ptr, size_t size) +	{ +		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +		if (accumulator) +		{ +			accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); +			accumulator->mAllocatedCount--; +			accumulator->mDeallocatedCount++; +		} +		::operator delete[](ptr); +	} + +	// claim memory associated with other objects/data as our own, adding to our calculated footprint +	template<typename CLAIM_T> +	CLAIM_T& memClaim(CLAIM_T& value) +	{ +		TrackMemImpl<CLAIM_T>::claim(*this, value); +		return value; +	} + +	template<typename CLAIM_T> +	const CLAIM_T& memClaim(const CLAIM_T& value) +	{ +		TrackMemImpl<CLAIM_T>::claim(*this, value); +		return value; +	} + + +	void memClaimAmount(size_t size) +	{ +		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +		mMemFootprint += size; +		if (accumulator) +		{ +			accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)size); +		} +	} + +	// remove memory we had claimed from our calculated footprint +	template<typename CLAIM_T> +	CLAIM_T& memDisclaim(CLAIM_T& value) +	{ +		TrackMemImpl<CLAIM_T>::disclaim(*this, value); +		return value; +	} + +	template<typename CLAIM_T> +	const CLAIM_T& memDisclaim(const CLAIM_T& value) +	{ +		TrackMemImpl<CLAIM_T>::disclaim(*this, value); +		return value; +	} + +	void memDisclaimAmount(size_t size) +	{ +		MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +		if (accumulator) +		{ +			accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)size); +		} +	} + +private: +	size_t mMemFootprint; + +	template<typename TRACKED, typename TRACKED_IS_TRACKER = void> +	struct TrackMemImpl +	{ +		static void claim(mem_trackable_t& tracker, const TRACKED& tracked) +		{ +			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +			if (accumulator) +			{ +				size_t footprint = MemFootprint<TRACKED>::measure(tracked); +				accumulator->mSize.sample(accumulator->mSize.getLastValue() + (F64)footprint); +				tracker.mMemFootprint += footprint; +			} +		} + +		static void disclaim(mem_trackable_t& tracker, const TRACKED& tracked) +		{ +			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +			if (accumulator) +			{ +				size_t footprint = MemFootprint<TRACKED>::measure(tracked); +				accumulator->mSize.sample(accumulator->mSize.getLastValue() - (F64)footprint); +				tracker.mMemFootprint -= footprint; +			} +		} +	}; + +	template<typename TRACKED> +	struct TrackMemImpl<TRACKED, typename TRACKED::mem_trackable_tag_t> +	{ +		static void claim(mem_trackable_t& tracker, TRACKED& tracked) +		{ +			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +			if (accumulator) +			{ +				accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() + (F64)MemFootprint<TRACKED>::measure(tracked)); +			} +		} + +		static void disclaim(mem_trackable_t& tracker, TRACKED& tracked) +		{ +			MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); +			if (accumulator) +			{ +				accumulator->mChildSize.sample(accumulator->mChildSize.getLastValue() - (F64)MemFootprint<TRACKED>::measure(tracked)); +			} +		} +	}; +}; + +} +#endif // LL_LLTRACE_H diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp new file mode 100644 index 0000000000..d32504b014 --- /dev/null +++ b/indra/llcommon/lltracerecording.cpp @@ -0,0 +1,944 @@ +/**  + * @file lltracesampler.cpp + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "linden_common.h" + +#include "lltrace.h" +#include "llfasttimer.h" +#include "lltracerecording.h" +#include "lltracethreadrecorder.h" +#include "llthread.h" + +namespace LLTrace +{ + + +/////////////////////////////////////////////////////////////////////// +// RecordingBuffers +/////////////////////////////////////////////////////////////////////// + +RecordingBuffers::RecordingBuffers()  +{} + +void RecordingBuffers::handOffTo(RecordingBuffers& other) +{ +	other.mCounts.reset(&mCounts); +	other.mSamples.reset(&mSamples); +	other.mEvents.reset(&mEvents); +	other.mStackTimers.reset(&mStackTimers); +	other.mMemStats.reset(&mMemStats); +} + +void RecordingBuffers::makePrimary() +{ +	mCounts.makePrimary(); +	mSamples.makePrimary(); +	mEvents.makePrimary(); +	mStackTimers.makePrimary(); +	mMemStats.makePrimary(); + +	ThreadRecorder* thread_recorder = get_thread_recorder().get(); +	AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers; +	// update stacktimer parent pointers +	for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++) +	{ +		TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(i); +		if (tree_node) +		{ +			timer_accumulator_buffer[i].mParent = tree_node->mParent; +		} +	} +} + +bool RecordingBuffers::isPrimary() const +{ +	return mCounts.isPrimary(); +} + +void RecordingBuffers::append( const RecordingBuffers& other ) +{ +	mCounts.addSamples(other.mCounts); +	mSamples.addSamples(other.mSamples); +	mEvents.addSamples(other.mEvents); +	mMemStats.addSamples(other.mMemStats); +	mStackTimers.addSamples(other.mStackTimers); +} + +void RecordingBuffers::merge( const RecordingBuffers& other) +{ +	mCounts.addSamples(other.mCounts, false); +	mSamples.addSamples(other.mSamples, false); +	mEvents.addSamples(other.mEvents, false); +	mMemStats.addSamples(other.mMemStats, false); +	// for now, hold out timers from merge, need to be displayed per thread +	//mStackTimers.addSamples(other.mStackTimers, false); +} + +void RecordingBuffers::reset(RecordingBuffers* other) +{ +	mCounts.reset(other ? &other->mCounts : NULL); +	mSamples.reset(other ? &other->mSamples : NULL); +	mEvents.reset(other ? &other->mEvents : NULL); +	mStackTimers.reset(other ? &other->mStackTimers : NULL); +	mMemStats.reset(other ? &other->mMemStats : NULL); +} + +void RecordingBuffers::flush() +{ +	mSamples.flush(); +} + +/////////////////////////////////////////////////////////////////////// +// Recording +/////////////////////////////////////////////////////////////////////// + +Recording::Recording()  +:	mElapsedSeconds(0) +{ +	mBuffers = new RecordingBuffers(); +} + +Recording::Recording( const Recording& other ) +{ +	// this will allow us to seamlessly start without affecting any data we've acquired from other +	setPlayState(PAUSED); + +	Recording& mutable_other = const_cast<Recording&>(other); +	EPlayState other_play_state = other.getPlayState(); +	mutable_other.pause(); + +	mBuffers = other.mBuffers; + +	LLStopWatchControlsMixin<Recording>::setPlayState(other_play_state); +	mutable_other.setPlayState(other_play_state); + +	// above call will clear mElapsedSeconds as a side effect, so copy it here +	mElapsedSeconds = other.mElapsedSeconds; +	mSamplingTimer = other.mSamplingTimer; +} + + +Recording::~Recording() +{ +	if (isStarted() && LLTrace::get_thread_recorder().notNull()) +	{ +		LLTrace::get_thread_recorder()->deactivate(this); +	} +} + +void Recording::update() +{ +	if (isStarted()) +	{ +		mBuffers.write()->flush(); +		LLTrace::get_thread_recorder()->bringUpToDate(this); +		mSamplingTimer.reset(); +	} +} + +void Recording::handleReset() +{ +	mBuffers.write()->reset(); + +	mElapsedSeconds = 0.0; +	mSamplingTimer.reset(); +} + +void Recording::handleStart() +{ +	mSamplingTimer.reset(); +	LLTrace::get_thread_recorder()->activate(this); +} + +void Recording::handleStop() +{ +	mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); +	mBuffers.write()->flush(); +	LLTrace::get_thread_recorder()->deactivate(this); +} + +void Recording::handleSplitTo(Recording& other) +{ +	mBuffers.write()->handOffTo(*other.mBuffers.write()); +} + +void Recording::appendRecording( const Recording& other ) +{ +	EPlayState play_state = getPlayState(); +	{ +		pause(); +		mBuffers.write()->append(*other.mBuffers); +		mElapsedSeconds += other.mElapsedSeconds; +	} +	setPlayState(play_state); +} + +void Recording::mergeRecording( const Recording& other) +{ +	EPlayState play_state = getPlayState(); +	{ +		pause(); +		mBuffers.write()->merge(*other.mBuffers); +	} +	setPlayState(play_state); +} + +LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat) +{ +	const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; +	update(); +	return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)  +				/ (F64)LLTrace::TimeBlock::countsPerSecond(); +} + +LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat) +{ +	const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; +	update(); +	return (F64)(accumulator.mSelfTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond(); +} + + +U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat) +{ +	update(); +	return mBuffers->mStackTimers[stat.getIndex()].mCalls; +} + +LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat) +{ +	const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; + +	update(); +	return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)  +				/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); +} + +LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat) +{ +	const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; + +	update(); +	return (F64)(accumulator.mSelfTimeCounter)  +			/ ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); +} + +F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat) +{ +	update(); +	return (F32)mBuffers->mStackTimers[stat.getIndex()].mCalls / mElapsedSeconds; +} + +LLUnit<LLUnits::Bytes, F64> Recording::getMin(const TraceType<MemStatAccumulator>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mSize.getMin(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getMean(const TraceType<MemStatAccumulator>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mSize.getMean(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getMax(const TraceType<MemStatAccumulator>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mSize.getMax(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getStandardDeviation(const TraceType<MemStatAccumulator>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mSize.getStandardDeviation(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getLastValue(const TraceType<MemStatAccumulator>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mSize.getLastValue(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMin(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMean(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getMax(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getStandardDeviation(); +} + +LLUnit<LLUnits::Bytes, F64> Recording::getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mChildSize.getLastValue(); +} + +U32 Recording::getSum(const TraceType<MemStatAccumulator::AllocationCountFacet>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mAllocatedCount; +} + +U32 Recording::getSum(const TraceType<MemStatAccumulator::DeallocationCountFacet>& stat) +{ +	update(); +	return mBuffers->mMemStats[stat.getIndex()].mAllocatedCount; +} + + +F64 Recording::getSum( const TraceType<CountAccumulator>& stat ) +{ +	update(); +	return mBuffers->mCounts[stat.getIndex()].getSum(); +} + +F64 Recording::getSum( const TraceType<EventAccumulator>& stat ) +{ +	update(); +	return (F64)mBuffers->mEvents[stat.getIndex()].getSum(); +} + +F64 Recording::getPerSec( const TraceType<CountAccumulator>& stat ) +{ +	update(); +	F64 sum = mBuffers->mCounts[stat.getIndex()].getSum(); +	return  (sum != 0.0)  +		? (sum / mElapsedSeconds) +		: 0.0; +} + +U32 Recording::getSampleCount( const TraceType<CountAccumulator>& stat ) +{ +	update(); +	return mBuffers->mCounts[stat.getIndex()].getSampleCount(); +} + +F64 Recording::getMin( const TraceType<SampleAccumulator>& stat ) +{ +	update(); +	return mBuffers->mSamples[stat.getIndex()].getMin(); +} + +F64 Recording::getMax( const TraceType<SampleAccumulator>& stat ) +{ +	update(); +	return mBuffers->mSamples[stat.getIndex()].getMax(); +} + +F64 Recording::getMean( const TraceType<SampleAccumulator>& stat ) +{ +	update(); +	return mBuffers->mSamples[stat.getIndex()].getMean(); +} + +F64 Recording::getStandardDeviation( const TraceType<SampleAccumulator>& stat ) +{ +	update(); +	return mBuffers->mSamples[stat.getIndex()].getStandardDeviation(); +} + +F64 Recording::getLastValue( const TraceType<SampleAccumulator>& stat ) +{ +	update(); +	return mBuffers->mSamples[stat.getIndex()].getLastValue(); +} + +U32 Recording::getSampleCount( const TraceType<SampleAccumulator>& stat ) +{ +	update(); +	return mBuffers->mSamples[stat.getIndex()].getSampleCount(); +} + +F64 Recording::getMin( const TraceType<EventAccumulator>& stat ) +{ +	update(); +	return mBuffers->mEvents[stat.getIndex()].getMin(); +} + +F64 Recording::getMax( const TraceType<EventAccumulator>& stat ) +{ +	update(); +	return mBuffers->mEvents[stat.getIndex()].getMax(); +} + +F64 Recording::getMean( const TraceType<EventAccumulator>& stat ) +{ +	update(); +	return mBuffers->mEvents[stat.getIndex()].getMean(); +} + +F64 Recording::getStandardDeviation( const TraceType<EventAccumulator>& stat ) +{ +	update(); +	return mBuffers->mEvents[stat.getIndex()].getStandardDeviation(); +} + +F64 Recording::getLastValue( const TraceType<EventAccumulator>& stat ) +{ +	update(); +	return mBuffers->mEvents[stat.getIndex()].getLastValue(); +} + +U32 Recording::getSampleCount( const TraceType<EventAccumulator>& stat ) +{ +	update(); +	return mBuffers->mEvents[stat.getIndex()].getSampleCount(); +} + +/////////////////////////////////////////////////////////////////////// +// PeriodicRecording +/////////////////////////////////////////////////////////////////////// + +PeriodicRecording::PeriodicRecording( U32 num_periods, EPlayState state)  +:	mAutoResize(num_periods == 0), +	mCurPeriod(0), +	mRecordingPeriods(num_periods ? num_periods : 1) +{ +	setPlayState(state); +} + +void PeriodicRecording::nextPeriod() +{ +	if (mAutoResize) +	{ +		mRecordingPeriods.push_back(Recording()); +	} + +	Recording& old_recording = getCurRecording(); + +	mCurPeriod = (mCurPeriod + 1) % mRecordingPeriods.size(); +	old_recording.splitTo(getCurRecording()); +} + + +void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) +{ +	if (other.mRecordingPeriods.empty()) return; + +	EPlayState play_state = getPlayState(); +	pause(); + +	EPlayState other_play_state = other.getPlayState(); +	other.pause(); + +	U32 other_recording_count = other.mRecordingPeriods.size(); + +	Recording& other_oldest_recording = other.mRecordingPeriods[(other.mCurPeriod + 1) % other.mRecordingPeriods.size()]; + +	// if I have a recording of any length, then close it off and start a fresh one +	if (getCurRecording().getDuration().value()) +	{ +		nextPeriod(); +	} +	getCurRecording().appendRecording(other_oldest_recording); + +	if (other_recording_count > 1) +	{ +		if (mAutoResize) +		{ +			for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count, +				end_index = (other.mCurPeriod + 1) % other_recording_count;  +				other_index != end_index;  +				other_index = (other_index + 1) % other_recording_count) +			{ +				llassert(other.mRecordingPeriods[other_index].getDuration() != 0.f  +							&& (mRecordingPeriods.empty()  +								|| other.mRecordingPeriods[other_index].getDuration() != mRecordingPeriods.back().getDuration())); +				mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]); +			} + +			mCurPeriod = mRecordingPeriods.size() - 1; +		} +		else +		{ +			size_t num_to_copy = llmin(	mRecordingPeriods.size(), other.mRecordingPeriods.size() - 1); +			std::vector<Recording>::iterator src_it = other.mRecordingPeriods.begin()  +														+ (	(other.mCurPeriod + 1									// oldest period +																+ (other.mRecordingPeriods.size() - num_to_copy))	// minus room for copy +															% other.mRecordingPeriods.size()); +			std::vector<Recording>::iterator dest_it = mRecordingPeriods.begin() + ((mCurPeriod + 1) % mRecordingPeriods.size()); + +			for(S32 i = 0; i < num_to_copy; i++) +			{ +				*dest_it = *src_it; + +				if (++src_it == other.mRecordingPeriods.end()) +				{ +					src_it = other.mRecordingPeriods.begin(); +				} + +				if (++dest_it == mRecordingPeriods.end()) +				{ +					dest_it = mRecordingPeriods.begin(); +				} +			} +		 +			mCurPeriod = (mCurPeriod + num_to_copy) % mRecordingPeriods.size(); +		} +	} + +	nextPeriod(); + +	setPlayState(play_state); +	other.setPlayState(other_play_state); +} + +LLUnit<LLUnits::Seconds, F64> PeriodicRecording::getDuration() const +{ +	LLUnit<LLUnits::Seconds, F64> duration; +	size_t num_periods = mRecordingPeriods.size(); +	for (size_t i = 1; i <= num_periods; i++) +	{ +		size_t index = (mCurPeriod + num_periods - i) % num_periods; +		duration += mRecordingPeriods[index].getDuration(); +	} +	return duration; +} + + +LLTrace::Recording PeriodicRecording::snapshotCurRecording() const +{ +	Recording recording_copy(getCurRecording()); +	recording_copy.stop(); +	return recording_copy; +} + + +Recording& PeriodicRecording::getLastRecording() +{ +	return getPrevRecording(1); +} + +const Recording& PeriodicRecording::getLastRecording() const +{ +	return getPrevRecording(1); +} + +Recording& PeriodicRecording::getCurRecording() +{ +	return mRecordingPeriods[mCurPeriod]; +} + +const Recording& PeriodicRecording::getCurRecording() const +{ +	return mRecordingPeriods[mCurPeriod]; +} + +Recording& PeriodicRecording::getPrevRecording( U32 offset ) +{ +	U32 num_periods = mRecordingPeriods.size(); +	offset = llclamp(offset, 0u, num_periods - 1); +	return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods]; +} + +const Recording& PeriodicRecording::getPrevRecording( U32 offset ) const +{ +	U32 num_periods = mRecordingPeriods.size(); +	offset = llclamp(offset, 0u, num_periods - 1); +	return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods]; +} + +void PeriodicRecording::handleStart() +{ +	getCurRecording().start(); +} + +void PeriodicRecording::handleStop() +{ +	getCurRecording().pause(); +} + +void PeriodicRecording::handleReset() +{ +	if (mAutoResize) +	{ +		mRecordingPeriods.clear(); +		mRecordingPeriods.push_back(Recording()); +	} +	else +	{ +		for (std::vector<Recording>::iterator it = mRecordingPeriods.begin(), end_it = mRecordingPeriods.end(); +			it != end_it; +			++it) +		{ +			it->reset(); +		} +	} +	mCurPeriod = 0; +	getCurRecording().setPlayState(getPlayState()); +} + +void PeriodicRecording::handleSplitTo(PeriodicRecording& other) +{ +	getCurRecording().splitTo(other.getCurRecording()); +} + + +F64 PeriodicRecording::getPeriodMean( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ ) +{ +	size_t total_periods = mRecordingPeriods.size(); +	num_periods = llmin(num_periods, total_periods); + +	F64 mean = 0; +	if (num_periods <= 0) { return mean; } + +	S32 total_sample_count = 0; + +	for (S32 i = 1; i <= num_periods; i++) +	{ +		S32 index = (mCurPeriod + total_periods - i) % total_periods; +		if (mRecordingPeriods[index].getDuration() > 0.f) +		{ +			S32 period_sample_count = mRecordingPeriods[index].getSampleCount(stat); +			mean += mRecordingPeriods[index].getMean(stat) * period_sample_count; +			total_sample_count += period_sample_count; +		} +	} + +	if (total_sample_count) +	{ +		mean = mean / total_sample_count; +	} +	return mean; +} + +F64 PeriodicRecording::getPeriodMin( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ ) +{ +	size_t total_periods = mRecordingPeriods.size(); +	num_periods = llmin(num_periods, total_periods); + +	F64 min_val = std::numeric_limits<F64>::max(); +	for (S32 i = 1; i <= num_periods; i++) +	{ +		S32 index = (mCurPeriod + total_periods - i) % total_periods; +		min_val = llmin(min_val, mRecordingPeriods[index].getMin(stat)); +	} +	return min_val; +} + +F64 PeriodicRecording::getPeriodMax( const TraceType<EventAccumulator>& stat, size_t num_periods /*= U32_MAX*/ ) +{ +	size_t total_periods = mRecordingPeriods.size(); +	num_periods = llmin(num_periods, total_periods); + +	F64 max_val = std::numeric_limits<F64>::min(); +	for (S32 i = 1; i <= num_periods; i++) +	{ +		S32 index = (mCurPeriod + total_periods - i) % total_periods; +		max_val = llmax(max_val, mRecordingPeriods[index].getMax(stat)); +	} +	return max_val; +} + +F64 PeriodicRecording::getPeriodMin( const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/ ) +{ +	size_t total_periods = mRecordingPeriods.size(); +	num_periods = llmin(num_periods, total_periods); + +	F64 min_val = std::numeric_limits<F64>::max(); +	for (S32 i = 1; i <= num_periods; i++) +	{ +		S32 index = (mCurPeriod + total_periods - i) % total_periods; +		min_val = llmin(min_val, mRecordingPeriods[index].getMin(stat)); +	} +	return min_val; +} + +F64 PeriodicRecording::getPeriodMax(const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/) +{ +	size_t total_periods = mRecordingPeriods.size(); +	num_periods = llmin(num_periods, total_periods); + +	F64 max_val = std::numeric_limits<F64>::min(); +	for (S32 i = 1; i <= num_periods; i++) +	{ +		S32 index = (mCurPeriod + total_periods - i) % total_periods; +		max_val = llmax(max_val, mRecordingPeriods[index].getMax(stat)); +	} +	return max_val; +} + + +F64 PeriodicRecording::getPeriodMean( const TraceType<SampleAccumulator>& stat, size_t num_periods /*= U32_MAX*/ ) +{ +	size_t total_periods = mRecordingPeriods.size(); +	num_periods = llmin(num_periods, total_periods); + +	LLUnit<LLUnits::Seconds, F64> total_duration = 0.f; + +	F64 mean = 0; +	if (num_periods <= 0) { return mean; } + +	for (S32 i = 1; i <= num_periods; i++) +	{ +		S32 index = (mCurPeriod + total_periods - i) % total_periods; +		if (mRecordingPeriods[index].getDuration() > 0.f) +		{ +			LLUnit<LLUnits::Seconds, F64> recording_duration = mRecordingPeriods[index].getDuration(); +			mean += mRecordingPeriods[index].getMean(stat) * recording_duration.value(); +			total_duration += recording_duration; +		} +	} + +	if (total_duration.value()) +	{ +		mean = mean / total_duration; +	} +	return mean; +} + + + +/////////////////////////////////////////////////////////////////////// +// ExtendableRecording +/////////////////////////////////////////////////////////////////////// + +void ExtendableRecording::extend() +{ +	// stop recording to get latest data +	mPotentialRecording.stop(); +	// push the data back to accepted recording +	mAcceptedRecording.appendRecording(mPotentialRecording); +	// flush data, so we can start from scratch +	mPotentialRecording.reset(); +	// go back to play state we were in initially +	mPotentialRecording.setPlayState(getPlayState()); +} + +void ExtendableRecording::handleStart() +{ +	mPotentialRecording.start(); +} + +void ExtendableRecording::handleStop() +{ +	mPotentialRecording.pause(); +} + +void ExtendableRecording::handleReset() +{ +	mAcceptedRecording.reset(); +	mPotentialRecording.reset(); +} + +void ExtendableRecording::handleSplitTo(ExtendableRecording& other) +{ +	mPotentialRecording.splitTo(other.mPotentialRecording); +} + + +/////////////////////////////////////////////////////////////////////// +// ExtendablePeriodicRecording +/////////////////////////////////////////////////////////////////////// + + +ExtendablePeriodicRecording::ExtendablePeriodicRecording()  +:	mAcceptedRecording(0),  +	mPotentialRecording(0) +{} + +void ExtendablePeriodicRecording::extend() +{ +	llassert(mPotentialRecording.getPlayState() == getPlayState()); +	// stop recording to get latest data +	mPotentialRecording.pause(); +	// push the data back to accepted recording +	mAcceptedRecording.appendPeriodicRecording(mPotentialRecording); +	// flush data, so we can start from scratch +	mPotentialRecording.reset(); +	// go back to play state we were in initially +	mPotentialRecording.setPlayState(getPlayState()); +} + + +void ExtendablePeriodicRecording::handleStart() +{ +	mPotentialRecording.start(); +} + +void ExtendablePeriodicRecording::handleStop() +{ +	mPotentialRecording.pause(); +} + +void ExtendablePeriodicRecording::handleReset() +{ +	mAcceptedRecording.reset(); +	mPotentialRecording.reset(); +} + +void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& other) +{ +	mPotentialRecording.splitTo(other.mPotentialRecording); +} + + +PeriodicRecording& get_frame_recording() +{ +	static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(1000, PeriodicRecording::STARTED)); +	return *sRecording; +} + +} + +void LLStopWatchControlsMixinCommon::start() +{ +	switch (mPlayState) +	{ +	case STOPPED: +		handleReset(); +		handleStart(); +		break; +	case PAUSED: +		handleStart(); +		break; +	case STARTED: +		handleReset(); +		break; +	default: +		llassert(false); +		break; +	} +	mPlayState = STARTED; +} + +void LLStopWatchControlsMixinCommon::stop() +{ +	switch (mPlayState) +	{ +	case STOPPED: +		break; +	case PAUSED: +		break; +	case STARTED: +		handleStop(); +		break; +	default: +		llassert(false); +		break; +	} +	mPlayState = STOPPED; +} + +void LLStopWatchControlsMixinCommon::pause() +{ +	switch (mPlayState) +	{ +	case STOPPED: +		break; +	case PAUSED: +		break; +	case STARTED: +		handleStop(); +		break; +	default: +		llassert(false); +		break; +	} +	mPlayState = PAUSED; +} + +void LLStopWatchControlsMixinCommon::resume() +{ +	switch (mPlayState) +	{ +	case STOPPED: +		handleStart(); +		break; +	case PAUSED: +		handleStart(); +		break; +	case STARTED: +		break; +	default: +		llassert(false); +		break; +	} +	mPlayState = STARTED; +} + +void LLStopWatchControlsMixinCommon::restart() +{ +	switch (mPlayState) +	{ +	case STOPPED: +		handleReset(); +		handleStart(); +		break; +	case PAUSED: +		handleReset(); +		handleStart(); +		break; +	case STARTED: +		handleReset(); +		break; +	default: +		llassert(false); +		break; +	} +	mPlayState = STARTED; +} + +void LLStopWatchControlsMixinCommon::reset() +{ +	handleReset(); +} + +void LLStopWatchControlsMixinCommon::setPlayState( EPlayState state ) +{ +	switch(state) +	{ +	case STOPPED: +		stop(); +		break; +	case PAUSED: +		pause(); +		break; +	case STARTED: +		start(); +		break; +	default: +		llassert(false); +		break; +	} + +	mPlayState = state; +} diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h new file mode 100644 index 0000000000..4651bfcb61 --- /dev/null +++ b/indra/llcommon/lltracerecording.h @@ -0,0 +1,527 @@ +/**  + * @file lltracerecording.h + * @brief Sampling object for collecting runtime statistics originating from lltrace. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLTRACERECORDING_H +#define LL_LLTRACERECORDING_H + +#include "stdtypes.h" +#include "llpreprocessor.h" + +#include "llpointer.h" +#include "lltimer.h" +#include "lltrace.h" + +class LLStopWatchControlsMixinCommon +{ +public: +	virtual ~LLStopWatchControlsMixinCommon() {} + +	enum EPlayState +	{ +		STOPPED, +		PAUSED, +		STARTED +	}; + +	void start(); +	void stop(); +	void pause(); +	void resume(); +	void restart(); +	void reset(); + +	bool isStarted() const { return mPlayState == STARTED; } +	bool isPaused() const  { return mPlayState == PAUSED; } +	bool isStopped() const { return mPlayState == STOPPED; } +	EPlayState getPlayState() const { return mPlayState; } +	// force play state to specific value by calling appropriate handle* methods +	void setPlayState(EPlayState state); + +protected: +	LLStopWatchControlsMixinCommon() +	:	mPlayState(STOPPED) +	{} + +private: +	// trigger active behavior (without reset) +	virtual void handleStart() = 0; +	// stop active behavior +	virtual void handleStop() = 0; +	// clear accumulated state, can be called while started +	virtual void handleReset() = 0; + +	EPlayState mPlayState; +}; + +template<typename DERIVED> +class LLStopWatchControlsMixin +:	public LLStopWatchControlsMixinCommon +{ +public: +	typedef LLStopWatchControlsMixin<DERIVED> self_t; +	virtual void splitTo(DERIVED& other) +	{ +		EPlayState play_state = getPlayState(); +		stop(); +		other.reset(); + +		handleSplitTo(other); + +		other.setPlayState(play_state); +	} + +	virtual void splitFrom(DERIVED& other) +	{ +		static_cast<self_t&>(other).handleSplitTo(*static_cast<DERIVED*>(this)); +	} +private: +	// atomically stop this object while starting the other +	// no data can be missed in between stop and start +	virtual void handleSplitTo(DERIVED& other) {}; + +}; + +namespace LLTrace +{ +	struct RecordingBuffers : public LLRefCount +	{ +		RecordingBuffers(); + +		void handOffTo(RecordingBuffers& other); +		void makePrimary(); +		bool isPrimary() const; + +		void append(const RecordingBuffers& other); +		void merge(const RecordingBuffers& other); +		void reset(RecordingBuffers* other = NULL); +		void flush(); + +		AccumulatorBuffer<CountAccumulator>	 			mCounts; +		AccumulatorBuffer<SampleAccumulator>			mSamples; +		AccumulatorBuffer<EventAccumulator>				mEvents; +		AccumulatorBuffer<TimeBlockAccumulator> 		mStackTimers; +		AccumulatorBuffer<MemStatAccumulator> 			mMemStats; +	}; + +	class Recording  +	:	public LLStopWatchControlsMixin<Recording> +	{ +	public: +		Recording(); + +		Recording(const Recording& other); +		~Recording(); + +		// accumulate data from subsequent, non-overlapping recording +		void appendRecording(const Recording& other); + +		// gather data from recording, ignoring time relationship (for example, pulling data from slave threads) +		void mergeRecording(const Recording& other); + +		// grab latest recorded data +		void update(); + +		// ensure that buffers are exclusively owned by this recording +		void makeUnique() { mBuffers.makeUnique(); } + +		// Timer accessors +		LLUnit<LLUnits::Seconds, F64> getSum(const TraceType<TimeBlockAccumulator>& stat); +		LLUnit<LLUnits::Seconds, F64> getSum(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat); +		U32 getSum(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat); + +		LLUnit<LLUnits::Seconds, F64> getPerSec(const TraceType<TimeBlockAccumulator>& stat); +		LLUnit<LLUnits::Seconds, F64> getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeFacet>& stat); +		F32 getPerSec(const TraceType<TimeBlockAccumulator::CallCountFacet>& stat); + +		// Memory accessors +		LLUnit<LLUnits::Bytes, F64> getMin(const TraceType<MemStatAccumulator>& stat); +		LLUnit<LLUnits::Bytes, F64> getMean(const TraceType<MemStatAccumulator>& stat); +		LLUnit<LLUnits::Bytes, F64> getMax(const TraceType<MemStatAccumulator>& stat); +		LLUnit<LLUnits::Bytes, F64> getStandardDeviation(const TraceType<MemStatAccumulator>& stat); +		LLUnit<LLUnits::Bytes, F64> getLastValue(const TraceType<MemStatAccumulator>& stat); + +		LLUnit<LLUnits::Bytes, F64> getMin(const TraceType<MemStatAccumulator::ChildMemFacet>& stat); +		LLUnit<LLUnits::Bytes, F64> getMean(const TraceType<MemStatAccumulator::ChildMemFacet>& stat); +		LLUnit<LLUnits::Bytes, F64> getMax(const TraceType<MemStatAccumulator::ChildMemFacet>& stat); +		LLUnit<LLUnits::Bytes, F64> getStandardDeviation(const TraceType<MemStatAccumulator::ChildMemFacet>& stat); +		LLUnit<LLUnits::Bytes, F64> getLastValue(const TraceType<MemStatAccumulator::ChildMemFacet>& stat); + +		U32 getSum(const TraceType<MemStatAccumulator::AllocationCountFacet>& stat); +		U32 getSum(const TraceType<MemStatAccumulator::DeallocationCountFacet>& stat); + +		// CountStatHandle accessors +		F64 getSum(const TraceType<CountAccumulator>& stat); +		template <typename T> +		T getSum(const CountStatHandle<T>& stat) +		{ +			return (T)getSum(static_cast<const TraceType<CountAccumulator>&> (stat)); +		} + +		F64 getPerSec(const TraceType<CountAccumulator>& stat); +		template <typename T> +		T getPerSec(const CountStatHandle<T>& stat) +		{ +			return (T)getPerSec(static_cast<const TraceType<CountAccumulator>&> (stat)); +		} + +		U32 getSampleCount(const TraceType<CountAccumulator>& stat); + + +		// SampleStatHandle accessors +		F64 getMin(const TraceType<SampleAccumulator>& stat); +		template <typename T> +		T getMin(const SampleStatHandle<T>& stat) +		{ +			return (T)getMin(static_cast<const TraceType<SampleAccumulator>&> (stat)); +		} + +		F64 getMean(const TraceType<SampleAccumulator>& stat); +		template <typename T> +		T getMean(SampleStatHandle<T>& stat) +		{ +			return (T)getMean(static_cast<const TraceType<SampleAccumulator>&> (stat)); +		} + +		F64 getMax(const TraceType<SampleAccumulator>& stat); +		template <typename T> +		T getMax(const SampleStatHandle<T>& stat) +		{ +			return (T)getMax(static_cast<const TraceType<SampleAccumulator>&> (stat)); +		} + +		F64 getStandardDeviation(const TraceType<SampleAccumulator>& stat); +		template <typename T> +		T getStandardDeviation(const SampleStatHandle<T>& stat) +		{ +			return (T)getStandardDeviation(static_cast<const TraceType<SampleAccumulator>&> (stat)); +		} + +		F64 getLastValue(const TraceType<SampleAccumulator>& stat); +		template <typename T> +		T getLastValue(const SampleStatHandle<T>& stat) +		{ +			return (T)getLastValue(static_cast<const TraceType<SampleAccumulator>&> (stat)); +		} + +		U32 getSampleCount(const TraceType<SampleAccumulator>& stat); + +		// EventStatHandle accessors +		F64 getSum(const TraceType<EventAccumulator>& stat); +		template <typename T> +		T getSum(const EventStatHandle<T>& stat) +		{ +			return (T)getSum(static_cast<const TraceType<EventAccumulator>&> (stat)); +		} + +		F64 getMin(const TraceType<EventAccumulator>& stat); +		template <typename T> +		T getMin(const EventStatHandle<T>& stat) +		{ +			return (T)getMin(static_cast<const TraceType<EventAccumulator>&> (stat)); +		} + +		F64 getMax(const TraceType<EventAccumulator>& stat); +		template <typename T> +		T getMax(const EventStatHandle<T>& stat) +		{ +			return (T)getMax(static_cast<const TraceType<EventAccumulator>&> (stat)); +		} + +		F64 getMean(const TraceType<EventAccumulator>& stat); +		template <typename T> +		T getMean(EventStatHandle<T>& stat) +		{ +			return (T)getMean(static_cast<const TraceType<EventAccumulator>&> (stat)); +		} + +		F64 getStandardDeviation(const TraceType<EventAccumulator>& stat); +		template <typename T> +		T getStandardDeviation(const EventStatHandle<T>& stat) +		{ +			return (T)getStandardDeviation(static_cast<const TraceType<EventAccumulator>&> (stat)); +		} + +		F64 getLastValue(const TraceType<EventAccumulator>& stat); +		template <typename T> +		T getLastValue(const EventStatHandle<T>& stat) +		{ +			return (T)getLastValue(static_cast<const TraceType<EventAccumulator>&> (stat)); +		} + +		U32 getSampleCount(const TraceType<EventAccumulator>& stat); + +		LLUnit<LLUnits::Seconds, F64> getDuration() const { return LLUnit<LLUnits::Seconds, F64>(mElapsedSeconds); } + +	protected: +		friend class ThreadRecorder; + +		// implementation for LLStopWatchControlsMixin +		/*virtual*/ void handleStart(); +		/*virtual*/ void handleStop(); +		/*virtual*/ void handleReset(); +		/*virtual*/ void handleSplitTo(Recording& other); + +		// returns data for current thread +		class ThreadRecorder* getThreadRecorder();  + +		LLTimer				mSamplingTimer; +		F64					mElapsedSeconds; +		LLCopyOnWritePointer<RecordingBuffers>	mBuffers; +	}; + +	class LL_COMMON_API PeriodicRecording +	:	public LLStopWatchControlsMixin<PeriodicRecording> +	{ +	public: +		PeriodicRecording(U32 num_periods, EPlayState state = STOPPED); + +		void nextPeriod(); +		U32 getNumPeriods() { return mRecordingPeriods.size(); } + +		LLUnit<LLUnits::Seconds, F64> getDuration() const; + +		void appendPeriodicRecording(PeriodicRecording& other); +		Recording& getLastRecording(); +		const Recording& getLastRecording() const; +		Recording& getCurRecording(); +		const Recording& getCurRecording() const; +		Recording& getPrevRecording(U32 offset); +		const Recording& getPrevRecording(U32 offset) const; +		Recording snapshotCurRecording() const; + +		// catch all for stats that have a defined sum +		template <typename T> +		typename T::value_t getPeriodMin(const TraceType<T>& stat, size_t num_periods = U32_MAX) +		{ +			size_t total_periods = mRecordingPeriods.size(); +			num_periods = llmin(num_periods, total_periods); + +			typename T::value_t min_val = std::numeric_limits<typename T::value_t>::max(); +			for (S32 i = 1; i <= num_periods; i++) +			{ +				S32 index = (mCurPeriod + total_periods - i) % total_periods; +				min_val = llmin(min_val, mRecordingPeriods[index].getSum(stat)); +			} +			return min_val; +		} + +		F64 getPeriodMin(const TraceType<SampleAccumulator>& stat, size_t num_periods = U32_MAX); +		template<typename T> +		T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = U32_MAX) +		{ +			return T(getPeriodMin(static_cast<const TraceType<SampleAccumulator>&>(stat), num_periods)); +		} + +		F64 getPeriodMin(const TraceType<EventAccumulator>& stat, size_t num_periods = U32_MAX); +		template<typename T> +		T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = U32_MAX) +		{ +			return T(getPeriodMin(static_cast<const TraceType<EventAccumulator>&>(stat), num_periods)); +		} + +		template <typename T> +		F64 getPeriodMinPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX) +		{ +			size_t total_periods = mRecordingPeriods.size(); +			num_periods = llmin(num_periods, total_periods); + +			F64 min_val = std::numeric_limits<F64>::max(); +			for (S32 i = 1; i <= num_periods; i++) +			{ +				S32 index = (mCurPeriod + total_periods - i) % total_periods; +				min_val = llmin(min_val, mRecordingPeriods[index].getPerSec(stat)); +			} +			return min_val; +		} + +		// catch all for stats that have a defined sum +		template <typename T> +		typename T::value_t getPeriodMax(const TraceType<T>& stat, size_t num_periods = U32_MAX) +		{ +			size_t total_periods = mRecordingPeriods.size(); +			num_periods = llmin(num_periods, total_periods); + +			typename T::value_t max_val = std::numeric_limits<typename T::value_t>::min(); +			for (S32 i = 1; i <= num_periods; i++) +			{ +				S32 index = (mCurPeriod + total_periods - i) % total_periods; +				max_val = llmax(max_val, mRecordingPeriods[index].getSum(stat)); +			} +			return max_val; +		} + +		F64 getPeriodMax(const TraceType<SampleAccumulator>& stat, size_t num_periods = U32_MAX); +		template<typename T> +		T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = U32_MAX) +		{ +			return T(getPeriodMax(static_cast<const TraceType<SampleAccumulator>&>(stat), num_periods)); +		} + +		F64 getPeriodMax(const TraceType<EventAccumulator>& stat, size_t num_periods = U32_MAX); +		template<typename T> +		T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = U32_MAX) +		{ +			return T(getPeriodMax(static_cast<const TraceType<EventAccumulator>&>(stat), num_periods)); +		} + +		template <typename T> +		F64 getPeriodMaxPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX) +		{ +			size_t total_periods = mRecordingPeriods.size(); +			num_periods = llmin(num_periods, total_periods); + +			F64 max_val = std::numeric_limits<F64>::min(); +			for (S32 i = 1; i <= num_periods; i++) +			{ +				S32 index = (mCurPeriod + total_periods - i) % total_periods; +				max_val = llmax(max_val, mRecordingPeriods[index].getPerSec(stat)); +			} +			return max_val; +		} + +		// catch all for stats that have a defined sum +		template <typename T> +		typename T::mean_t getPeriodMean(const TraceType<T >& stat, size_t num_periods = U32_MAX) +		{ +			size_t total_periods = mRecordingPeriods.size(); +			num_periods = llmin(num_periods, total_periods); + +			typename T::mean_t mean = 0; +			if (num_periods <= 0) { return mean; } + +			for (S32 i = 1; i <= num_periods; i++) +			{ +				S32 index = (mCurPeriod + total_periods - i) % total_periods; +				if (mRecordingPeriods[index].getDuration() > 0.f) +				{ +					mean += mRecordingPeriods[index].getSum(stat); +				} +			} +			mean = mean / num_periods; +			return mean; +		} + +		F64 getPeriodMean(const TraceType<SampleAccumulator>& stat, size_t num_periods = U32_MAX); +		template<typename T>  +		T getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = U32_MAX) +		{ +			return T(getPeriodMean(static_cast<const TraceType<SampleAccumulator>&>(stat), num_periods)); +		} + +		F64 getPeriodMean(const TraceType<EventAccumulator>& stat, size_t num_periods = U32_MAX); +		template<typename T> +		T getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = U32_MAX) +		{ +			return T(getPeriodMean(static_cast<const TraceType<EventAccumulator>&>(stat), num_periods)); +		} + +		template <typename T> +		typename T::mean_t getPeriodMeanPerSec(const TraceType<T>& stat, size_t num_periods = U32_MAX) +		{ +			size_t total_periods = mRecordingPeriods.size(); +			num_periods = llmin(num_periods, total_periods); + +			typename T::mean_t mean = 0; +			if (num_periods <= 0) { return mean; } + +			for (S32 i = 1; i <= num_periods; i++) +			{ +				S32 index = (mCurPeriod + total_periods - i) % total_periods; +				if (mRecordingPeriods[index].getDuration() > 0.f) +				{ +					mean += mRecordingPeriods[index].getPerSec(stat); +				} +			} +			mean = mean / num_periods; +			return mean; +		} + +	private: +		// implementation for LLStopWatchControlsMixin +		/*virtual*/ void handleStart(); +		/*virtual*/ void handleStop(); +		/*virtual*/ void handleReset(); +		/*virtual*/ void handleSplitTo(PeriodicRecording& other); + +	private: +		std::vector<Recording>	mRecordingPeriods; +		const bool	mAutoResize; +		S32			mCurPeriod; +	}; + +	PeriodicRecording& get_frame_recording(); + +	class ExtendableRecording +	:	public LLStopWatchControlsMixin<ExtendableRecording> +	{ +	public: +		void extend(); + +		Recording& getAcceptedRecording() { return mAcceptedRecording; } +		const Recording& getAcceptedRecording() const {return mAcceptedRecording;} + +		Recording& getPotentialRecording()				{ return mPotentialRecording; } +		const Recording& getPotentialRecording() const	{ return mPotentialRecording;} + +	private: +		// implementation for LLStopWatchControlsMixin +		/*virtual*/ void handleStart(); +		/*virtual*/ void handleStop(); +		/*virtual*/ void handleReset(); +		/*virtual*/ void handleSplitTo(ExtendableRecording& other); + +	private: +		Recording mAcceptedRecording; +		Recording mPotentialRecording; +	}; + +	class ExtendablePeriodicRecording +	:	public LLStopWatchControlsMixin<ExtendablePeriodicRecording> +	{ +	public: +		ExtendablePeriodicRecording(); +		void extend(); + +		PeriodicRecording& getAcceptedRecording()				{ return mAcceptedRecording; } +		const PeriodicRecording& getAcceptedRecording() const	{return mAcceptedRecording;} +		 +		PeriodicRecording& getPotentialRecording()				{ return mPotentialRecording; } +		const PeriodicRecording& getPotentialRecording() const	{return mPotentialRecording;} + +	private: +		// implementation for LLStopWatchControlsMixin +		/*virtual*/ void handleStart(); +		/*virtual*/ void handleStop(); +		/*virtual*/ void handleReset(); +		/*virtual*/ void handleSplitTo(ExtendablePeriodicRecording& other); + +	private: +		PeriodicRecording mAcceptedRecording; +		PeriodicRecording mPotentialRecording; +	}; +} + +#endif // LL_LLTRACERECORDING_H diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp new file mode 100644 index 0000000000..c1a0700eff --- /dev/null +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -0,0 +1,291 @@ +/**  + * @file lltracethreadrecorder.cpp + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "linden_common.h" + +#include "lltracethreadrecorder.h" +#include "llfasttimer.h" + +namespace LLTrace +{ + + +/////////////////////////////////////////////////////////////////////// +// ThreadRecorder +/////////////////////////////////////////////////////////////////////// + +ThreadRecorder::ThreadRecorder() +{ +	//NB: the ordering of initialization in this function is very fragile due to a large number of implicit dependencies +	set_thread_recorder(this); +	TimeBlock& root_time_block = TimeBlock::getRootTimeBlock(); + +	ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance(); +	timer_stack->mTimeBlock = &root_time_block; +	timer_stack->mActiveTimer = NULL; + +	mNumTimeBlockTreeNodes = AccumulatorBuffer<TimeBlockAccumulator>::getDefaultBuffer()->size(); +	mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes]; + +	mThreadRecording.start(); + +	// initialize time block parent pointers +	for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances();  +		it != end_it;  +		++it) +	{ +		TimeBlock& time_block = *it; +		TimeBlockTreeNode& tree_node = mTimeBlockTreeNodes[it->getIndex()]; +		tree_node.mBlock = &time_block; +		tree_node.mParent = &root_time_block; + +		it->getPrimaryAccumulator()->mParent = &root_time_block; +	} + +	mRootTimer = new BlockTimer(root_time_block); +	timer_stack->mActiveTimer = mRootTimer; + +	TimeBlock::getRootTimeBlock().getPrimaryAccumulator()->mActiveCount = 1; +} + +ThreadRecorder::~ThreadRecorder() +{ +	delete mRootTimer; + +	if (!mActiveRecordings.empty()) +	{ +		std::for_each(mActiveRecordings.begin(), mActiveRecordings.end(), DeletePointer()); +		mActiveRecordings.clear(); +	} + +	set_thread_recorder(NULL); +	delete[] mTimeBlockTreeNodes; +} + +TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index) +{ +	if (0 <= index && index < mNumTimeBlockTreeNodes) +	{ +		return &mTimeBlockTreeNodes[index]; +	} +	return NULL; +} + + +void ThreadRecorder::activate( Recording* recording ) +{ +	ActiveRecording* active_recording = new ActiveRecording(recording); +	if (!mActiveRecordings.empty()) +	{ +		mActiveRecordings.back()->mPartialRecording.handOffTo(active_recording->mPartialRecording); +	} +	mActiveRecordings.push_back(active_recording); + +	mActiveRecordings.back()->mPartialRecording.makePrimary(); +} + +ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( Recording* recording ) +{ +	if (mActiveRecordings.empty()) return mActiveRecordings.rend(); + +	mActiveRecordings.back()->mPartialRecording.flush(); + +	active_recording_list_t::reverse_iterator it, end_it; +	for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); +		it != end_it; +		++it) +	{ +		ActiveRecording* cur_recording = *it; + +		active_recording_list_t::reverse_iterator next_it = it; +		++next_it; + +		// if we have another recording further down in the stack... +		if (next_it != mActiveRecordings.rend()) +		{ +			// ...push our gathered data down to it +			(*next_it)->mPartialRecording.append(cur_recording->mPartialRecording); +		} + +		// copy accumulated measurements into result buffer and clear accumulator (mPartialRecording) +		cur_recording->movePartialToTarget(); + +		if (cur_recording->mTargetRecording == recording) +		{ +			// found the recording, so return it +			break; +		} +	} + +	if (it == end_it) +	{ +		llwarns << "Recording not active on this thread" << llendl; +	} + +	return it; +} + +void ThreadRecorder::deactivate( Recording* recording ) +{ +	active_recording_list_t::reverse_iterator it = bringUpToDate(recording); +	if (it != mActiveRecordings.rend()) +	{ +		// and if we've found the recording we wanted to update +		active_recording_list_t::reverse_iterator next_it = it; +		++next_it; +		if (next_it != mActiveRecordings.rend()) +		{ +			(*next_it)->mPartialRecording.makePrimary(); +		} + +		active_recording_list_t::iterator recording_to_remove = (++it).base(); +		llassert((*recording_to_remove)->mTargetRecording == recording); +		delete *recording_to_remove; +		mActiveRecordings.erase(recording_to_remove); +	} +} + +ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target )  +:	mTargetRecording(target) +{ +} + +void ThreadRecorder::ActiveRecording::movePartialToTarget() +{ +	mTargetRecording->mBuffers.write()->append(mPartialRecording); +	// reset based on self to keep history +	mPartialRecording.reset(&mPartialRecording); +} + + +/////////////////////////////////////////////////////////////////////// +// SlaveThreadRecorder +/////////////////////////////////////////////////////////////////////// + +SlaveThreadRecorder::SlaveThreadRecorder(MasterThreadRecorder& master) +:	mMasterRecorder(master) +{ +	mMasterRecorder.addSlaveThread(this); +} + +SlaveThreadRecorder::~SlaveThreadRecorder() +{ +	mMasterRecorder.removeSlaveThread(this); +} + +void SlaveThreadRecorder::pushToMaster() +{ +	mThreadRecording.stop(); +	{ +		LLMutexLock(mMasterRecorder.getSlaveListMutex()); +		mSharedData.appendFrom(mThreadRecording); +	} +	mThreadRecording.start(); +} + +void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source ) +{ +	LLMutexLock lock(&mRecordingMutex); +	appendRecording(source); +} + +void SlaveThreadRecorder::SharedData::appendTo( Recording& sink ) +{ +	LLMutexLock lock(&mRecordingMutex); +	sink.appendRecording(*this); +} + +void SlaveThreadRecorder::SharedData::mergeFrom( const RecordingBuffers& source ) +{ +	LLMutexLock lock(&mRecordingMutex); +	mBuffers.write()->merge(source); +} + +void SlaveThreadRecorder::SharedData::mergeTo( RecordingBuffers& sink ) +{ +	LLMutexLock lock(&mRecordingMutex); +	sink.merge(*mBuffers); +} + +void SlaveThreadRecorder::SharedData::reset() +{ +	LLMutexLock lock(&mRecordingMutex); +	Recording::reset(); +} + + +/////////////////////////////////////////////////////////////////////// +// MasterThreadRecorder +/////////////////////////////////////////////////////////////////////// + +static LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_SLAVES("Pull slave trace data"); +void MasterThreadRecorder::pullFromSlaveThreads() +{ +	LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_SLAVES); +	if (mActiveRecordings.empty()) return; + +	LLMutexLock lock(&mSlaveListMutex); + +	RecordingBuffers& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; +	for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); +		it != end_it; +		++it) +	{ +		// ignore block timing info for now +		(*it)->mSharedData.mergeTo(target_recording_buffers); +		(*it)->mSharedData.reset(); +	} +} + +void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child ) +{ +	LLMutexLock lock(&mSlaveListMutex); + +	mSlaveThreadRecorders.push_back(child); +} + +void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child ) +{ +	LLMutexLock lock(&mSlaveListMutex); + +	for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); +		it != end_it; +		++it) +	{ +		if ((*it) == child) +		{ +			mSlaveThreadRecorders.erase(it); +			break; +		} +	} +} + +void MasterThreadRecorder::pushToMaster() +{} + +MasterThreadRecorder::MasterThreadRecorder() +{} + +} diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h new file mode 100644 index 0000000000..bf3701304f --- /dev/null +++ b/indra/llcommon/lltracethreadrecorder.h @@ -0,0 +1,126 @@ +/**  + * @file lltrace.h + * @brief Runtime statistics accumulation. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLTRACETHREADRECORDER_H +#define LL_LLTRACETHREADRECORDER_H + +#include "stdtypes.h" +#include "llpreprocessor.h" + +#include "llmutex.h" +#include "lltracerecording.h" + +namespace LLTrace +{ +	class LL_COMMON_API ThreadRecorder +	{ +	protected: +		struct ActiveRecording; +		typedef std::vector<ActiveRecording*> active_recording_list_t; +	public: +		ThreadRecorder(); + +		virtual ~ThreadRecorder(); + +		void activate(Recording* recording); +		void deactivate(Recording* recording); +		active_recording_list_t::reverse_iterator bringUpToDate(Recording* recording); + +		virtual void pushToMaster() = 0; + +		TimeBlockTreeNode* getTimeBlockTreeNode(S32 index); + +	protected: +		struct ActiveRecording +		{ +			ActiveRecording(Recording* target); + +			Recording*			mTargetRecording; +			RecordingBuffers	mPartialRecording; + +			void movePartialToTarget(); +		}; +		Recording					mThreadRecording; + +		active_recording_list_t		mActiveRecordings; + +		class BlockTimer*			mRootTimer; +		TimeBlockTreeNode*			mTimeBlockTreeNodes; +		size_t						mNumTimeBlockTreeNodes; +	}; + +	class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder +	{ +	public: +		MasterThreadRecorder(); + +		void addSlaveThread(class SlaveThreadRecorder* child); +		void removeSlaveThread(class SlaveThreadRecorder* child); + +		/*virtual */ void pushToMaster(); + +		// call this periodically to gather stats data from slave threads +		void pullFromSlaveThreads(); + +		LLMutex* getSlaveListMutex() { return &mSlaveListMutex; } + + +	private: + +		typedef std::list<class SlaveThreadRecorder*> slave_thread_recorder_list_t; + +		slave_thread_recorder_list_t	mSlaveThreadRecorders;	// list of slave thread recorders associated with this master +		LLMutex							mSlaveListMutex;		// protects access to slave list +	}; + +	class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder +	{ +	public: +		SlaveThreadRecorder(MasterThreadRecorder& master); +		~SlaveThreadRecorder(); + +		// call this periodically to gather stats data for master thread to consume +		/*virtual*/ void pushToMaster(); + +		MasterThreadRecorder* 	mMaster; + +		class SharedData : public Recording +		{ +		public: +			void appendFrom(const Recording& source); +			void appendTo(Recording& sink); +			void mergeFrom(const RecordingBuffers& source); +			void mergeTo(RecordingBuffers& sink); +			void reset(); +		private: +			LLMutex		mRecordingMutex; +		}; +		SharedData				mSharedData; +		MasterThreadRecorder&	mMasterRecorder; +	}; +} + +#endif // LL_LLTRACETHREADRECORDER_H diff --git a/indra/llcommon/lltypeinfolookup.h b/indra/llcommon/lltypeinfolookup.h deleted file mode 100755 index 0b6862444e..0000000000 --- a/indra/llcommon/lltypeinfolookup.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @file   lltypeinfolookup.h - * @author Nat Goodspeed - * @date   2012-04-08 - * @brief  Template data structure like std::map<std::type_info*, T> - *  - * $LicenseInfo:firstyear=2012&license=viewerlgpl$ - * Copyright (c) 2012, Linden Research, Inc. - * $/LicenseInfo$ - */ - -#if ! defined(LL_LLTYPEINFOLOOKUP_H) -#define LL_LLTYPEINFOLOOKUP_H - -#include <boost/unordered_map.hpp> -#include <boost/functional/hash.hpp> -#include <boost/optional.hpp> -#include <functional>               // std::binary_function -#include <typeinfo> - -/** - * The following helper classes are based on the Boost.Unordered documentation: - * http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html - */ - -/** - * Compute hash for a string passed as const char* - */ -struct const_char_star_hash: public std::unary_function<const char*, std::size_t> -{ -    std::size_t operator()(const char* str) const -    { -        std::size_t seed = 0; -        for ( ; *str; ++str) -        { -            boost::hash_combine(seed, *str); -        } -        return seed; -    } -}; - -/** - * Compute equality for strings passed as const char* - * - * I (nat) suspect that this is where the default behavior breaks for the - * const char* values returned from std::type_info::name(). If you compare the - * two const char* pointer values, as a naive, unspecialized implementation - * will surely do, they'll compare unequal. - */ -struct const_char_star_equal: public std::binary_function<const char*, const char*, bool> -{ -    bool operator()(const char* lhs, const char* rhs) const -    { -        return strcmp(lhs, rhs) == 0; -    } -}; - -/** - * LLTypeInfoLookup is specifically designed for use cases for which you might - * consider std::map<std::type_info*, VALUE>. We have several such data - * structures in the viewer. The trouble with them is that at least on Linux, - * you can't rely on always getting the same std::type_info* for a given type: - * different load modules will produce different std::type_info*. - * LLTypeInfoLookup contains a workaround to address this issue. - * - * The API deliberately diverges from std::map in several respects: - * * It avoids iterators, not only begin()/end() but also as return values - *   from insert() and find(). This bypasses transform_iterator overhead. - * * Since we literally use compile-time types as keys, the essential insert() - *   and find() methods accept the key type as a @em template parameter, - *   accepting and returning value_type as a normal runtime value. This is to - *   permit future optimization (e.g. compile-time type hashing) without - *   changing the API. - */ -template <typename VALUE> -class LLTypeInfoLookup -{ -    // Use this for our underlying implementation: lookup by -    // std::type_info::name() string. This is one of the rare cases in which I -    // dare use const char* directly, rather than std::string, because I'm -    // sure that every value returned by std::type_info::name() is static. -    // HOWEVER, specify our own hash + equality functors: naively comparing -    // distinct const char* values won't work. -    typedef boost::unordered_map<const char*, VALUE, -                                 const_char_star_hash, const_char_star_equal> impl_map_type; - -public: -    typedef VALUE value_type; - -    LLTypeInfoLookup() {} - -    bool empty() const { return mMap.empty(); } -    std::size_t size() const { return mMap.size(); } - -    template <typename KEY> -    bool insert(const value_type& value) -    { -        // Obtain and store the std::type_info::name() string as the key. -        // Return just the bool from std::map::insert()'s return pair. -        return mMap.insert(typename impl_map_type::value_type(typeid(KEY).name(), value)).second; -    } - -    template <typename KEY> -    boost::optional<value_type> find() const -    { -        // Use the std::type_info::name() string as the key. -        typename impl_map_type::const_iterator found = mMap.find(typeid(KEY).name()); -        if (found == mMap.end()) -            return boost::optional<value_type>(); -        return found->second; -    } - -private: -    impl_map_type mMap; -}; - -#endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */ diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h new file mode 100644 index 0000000000..a5406fb3f0 --- /dev/null +++ b/indra/llcommon/llunit.h @@ -0,0 +1,481 @@ +/**  + * @file llunit.h + * @brief Unit conversion classes + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLUNIT_H +#define LL_LLUNIT_H + +#include "stdtypes.h" +#include "llpreprocessor.h" +#include "llerrorlegacy.h" + +namespace LLUnits +{ + +template<typename DERIVED_UNITS_TAG, typename BASE_UNITS_TAG, typename VALUE_TYPE> +struct ConversionFactor +{ +	static F64 get() +	{ +		// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template +		llstatic_assert_template(DERIVED_UNITS_TAG, false,  "Cannot convert between types."); +	} +}; + +template<typename BASE_UNITS_TAG, typename VALUE_TYPE> +struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG, VALUE_TYPE> +{ +	static F64 get()  +	{  +		return 1;  +	} +}; + +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE> +struct LLUnit +{ +	typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> self_t; +	typedef STORAGE_TYPE storage_t; + +	// value initialization +	LLUnit(storage_t value = storage_t()) +	:	mValue(value) +	{} + +	// unit initialization and conversion +	template<typename OTHER_UNIT, typename OTHER_STORAGE> +	LLUnit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other) +	:	mValue(convert(other)) +	{} +	 +	// value assignment +	self_t& operator = (storage_t value) +	{ +		mValue = value; +		return *this; +	} + +	// unit assignment +	template<typename OTHER_UNIT, typename OTHER_STORAGE> +	self_t& operator = (LLUnit<OTHER_UNIT, OTHER_STORAGE> other) +	{ +		mValue = convert(other); +		return *this; +	} + +	storage_t value() const +	{ +		return mValue; +	} + +	template<typename NEW_UNIT_TYPE> LLUnit<NEW_UNIT_TYPE, STORAGE_TYPE> as() +	{ +		return LLUnit<NEW_UNIT_TYPE, STORAGE_TYPE>(*this); +	} + + +	void operator += (storage_t value) +	{ +		mValue += value; +	} + +	template<typename OTHER_UNIT, typename OTHER_STORAGE> +	void operator += (LLUnit<OTHER_UNIT, OTHER_STORAGE> other) +	{ +		mValue += convert(other); +	} + +	void operator -= (storage_t value) +	{ +		mValue -= value; +	} + +	template<typename OTHER_UNIT, typename OTHER_STORAGE> +	void operator -= (LLUnit<OTHER_UNIT, OTHER_STORAGE> other) +	{ +		mValue -= convert(other); +	} + +	void operator *= (storage_t multiplicand) +	{ +		mValue *= multiplicand; +	} + +	template<typename OTHER_UNIT, typename OTHER_STORAGE> +	void operator *= (LLUnit<OTHER_UNIT, OTHER_STORAGE> multiplicand) +	{ +		// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template +		llstatic_assert_template(OTHER_UNIT, false, "Multiplication of unit types not supported."); +	} + +	void operator /= (storage_t divisor) +	{ +		mValue /= divisor; +	} + +	template<typename OTHER_UNIT, typename OTHER_STORAGE> +	void operator /= (LLUnit<OTHER_UNIT, OTHER_STORAGE> divisor) +	{ +		// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template +		llstatic_assert_template(OTHER_UNIT, false, "Illegal in-place division of unit types."); +	} + +	template<typename SOURCE_UNITS, typename SOURCE_STORAGE> +	static storage_t convert(LLUnit<SOURCE_UNITS, SOURCE_STORAGE> v)  +	{  +		return (storage_t)(v.value()  +			* LLUnits::ConversionFactor<SOURCE_UNITS, typename UNIT_TYPE::base_unit_t, SOURCE_STORAGE>::get()  +			* LLUnits::ConversionFactor<typename UNIT_TYPE::base_unit_t, UNIT_TYPE, STORAGE_TYPE>::get());  +	} + +protected: +	storage_t mValue; +}; + +template<typename UNIT_TYPE, typename STORAGE_TYPE> +struct LLUnitImplicit : public LLUnit<UNIT_TYPE, STORAGE_TYPE> +{ +	typedef LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> self_t; +	typedef typename LLUnit<UNIT_TYPE, STORAGE_TYPE>::storage_t storage_t; +	typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> base_t; + +	LLUnitImplicit(storage_t value = storage_t()) +	:	base_t(value) +	{} + +	template<typename OTHER_UNIT, typename OTHER_STORAGE> +	LLUnitImplicit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other) +	:	base_t(convert(other)) +	{} + +	// unlike LLUnit, LLUnitImplicit is *implicitly* convertable to a POD scalar (F32, S32, etc) +	// this allows for interoperability with legacy code +	operator storage_t() const +	{ +		return base_t::value(); +	} +}; + +// +// operator + +// +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second) +{ +	LLUnit<UNIT_TYPE1, STORAGE_TYPE1> result(first); +	result += second; +	return result; +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnit<UNIT_TYPE, STORAGE_TYPE> operator + (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) +{ +	LLUnit<UNIT_TYPE, STORAGE_TYPE> result(first); +	result += second; +	return result; +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnit<UNIT_TYPE, STORAGE_TYPE> operator + (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) +{ +	LLUnit<UNIT_TYPE, STORAGE_TYPE> result(first); +	result += second; +	return result; +} + +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second) +{ +	LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first); +	result += second; +	return result; +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator + (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) +{ +	LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first); +	result += second; +	return result; +} + +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator + (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second) +{ +	LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first); +	result += second; +	return result; +} + +// +// operator - +// +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator - (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second) +{ +	LLUnit<UNIT_TYPE1, STORAGE_TYPE1> result(first); +	result -= second; +	return result; +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnit<UNIT_TYPE, STORAGE_TYPE> operator - (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) +{ +	LLUnit<UNIT_TYPE, STORAGE_TYPE> result(first); +	result -= second; +	return result; +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) +{ +	LLUnit<UNIT_TYPE, STORAGE_TYPE> result(first); +	result -= second; +	return result; +} + +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator - (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second) +{ +	LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> result(first); +	result -= second; +	return result; +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator - (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) +{ +	LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first); +	result -= second; +	return result; +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> second) +{ +	LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> result(first); +	result -= second; +	return result; +} + +// +// operator * +// +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnit<UNIT_TYPE, STORAGE_TYPE> operator * (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) +{ +	return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first * second.value())); +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnit<UNIT_TYPE, STORAGE_TYPE> operator * (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) +{ +	return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() * second)); +} + +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +LLUnit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnit<UNIT_TYPE1, STORAGE_TYPE1>, LLUnit<UNIT_TYPE2, STORAGE_TYPE2>) +{ +	// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template +	llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported."); +	return LLUnit<UNIT_TYPE1, STORAGE_TYPE1>(); +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator * (SCALAR_TYPE first, LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> second) +{ +	return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first * second.value()); +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator * (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) +{ +	return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first.value() * second); +} + +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> operator * (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2>) +{ +	// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template +	llstatic_assert_template(STORAGE_TYPE1, false, "Multiplication of unit types results in new unit type - not supported."); +	return LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1>(); +} + +// +// operator / +// +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) +{ +	return SCALAR_TYPE(first / second.value()); +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnit<UNIT_TYPE, STORAGE_TYPE> operator / (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) +{ +	return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() / second)); +} + +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +STORAGE_TYPE1 operator / (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second) +{ +	// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template +	return STORAGE_TYPE1(first.value() / second.value()); +} + +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> +LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator / (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) +{ +	return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() / second)); +} + +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> +STORAGE_TYPE1 operator / (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second) +{ +	// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template +	return STORAGE_TYPE1(first.value() / second.value()); +} + +#define COMPARISON_OPERATORS(op)                                                                                     \ +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>                                            \ +bool operator op (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second)                                         \ +{                                                                                                                    \ +	return first op second.value();                                                                                  \ +}                                                                                                                    \ +	                                                                                                                 \ +template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE>                                            \ +bool operator op (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second)                                         \ +{                                                                                                                    \ +	return first.value() op second;                                                                                  \ +}                                                                                                                    \ +	                                                                                                                 \ +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>                   \ +bool operator op (LLUnitImplicit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnitImplicit<UNIT_TYPE2, STORAGE_TYPE2> second) \ +{                                                                                                                    \ +	return first.value() op first.convert(second);                                                                   \ +}                                                                                                                    \ +	                                                                                                                 \ +template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2>                   \ +	bool operator op (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_TYPE2, STORAGE_TYPE2> second)             \ +{                                                                                                                    \ +	return first.value() op first.convert(second);                                                                   \ +} + +COMPARISON_OPERATORS(<) +COMPARISON_OPERATORS(<=) +COMPARISON_OPERATORS(>) +COMPARISON_OPERATORS(>=) +COMPARISON_OPERATORS(==) +COMPARISON_OPERATORS(!=) + + +template<typename T>  +struct LLGetUnitLabel +{ +	static const char* getUnitLabel() { return ""; } +}; + +template<typename T, typename STORAGE_T> +struct LLGetUnitLabel<LLUnit<T, STORAGE_T> > +{ +	static const char* getUnitLabel() { return T::getUnitLabel(); } +}; + +// +// Unit declarations +// +namespace LLUnits +{ +template<typename T> +T rawValue(T val) { return val; } + +template<typename UNIT_TYPE, typename STORAGE_TYPE>  +STORAGE_TYPE rawValue(LLUnit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); } + +template<typename UNIT_TYPE, typename STORAGE_TYPE>  +STORAGE_TYPE rawValue(LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> val) { return val.value(); } + +#define LL_DECLARE_DERIVED_UNIT(conversion_factor, base_unit_name, unit_name, unit_label)		\ +struct unit_name                                                                                \ +{                                                                                               \ +	typedef base_unit_name base_unit_t;                                                         \ +	static const char* getUnitLabel() { return unit_label; }									\ +};                                                                                              \ +template<typename STORAGE_TYPE>                                                                 \ +struct ConversionFactor<unit_name, base_unit_name, STORAGE_TYPE>                                \ +{                                                                                               \ +	static F64 get()                                                                            \ +	{                                                                                           \ +		return (F64)conversion_factor;                                                          \ +	}                                                                                           \ +};                                                                                              \ +	                                                                                            \ +template<typename STORAGE_TYPE>                                                                 \ +struct ConversionFactor<base_unit_name, unit_name, STORAGE_TYPE>						        \ +{                                                                                               \ +	static F64 get()                                                                            \ +	{                                                                                           \ +		return (F64)(1.0 / (conversion_factor));                                                \ +	}                                                                                           \ +} + +#define LL_DECLARE_BASE_UNIT(base_unit_name, unit_label) \ +struct base_unit_name { typedef base_unit_name base_unit_t; static const char* getUnitLabel() { return unit_label; }} + +LL_DECLARE_BASE_UNIT(Bytes, "B"); +LL_DECLARE_DERIVED_UNIT(1024, Bytes, Kibibytes, "KiB"); +LL_DECLARE_DERIVED_UNIT(1024 * 1024, Bytes, Mibibytes, "MiB"); +LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024, Bytes, Gibibytes, "GiB"); +LL_DECLARE_DERIVED_UNIT(1.0 / 8.0, Bytes, Bits, "b"); +LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Kibibits, "Kib"); +LL_DECLARE_DERIVED_UNIT(1024 / 8, Bytes, Mibibits, "Mib"); +LL_DECLARE_DERIVED_UNIT(1024 * 1024 * 1024 / 8, Bytes, Gibibits, "Gib"); + +LL_DECLARE_BASE_UNIT(Seconds, "s"); +LL_DECLARE_DERIVED_UNIT(60, Seconds, Minutes, "min"); +LL_DECLARE_DERIVED_UNIT(60 * 60, Seconds, Hours, "h"); +LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Seconds, Milliseconds, "ms"); +LL_DECLARE_DERIVED_UNIT(1.0 / 1000000.0, Seconds, Microseconds, "\x09\x3cs"); +LL_DECLARE_DERIVED_UNIT(1.0 / 1000000000.0, Seconds, Nanoseconds, "ns"); + +LL_DECLARE_BASE_UNIT(Meters, "m"); +LL_DECLARE_DERIVED_UNIT(1000, Meters, Kilometers, "km"); +LL_DECLARE_DERIVED_UNIT(1.0 / 100.0, Meters, Centimeters, "cm"); +LL_DECLARE_DERIVED_UNIT(1.0 / 1000.0, Meters, Millimeters, "mm"); + +LL_DECLARE_BASE_UNIT(Hertz, "Hz"); +LL_DECLARE_DERIVED_UNIT(1000, Hertz, Kilohertz, "KHz"); +LL_DECLARE_DERIVED_UNIT(1000 * 1000, Hertz, Megahertz, "MHz"); +LL_DECLARE_DERIVED_UNIT(1000 * 1000 * 1000, Hertz, Gigahertz, "GHz"); + +LL_DECLARE_BASE_UNIT(Radians, "rad"); +LL_DECLARE_DERIVED_UNIT(DEG_TO_RAD, Radians, Degrees, "deg"); + + +} // namespace LLUnits + +#endif // LL_LLUNIT_H diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index 0aaa50d231..ba4b670b9a 100755 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -27,9 +27,7 @@  // We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes.  #if LL_WINDOWS -#undef WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> +#include "llwin32headers.h"  // ugh, this is ugly.  We need to straighten out our linking for this library  #pragma comment(lib, "IPHLPAPI.lib")  #include <iphlpapi.h> diff --git a/indra/llcommon/lluuidhashmap.h b/indra/llcommon/lluuidhashmap.h deleted file mode 100755 index e294670030..0000000000 --- a/indra/llcommon/lluuidhashmap.h +++ /dev/null @@ -1,583 +0,0 @@ -/**  - * @file lluuidhashmap.h - * @brief A uuid based hash map. - * - * $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$ - */ - -#ifndef LL_LLUUIDHASHMAP_H -#define LL_LLUUIDHASHMAP_H - -#include "stdtypes.h" -#include "llerror.h" -#include "lluuid.h" - -// UUID hash map - -	/* -	LLUUIDHashMap<uuid_pair, 32> foo(test_equals); -	LLUUIDHashMapIter<uuid_pair, 32> bar(&foo); - -	LLDynamicArray<LLUUID> source_ids; -	const S32 COUNT = 100000; -	S32 q; -	for (q = 0; q < COUNT; q++) -	{ -		llinfos << "Creating" << llendl; -		LLUUID id; -		id.generate(); -		//llinfos << q << ":" << id << llendl; -		uuid_pair pair; -		pair.mUUID = id; -		pair.mValue = q; -		foo.set(id, pair); -		source_ids.put(id); -		//ms_sleep(1); -	} - -	uuid_pair cur; -	llinfos << "Iterating" << llendl; -	for (cur = bar.first(); !bar.done(); cur = bar.next()) -	{ -		if (source_ids[cur.mValue] != cur.mUUID) -		{ -			llerrs << "Incorrect value iterated!" << llendl; -		} -		//llinfos << cur.mValue << ":" << cur.mUUID << llendl; -		//ms_sleep(1); -	} - -	llinfos << "Finding" << llendl; -	for (q = 0; q < COUNT; q++) -	{ -		cur = foo.get(source_ids[q]); -		if (source_ids[cur.mValue] != cur.mUUID) -		{ -			llerrs << "Incorrect value found!" << llendl; -		} -		//llinfos << res.mValue << ":" << res.mUUID << llendl; -		//ms_sleep(1); -	} -	 -	llinfos << "Removing" << llendl; -	for (q = 0; q < COUNT/2; q++) -	{ -		if (!foo.remove(source_ids[q])) -		{ -			llerrs << "Remove failed!" << llendl; -		} -		//ms_sleep(1); -	} - -	llinfos << "Iterating" << llendl; -	for (cur = bar.first(); !bar.done(); cur = bar.next()) -	{ -		if (source_ids[cur.mValue] != cur.mUUID) -		{ -			llerrs << "Incorrect value found!" << llendl; -		} -		//llinfos << cur.mValue << ":" << cur.mUUID << llendl; -		//ms_sleep(1); -	} -	llinfos << "Done with UUID map test" << llendl; - -	return 0; -	*/ - - -// -// LLUUIDHashNode -// - -template <class DATA, int SIZE> -class LLUUIDHashNode -{ -public: -	LLUUIDHashNode(); - -public: -	S32 mCount; -	U8	mKey[SIZE]; -	DATA mData[SIZE]; -	LLUUIDHashNode<DATA, SIZE> *mNextNodep; -}; - - -// -// LLUUIDHashNode implementation -// -template <class DATA, int SIZE> -LLUUIDHashNode<DATA, SIZE>::LLUUIDHashNode() -{ -	mCount = 0; -	mNextNodep = NULL; -} - - -template <class DATA_TYPE, int SIZE> -class LLUUIDHashMap -{ -public: -	// basic constructor including sorter -	LLUUIDHashMap(BOOL (*equals)(const LLUUID &uuid, const DATA_TYPE &data), -				  const DATA_TYPE &null_data); -	~LLUUIDHashMap(); - -	inline DATA_TYPE &get(const LLUUID &uuid); -	inline BOOL check(const LLUUID &uuid) const; -	inline DATA_TYPE &set(const LLUUID &uuid, const DATA_TYPE &type); -	inline BOOL remove(const LLUUID &uuid); -	void removeAll(); - -	inline S32 getLength() const; // Warning, NOT O(1!) -public: -	BOOL (*mEquals)(const LLUUID &uuid, const DATA_TYPE &data); -	LLUUIDHashNode<DATA_TYPE, SIZE> mNodes[256]; - -	S32 mIterCount; -protected: -	DATA_TYPE mNull; -}; - - -// -// LLUUIDHashMap implementation -// - -template <class DATA_TYPE, int SIZE> -LLUUIDHashMap<DATA_TYPE, SIZE>::LLUUIDHashMap(BOOL (*equals)(const LLUUID &uuid, const DATA_TYPE &data), -											  const DATA_TYPE &null_data) -:	mEquals(equals), -	mIterCount(0), -	mNull(null_data) -{ } - -template <class DATA_TYPE, int SIZE> -LLUUIDHashMap<DATA_TYPE, SIZE>::~LLUUIDHashMap() -{ -	removeAll(); -} - -template <class DATA_TYPE, int SIZE> -void LLUUIDHashMap<DATA_TYPE, SIZE>::removeAll() -{ -	S32 bin; -	for (bin = 0; bin < 256; bin++) -	{ -		LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[bin]; - -		BOOL first = TRUE; -		while (nodep) -		{ -			S32 i; -			const S32 count = nodep->mCount; - -			// Iterate through all members of this node -			for (i = 0; i < count; i++) -			{ -				nodep->mData[i] = mNull; -			} - -			nodep->mCount = 0; -			// Done with all objects in this node, go to the next. - -			LLUUIDHashNode<DATA_TYPE, SIZE>* curp = nodep; -			nodep = nodep->mNextNodep; - -			// Delete the node if it's not the first node -			if (first) -			{ -				first = FALSE; -				curp->mNextNodep = NULL; -			} -			else -			{ -				delete curp; -			} -		} -	} -} - -template <class DATA_TYPE, int SIZE> -inline S32 LLUUIDHashMap<DATA_TYPE, SIZE>::getLength() const -{ -	S32 count = 0; -	S32 bin; -	for (bin = 0; bin < 256; bin++) -	{ -		LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = (LLUUIDHashNode<DATA_TYPE, SIZE>*) &mNodes[bin]; -		while (nodep) -		{ -			count += nodep->mCount; -			nodep = nodep->mNextNodep; -		} -	} -	return count; -} - -template <class DATA_TYPE, int SIZE> -inline DATA_TYPE &LLUUIDHashMap<DATA_TYPE, SIZE>::get(const LLUUID &uuid) -{ -	LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[uuid.mData[0]]; - -	// Grab the second byte of the UUID, which is the key for the node data -	const S32 second_byte = uuid.mData[1]; -	while (nodep) -	{ -		S32 i; -		const S32 count = nodep->mCount; - -		// Iterate through all members of this node -		for (i = 0; i < count; i++) -		{ -			if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i])) -			{ -				// The second byte matched, and our equality test passed. -				// We found it. -				return nodep->mData[i]; -			} -		} - -		// Done with all objects in this node, go to the next. -		nodep = nodep->mNextNodep; -	} -	return mNull; -} - - -template <class DATA_TYPE, int SIZE> -inline BOOL LLUUIDHashMap<DATA_TYPE, SIZE>::check(const LLUUID &uuid) const -{ -	const LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[uuid.mData[0]]; - -	// Grab the second byte of the UUID, which is the key for the node data -	const S32 second_byte = uuid.mData[1]; -	while (nodep) -	{ -		S32 i; -		const S32 count = nodep->mCount; - -		// Iterate through all members of this node -		for (i = 0; i < count; i++) -		{ -			if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i])) -			{ -				// The second byte matched, and our equality test passed. -				// We found it. -				return TRUE; -			} -		} - -		// Done with all objects in this node, go to the next. -		nodep = nodep->mNextNodep; -	} - -	// Didn't find anything -	return FALSE; -} - - -template <class DATA_TYPE, int SIZE> -inline DATA_TYPE &LLUUIDHashMap<DATA_TYPE, SIZE>::set(const LLUUID &uuid, const DATA_TYPE &data) -{ -	// Set is just like a normal find, except that if we find a match -	// we replace it with the input value. -	// If we don't find a match, we append to the end of the list. - -	LLUUIDHashNode<DATA_TYPE, SIZE>* nodep = &mNodes[uuid.mData[0]]; - -	const S32 second_byte = uuid.mData[1]; -	while (1) -	{ -		const S32 count = nodep->mCount; - -		S32 i; -		for (i = 0; i < count; i++) -		{ -			if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i])) -			{ -				// We found a match for this key, replace the data with -				// the incoming data. -				nodep->mData[i] = data; -				return nodep->mData[i]; -			} -		} -		if (!nodep->mNextNodep) -		{ -			// We've iterated through all of the keys without finding a match -			if (i < SIZE) -			{ -				// There's still some space on this node, append -				// the key and data to it. -				nodep->mKey[i] = second_byte; -				nodep->mData[i] = data; -				nodep->mCount++; - -				return nodep->mData[i]; -			} -			else -			{ -				// This node is full, append a new node to the end. -				nodep->mNextNodep = new LLUUIDHashNode<DATA_TYPE, SIZE>; -				nodep->mNextNodep->mKey[0] = second_byte; -				nodep->mNextNodep->mData[0] = data; -				nodep->mNextNodep->mCount = 1; - -				return nodep->mNextNodep->mData[0]; -			} -		} - -		// No match on this node, go to the next -		nodep = nodep->mNextNodep; -	} -} - - -template <class DATA_TYPE, int SIZE> -inline BOOL LLUUIDHashMap<DATA_TYPE, SIZE>::remove(const LLUUID &uuid) -{ -	if (mIterCount) -	{ -		// We don't allow remove when we're iterating, it's bad karma! -		llerrs << "Attempted remove while an outstanding iterator in LLUUIDHashMap!" << llendl; -	} -	// Remove is the trickiest operation. -	// What we want to do is swap the last element of the last -	// node if we find the one that we want to remove, but we have -	// to deal with deleting the node from the tail if it's empty, but -	// NOT if it's the only node left. - -	LLUUIDHashNode<DATA_TYPE, SIZE> *nodep = &mNodes[uuid.mData[0]]; - -	// Not empty, we need to search through the nodes -	const S32 second_byte = uuid.mData[1]; - -	// A modification of the standard search algorithm. -	while (nodep) -	{ -		const S32 count = nodep->mCount; - -		S32 i; -		for (i = 0; i < count; i++) -		{ -			if ((nodep->mKey[i] == second_byte) && mEquals(uuid, nodep->mData[i])) -			{ -				// We found the node that we want to remove. -				// Find the last (and next-to-last) node, and the index of the last -				// element.  We could conceviably start from the node we're on, -				// but that makes it more complicated, this is easier. - -				LLUUIDHashNode<DATA_TYPE, SIZE> *prevp = &mNodes[uuid.mData[0]]; -				LLUUIDHashNode<DATA_TYPE, SIZE> *lastp = prevp; - -				// Find the last and next-to-last -				while (lastp->mNextNodep) -				{ -					prevp = lastp; -					lastp = lastp->mNextNodep; -				} - -				// First, swap in the last to the current location. -				nodep->mKey[i] = lastp->mKey[lastp->mCount - 1]; -				nodep->mData[i] = lastp->mData[lastp->mCount - 1]; - -				// Now, we delete the entry -				lastp->mCount--; -				lastp->mData[lastp->mCount] = mNull; - -				if (!lastp->mCount) -				{ -					// We deleted the last element! -					if (lastp != &mNodes[uuid.mData[0]]) -					{ -						// Only blitz the node if it's not the head -						// Set the previous node to point to NULL, then -						// blitz the empty last node -						prevp->mNextNodep = NULL; -						delete lastp; -					} -				} -				return TRUE; -			} -		} - -		// Iterate to the next node, we've scanned all the entries in this one. -		nodep = nodep->mNextNodep; -	} -	return FALSE; -} - - -// -// LLUUIDHashMapIter -// - -template <class DATA_TYPE, int SIZE> -class LLUUIDHashMapIter -{ -public: -	LLUUIDHashMapIter(LLUUIDHashMap<DATA_TYPE, SIZE> *hash_mapp); -	~LLUUIDHashMapIter(); - - -	inline void reset(); -	inline void first(); -	inline void next(); -	inline BOOL done() const; - -	DATA_TYPE& operator*() const -	{ -		return mCurHashNodep->mData[mCurHashNodeKey]; -	} -	DATA_TYPE* operator->() const -	{ -		return &(operator*()); -	} - -protected: -	LLUUIDHashMap<DATA_TYPE, SIZE> *mHashMapp; -	LLUUIDHashNode<DATA_TYPE, SIZE> *mCurHashNodep; - -	S32 mCurHashMapNodeNum; -	S32 mCurHashNodeKey; - -	DATA_TYPE mNull; -}; - - -// -// LLUUIDHashMapIter Implementation -// -template <class DATA_TYPE, int SIZE> -LLUUIDHashMapIter<DATA_TYPE, SIZE>::LLUUIDHashMapIter(LLUUIDHashMap<DATA_TYPE, SIZE> *hash_mapp) -{ -	mHashMapp = hash_mapp; -	mCurHashNodep = NULL; -	mCurHashMapNodeNum = 0; -	mCurHashNodeKey = 0; -} - -template <class DATA_TYPE, int SIZE> -LLUUIDHashMapIter<DATA_TYPE, SIZE>::~LLUUIDHashMapIter() -{ -	reset(); -} - -template <class DATA_TYPE, int SIZE> -inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::reset() -{ -	if (mCurHashNodep) -	{ -		// We're partway through an iteration, we can clean up now -		mHashMapp->mIterCount--; -		mCurHashNodep = NULL; -	} -} - -template <class DATA_TYPE, int SIZE> -inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::first() -{ -	// Iterate through until we find the first non-empty node; -	S32 i; -	for (i = 0; i < 256; i++) -	{ -		if (mHashMapp->mNodes[i].mCount) -		{ -			if (!mCurHashNodep) -			{ -				// Increment, since it's no longer safe for us to do a remove -				mHashMapp->mIterCount++; -			} - -			mCurHashNodep = &mHashMapp->mNodes[i]; -			mCurHashMapNodeNum = i; -			mCurHashNodeKey = 0; -			//return mCurHashNodep->mData[0]; -			return; -		} -	} - -	// Completely empty! -	mCurHashNodep = NULL; -	//return mNull; -	return; -} - -template <class DATA_TYPE, int SIZE> -inline BOOL LLUUIDHashMapIter<DATA_TYPE, SIZE>::done() const -{ -	return mCurHashNodep ? FALSE : TRUE; -} - -template <class DATA_TYPE, int SIZE> -inline void LLUUIDHashMapIter<DATA_TYPE, SIZE>::next() -{ -	// No current entry, this iterator is done -	if (!mCurHashNodep) -	{ -		//return mNull; -		return; -	} - -	// Go to the next element -	mCurHashNodeKey++; -	if (mCurHashNodeKey < mCurHashNodep->mCount) -	{ -		// We're not done with this node, return the current element -		//return mCurHashNodep->mData[mCurHashNodeKey]; -		return; -	} - -	// Done with this node, move to the next -	mCurHashNodep = mCurHashNodep->mNextNodep; -	if (mCurHashNodep) -	{ -		// Return the first element -		mCurHashNodeKey = 0; -		//return mCurHashNodep->mData[0]; -		return; -	} - -	// Find the next non-empty node (keyed on the first byte) -	mCurHashMapNodeNum++; - -	S32 i; -	for (i = mCurHashMapNodeNum; i < 256; i++) -	{ -		if (mHashMapp->mNodes[i].mCount) -		{ -			// We found one that wasn't empty -			mCurHashNodep = &mHashMapp->mNodes[i]; -			mCurHashMapNodeNum = i; -			mCurHashNodeKey = 0; -			//return mCurHashNodep->mData[0]; -			return; -		} -	} - -	// OK, we're done, nothing else to iterate -	mCurHashNodep = NULL; -	mHashMapp->mIterCount--; // Decrement since we're safe to do removes now -	//return mNull; -} - -#endif // LL_LLUUIDHASHMAP_H diff --git a/indra/llcommon/reflective.h b/indra/llcommon/llwin32headers.h index da5c5a2630..cf85067d95 100755..100644 --- a/indra/llcommon/reflective.h +++ b/indra/llcommon/llwin32headers.h @@ -1,10 +1,8 @@  /**  - * @file reflective.h - * @author Babbage - * @date 2006-05-15 - * @brief Interface that must be implemented by all reflective classes. + * @file llwindows.h + * @brief sanitized include of windows header files   * - * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc.   *  @@ -26,17 +24,19 @@   * $/LicenseInfo$   */ -#ifndef LL_REFLECTIVE_H -#define LL_REFLECTIVE_H +#ifndef LL_LLWINDOWS_H +#define LL_LLWINDOWS_H -class LLMetaClass; -class LL_COMMON_API LLReflective -{ -public: -	LLReflective(); -	virtual ~LLReflective(); -	 -	virtual const LLMetaClass& getMetaClass() const = 0; -}; +#ifdef LL_WINDOWS +#ifndef NOMINMAX +#define NOMINMAX +#endif +#undef WIN32_LEAN_AND_MEAN +#include <winsock2.h> +#include <windows.h> +// reset to default, which is lean +#define WIN32_LEAN_AND_MEAN +#undef NOMINMAX +#endif -#endif // LL_REFLECTIVE_H +#endif diff --git a/indra/llcommon/lldarrayptr.h b/indra/llcommon/llwin32headerslean.h index c9a0b204d1..f7e71301a8 100755..100644 --- a/indra/llcommon/lldarrayptr.h +++ b/indra/llcommon/llwin32headerslean.h @@ -1,6 +1,6 @@  /**  - * @file lldarrayptr.h - * @brief Wrapped std::vector for backward compatibility. + * @file llwindows.h + * @brief sanitized include of windows header files   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code @@ -23,14 +23,18 @@   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -#ifndef LL_LLDARRAYPTR_H -#define LL_LLDARRAYPTR_H -#include "lldarray.h" +#ifndef LL_LLWINDOWS_H +#define LL_LLWINDOWS_H -template <class Type, int BlockSize = 32>  -class LLDynamicArrayPtr : public LLDynamicArray<Type, BlockSize> -{ -}; +#ifdef LL_WINDOWS +#ifndef NOMINMAX +#define NOMINMAX +#endif +#define WIN32_LEAN_AND_MEAN +#include <winsock2.h> +#include <windows.h> +#undef NOMINMAX +#endif -#endif // LL_LLDARRAYPTR_H +#endif diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index be46394d6e..09776816a8 100755 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -26,10 +26,11 @@  #ifndef LL_LLWORKERTHREAD_H  #define LL_LLWORKERTHREAD_H -#include <queue> -#include <string> +#include <list>  #include <map> +#include <queue>  #include <set> +#include <string>  #include "llqueuedthread.h"  #include "llapr.h" diff --git a/indra/llcommon/metaclass.cpp b/indra/llcommon/metaclass.cpp deleted file mode 100755 index 5e403511cf..0000000000 --- a/indra/llcommon/metaclass.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/**  - * @file metaclass.cpp - * @author Babbage - * @date 2006-05-15 - * @brief Implementation of LLMetaClass - * - * $LicenseInfo:firstyear=2006&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 "linden_common.h"  - -#include "metaclass.h" - -#include "metaproperty.h" -#include "reflective.h" - -LLMetaClass::LLMetaClass() -{ -} - -//virtual  -LLMetaClass::~LLMetaClass() -{ -} - -const LLMetaProperty* LLMetaClass::findProperty(const std::string& name) const -{ -	PropertyIterator iter = mProperties.find(name); -	if(iter == mProperties.end()) -	{ -		return NULL; -	} -	return (*iter).second; -} - -void LLMetaClass::addProperty(const LLMetaProperty* property) -{ -	mProperties.insert(std::make_pair(property->getName(), property)); -} - -U32 LLMetaClass::getPropertyCount() const -{ -	return mProperties.size(); -} - -LLMetaClass::PropertyIterator LLMetaClass::beginProperties() const -{ -	return mProperties.begin(); -} - -LLMetaClass::PropertyIterator LLMetaClass::endProperties() const -{ -	return mProperties.end(); -} - -bool LLMetaClass::isInstance(const LLReflective* object) const -{ -	// TODO: Babbage: Search through super classes of objects MetaClass. -	const LLMetaClass* object_meta_class = &(object->getMetaClass()); -	return (object_meta_class == this); -} - diff --git a/indra/llcommon/metaclass.h b/indra/llcommon/metaclass.h deleted file mode 100755 index 626757d58d..0000000000 --- a/indra/llcommon/metaclass.h +++ /dev/null @@ -1,82 +0,0 @@ -/**  - * @file metaclass.h - * @author Babbage - * @date 2006-05-15 - * @brief Reflective meta information describing a class. - * - * $LicenseInfo:firstyear=2006&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_METACLASS_H -#define LL_METACLASS_H - -#include <string> -#include <map> - -#include "stdtypes.h" - -class LLReflective; -class LLMetaProperty; -class LLMetaMethod; -class LL_COMMON_API LLMetaClass -{ -public: - -	LLMetaClass(); -	virtual ~LLMetaClass(); -   -	// Create instance of this MetaClass. NULL if class is abstract.  -	// Gives ownership of returned object. -	// virtual LLReflective* create() const = 0; -   -	// Returns named property or NULL. -	const LLMetaProperty* findProperty(const std::string& name) const; -   -	// Add property to metaclass. Takes ownership of given property. -	void addProperty(const LLMetaProperty* property); -	 -	typedef std::map<std::string, const LLMetaProperty*>::const_iterator PropertyIterator; -	 -	U32 getPropertyCount() const; -	 -	PropertyIterator beginProperties() const; -	PropertyIterator endProperties() const; -   -	// Returns named property or NULL. -	// const LLMetaMethod* findMethod(const std::string& name) const; -   -	// Add method to metaclass. Takes ownership of given method. -	// void addMethod(const LLMetaMethod* method); -   -	// Find MetaClass by name. NULL if name is unknown. -	// static LLMetaClass* findClass(const std::string& name); -	 -	// True if object is instance of this meta class. -	bool isInstance(const LLReflective* object) const; -   -private: - -	typedef std::map<std::string, const LLMetaProperty*> PropertyMap; -	PropertyMap mProperties; -}; - -#endif // LL_METACLASS_H diff --git a/indra/llcommon/metaclasst.h b/indra/llcommon/metaclasst.h deleted file mode 100755 index b9a7ae219d..0000000000 --- a/indra/llcommon/metaclasst.h +++ /dev/null @@ -1,60 +0,0 @@ -/**  - * @file metaclasst.h - * - * $LicenseInfo:firstyear=2006&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_METACLASST_H -#define LL_METACLASST_H - -#include "metaclass.h" - -template<class TObject> -class LLMetaClassT : public LLMetaClass -{ -	public: -		 -		virtual ~LLMetaClassT() {;} -		 -		static const LLMetaClassT& instance() -		{ -			static const LLMetaClassT& instance = buildMetaClass(); -			return instance; -		} -	 -	private: -	 -		static const LLMetaClassT& buildMetaClass() -		{ -			LLMetaClassT& meta_class = *(new LLMetaClassT()); -			reflectProperties(meta_class); -			return meta_class; -		} -	 -		LLMetaClassT() {;} -	 -		static void reflectProperties(LLMetaClass&) -		{ -		} -}; - -#endif // LL_METACLASST_H diff --git a/indra/llcommon/metaproperty.h b/indra/llcommon/metaproperty.h deleted file mode 100755 index bd5bb1a30f..0000000000 --- a/indra/llcommon/metaproperty.h +++ /dev/null @@ -1,73 +0,0 @@ -/**  - * @file metaproperty.h - * @author Babbage - * @date 2006-05-15 - * @brief Reflective meta information describing a property of a class. - * - * $LicenseInfo:firstyear=2006&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_METAPROPERTY_H -#define LL_METAPROPERTY_H - -#include "stdtypes.h" -#include "llsd.h" -#include "reflective.h" - -class LLMetaClass; -class LLReflective; -class LL_COMMON_API LLMetaProperty -{ -public: -	LLMetaProperty(const std::string& name, const LLMetaClass& object_class); -  virtual ~LLMetaProperty(); -   -  // Get property name. -  const std::string& getName() const {return mName;} - -  // Get value of this property. -  virtual const LLReflective* get(const LLReflective* object) const = 0; -   -  // Set value of this property. -  // virtual void set(LLReflective* object, const LLReflective* value) = 0; -   -  // Get value of this property as LLSD. Default returns undefined LLSD. -  virtual LLSD getLLSD(const LLReflective* object) const = 0; -   -  // Get the MetaClass of legal values of this property. -  // const LLMetaClass& getValueMetaClass(); -   -  // Get the meta class that this property is a member of. -  const LLMetaClass& getObjectMetaClass() const; - -protected: - -  // Check object is instance of object class, throw exception if not. -  void checkObjectClass(const LLReflective* object) const; - -private: - -	std::string mName; -	const LLMetaClass& mObjectClass; -}; - -#endif // LL_METAPROPERTY_H diff --git a/indra/llcommon/metapropertyt.h b/indra/llcommon/metapropertyt.h deleted file mode 100755 index 7a36c161da..0000000000 --- a/indra/llcommon/metapropertyt.h +++ /dev/null @@ -1,183 +0,0 @@ -/**  - * @file metapropertyt.h - * - * $LicenseInfo:firstyear=2006&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_METAPROPERTYT_H -#define LL_METAPROPERTYT_H - -#include "llsd.h" -#include "llstring.h" -#include "metaclasst.h" -#include "metaproperty.h" -#include "reflectivet.h" - -template<class TProperty> -class LLMetaPropertyT : public LLMetaProperty -{ -public: -	 -	virtual ~LLMetaPropertyT() {;} -	 -	// Get value of this property. Gives ownership of returned value. -	virtual const LLReflective* get(const LLReflective* object) const -	{ -		checkObjectClass(object); -		return getProperty(object); -	} -   -	// Set value of this property. -	/*virtual void set(LLReflective* object, const LLReflective* value) -	{ -		// TODO: Babbage: Check types. -		ref(object) = static_cast<const LLReflectiveT<TProperty>* >(value)->getValue(); -	}*/ -	 -	// Get value of this property as LLSD. -	virtual LLSD getLLSD(const LLReflective* object) const -	{ -		return LLSD(); -	} - -protected: - -	LLMetaPropertyT(const std::string& name, const LLMetaClass& object_class) : LLMetaProperty(name, object_class) {;} - -	virtual const TProperty* getProperty(const LLReflective* object) const = 0; -}; - -template <> -inline const LLReflective* LLMetaPropertyT<S32>::get(const LLReflective* object) const -{ -	checkObjectClass(object); -	return NULL; -} - -template <> -inline const LLReflective* LLMetaPropertyT<std::string>::get(const LLReflective* object) const -{ -	checkObjectClass(object); -	return NULL; -} - -template <> -inline const LLReflective* LLMetaPropertyT<LLUUID>::get(const LLReflective* object) const -{ -	checkObjectClass(object); -	return NULL; -} - -template <> -inline const LLReflective* LLMetaPropertyT<bool>::get(const LLReflective* object) const -{ -	checkObjectClass(object); -	return NULL; -} - -template <> -inline LLSD LLMetaPropertyT<S32>::getLLSD(const LLReflective* object) const -{ -	return *(getProperty(object)); -} - -template <> -inline LLSD LLMetaPropertyT<std::string>::getLLSD(const LLReflective* object) const -{ -	return *(getProperty(object)); -} - -template <> -inline LLSD LLMetaPropertyT<LLUUID>::getLLSD(const LLReflective* object) const -{ -	return *(getProperty(object)); -} - -template <> -inline LLSD LLMetaPropertyT<bool>::getLLSD(const LLReflective* object) const -{ -	return *(getProperty(object)); -} - -template<class TObject, class TProperty> -class LLMetaPropertyTT : public LLMetaPropertyT<TProperty> -{ -public: - -	LLMetaPropertyTT(const std::string& name, const LLMetaClass& object_class, TProperty (TObject::*property)) :  -	  LLMetaPropertyT<TProperty>(name, object_class), mProperty(property) {;} - -protected: - -	// Get void* to property. -	virtual const TProperty* getProperty(const LLReflective* object) const -	{ -		const TObject* typed_object = static_cast<const TObject*>(object); -		return &(typed_object->*mProperty); -	}; - -private: - -	TProperty (TObject::*mProperty); -}; - -template<class TObject, class TProperty> -class LLMetaPropertyPtrTT : public LLMetaPropertyT<TProperty> -{ -public: - -	LLMetaPropertyPtrTT(const std::string& name, const LLMetaClass& object_class, TProperty* (TObject::*property)) :  -	  LLMetaPropertyT<TProperty>(name, object_class), mProperty(property) {;} - -protected: - -	// Get void* to property. -	virtual const TProperty* getProperty(const LLReflective* object) const -	{ -		const TObject* typed_object = static_cast<const TObject*>(object); -		return typed_object->*mProperty; -	}; - -private: - -	TProperty* (TObject::*mProperty); -}; - -// Utility function to simplify the registration of members. -template<class TObject, class TProperty> -void reflectProperty(LLMetaClass& meta_class, const std::string& name, TProperty (TObject::*property)) -{ -	typedef LLMetaPropertyTT<TObject, TProperty> PropertyType; -	const LLMetaProperty* meta_property = new PropertyType(name, meta_class, property); -	meta_class.addProperty(meta_property); -} - -// Utility function to simplify the registration of ptr properties. -template<class TObject, class TProperty> -void reflectPtrProperty(LLMetaClass& meta_class, const std::string& name, TProperty* (TObject::*property)) -{ -	typedef LLMetaPropertyPtrTT<TObject, TProperty> PropertyType; -	const LLMetaProperty* meta_property = new PropertyType(name, meta_class, property); -	meta_class.addProperty(meta_property); -} - -#endif // LL_METAPROPERTYT_H diff --git a/indra/llcommon/reflectivet.h b/indra/llcommon/reflectivet.h deleted file mode 100755 index 958921f23e..0000000000 --- a/indra/llcommon/reflectivet.h +++ /dev/null @@ -1,48 +0,0 @@ -/**  - * @file reflectivet.h - * - * $LicenseInfo:firstyear=2006&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_REFLECTIVET_H -#define LL_REFLECTIVET_H - -#include "reflective.h" - -template <class T> -class LLReflectiveT : public LLReflective -{ -public: - -	LLReflectiveT(const T& value) : mValue(value) {;} -	virtual ~LLReflectiveT() {;} -	 -	virtual const LLMetaClass& getMetaClass() const {return LLMetaClassT<LLReflectiveT<T> >::instance();} -	 -	const T& getValue() const {return mValue;} -	 -private: - -	T mValue; -}; - -#endif diff --git a/indra/llcommon/tests/llunits_test.cpp b/indra/llcommon/tests/llunits_test.cpp new file mode 100644 index 0000000000..2a941e8229 --- /dev/null +++ b/indra/llcommon/tests/llunits_test.cpp @@ -0,0 +1,208 @@ +/**  + * @file llsingleton_test.cpp + * @date 2011-08-11 + * @brief Unit test for the LLSingleton class + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, 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 "linden_common.h" + +#include "llunit.h" +#include "../test/lltut.h" + +namespace LLUnits +{ +	// using powers of 2 to allow strict floating point equality +	struct Quatloos { typedef Quatloos base_unit_t; }; +	LL_DECLARE_DERIVED_UNIT(4, Quatloos, Latinum); +	LL_DECLARE_DERIVED_UNIT((1.0 / 4.0), Quatloos, Solari); +} + +namespace tut +{ +	using namespace LLUnits; +	struct units +	{ +	}; + +	typedef test_group<units> units_t; +	typedef units_t::object units_object_t; +	tut::units_t tut_singleton("LLUnit"); + +	// storage type conversions +	template<> template<> +	void units_object_t::test<1>() +	{ +		LLUnit<Quatloos, F32> float_quatloos; +		ensure(float_quatloos.value() == 0.f); + +		LLUnit<Quatloos, S32> int_quatloos; +		ensure(int_quatloos.value() == 0); + +		int_quatloos = 42; +		ensure(int_quatloos.value() == 42); +		float_quatloos = int_quatloos; +		ensure(float_quatloos.value() == 42.f); + +		int_quatloos = float_quatloos; +		ensure(int_quatloos.value() == 42); + +		float_quatloos = 42.1f; +		ensure(float_quatloos.value() == 42.1f); +		int_quatloos = float_quatloos; +		ensure(int_quatloos.value() == 42); +		LLUnit<Quatloos, U32> unsigned_int_quatloos(float_quatloos); +		ensure(unsigned_int_quatloos.value() == 42); +	} + +	// conversions to/from base unit +	template<> template<> +	void units_object_t::test<2>() +	{ +		LLUnit<Quatloos, F32> quatloos(1.f); +		ensure(quatloos.value() == 1.f); +		LLUnit<Latinum, F32> latinum_bars(quatloos); +		ensure(latinum_bars.value() == 1.f / 4.f); + +		latinum_bars = 256; +		quatloos = latinum_bars; +		ensure(quatloos.value() == 1024); + +		LLUnit<Solari, F32> solari(quatloos); +		ensure(solari.value() == 4096); +	} + +	// conversions across non-base units +	template<> template<> +	void units_object_t::test<3>() +	{ +		LLUnit<Solari, F32> solari = 4.f; +		LLUnit<Latinum, F32> latinum_bars = solari; +		ensure(latinum_bars.value() == 0.25f); +	} + +	// math operations +	template<> template<> +	void units_object_t::test<4>() +	{ +		LLUnit<Quatloos, F32> quatloos = 1.f; +		quatloos *= 4.f; +		ensure(quatloos.value() == 4); +		quatloos = quatloos * 2; +		ensure(quatloos.value() == 8); +		quatloos = 2.f * quatloos; +		ensure(quatloos.value() == 16); + +		quatloos += 4.f; +		ensure(quatloos.value() == 20); +		quatloos += 4; +		ensure(quatloos.value() == 24); +		quatloos = quatloos + 4; +		ensure(quatloos.value() == 28); +		quatloos = 4 + quatloos; +		ensure(quatloos.value() == 32); +		quatloos += quatloos * 3; +		ensure(quatloos.value() == 128); + +		quatloos -= quatloos / 4 * 3; +		ensure(quatloos.value() == 32); +		quatloos = quatloos - 8; +		ensure(quatloos.value() == 24); +		quatloos -= 4; +		ensure(quatloos.value() == 20); +		quatloos -= 4.f; +		ensure(quatloos.value() == 16); + +		quatloos *= 2.f; +		ensure(quatloos.value() == 32); +		quatloos = quatloos * 2.f; +		ensure(quatloos.value() == 64); +		quatloos = 0.5f * quatloos; +		ensure(quatloos.value() == 32); + +		quatloos /= 2.f; +		ensure(quatloos.value() == 16); +		quatloos = quatloos / 4; +		ensure(quatloos.value() == 4); + +		F32 ratio = quatloos / LLUnit<Quatloos, F32>(4.f); +		ensure(ratio == 1); + +		quatloos += LLUnit<Solari, F32>(4.f); +		ensure(quatloos.value() == 5); +		quatloos -= LLUnit<Latinum, F32>(1.f); +		ensure(quatloos.value() == 1); +	} + +	// implicit units +	template<> template<> +	void units_object_t::test<5>() +	{ +		// 0-initialized +		LLUnit<Quatloos, F32> quatloos(0); +		// initialize implicit unit from explicit +		LLUnitImplicit<Quatloos, F32> quatloos_implicit = quatloos + 1; +		ensure(quatloos_implicit.value() == 1); + +		// assign implicit to explicit, or perform math operations +		quatloos = quatloos_implicit; +		ensure(quatloos.value() == 1); +		quatloos += quatloos_implicit; +		ensure(quatloos.value() == 2); + +		// math operations on implicits +		quatloos_implicit = 1; +		ensure(quatloos_implicit == 1); + +		quatloos_implicit += 2; +		ensure(quatloos_implicit == 3); + +		quatloos_implicit *= 2; +		ensure(quatloos_implicit == 6); + +		quatloos_implicit -= 1; +		ensure(quatloos_implicit == 5); + +		quatloos_implicit /= 5; +		ensure(quatloos_implicit == 1); + +		quatloos_implicit = quatloos_implicit + 3 + quatloos_implicit; +		ensure(quatloos_implicit == 5); + +		quatloos_implicit = 10 - quatloos_implicit - 1; +		ensure(quatloos_implicit == 4); + +		quatloos_implicit = 2 * quatloos_implicit * 2; +		ensure(quatloos_implicit == 16); + +		F32 one_half = quatloos_implicit / (quatloos_implicit * 2); +		ensure(one_half == 0.5f); + +		// implicit conversion to POD +		F32 float_val = quatloos_implicit; +		ensure(float_val == 16); + +		S32 int_val = quatloos_implicit; +		ensure(int_val == 16); +	} +} diff --git a/indra/llcommon/tests/reflection_test.cpp b/indra/llcommon/tests/reflection_test.cpp deleted file mode 100755 index 8980ebb1f1..0000000000 --- a/indra/llcommon/tests/reflection_test.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/**  - * @file reflection_test.cpp - * @date   May 2006 - * @brief Reflection unit tests. - * - * $LicenseInfo:firstyear=2006&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 "../linden_common.h" -#include "../reflective.h" -#include "../metaclasst.h" -#include "../metapropertyt.h" -#include "../stdtypes.h" - -#include "../test/lltut.h" - -namespace tut -{ -  class TestAggregatedData : public LLReflective -  { -  public: -	TestAggregatedData() {;} -	virtual const LLMetaClass& getMetaClass() const; -   -  private: -  }; -   -  class TestReflectionData : public LLReflective -  { -  public: -	TestReflectionData() : mInt(42), mString("foo"), mNullPtr(NULL), mPtr(new TestAggregatedData()), mRef(*(new TestAggregatedData)) {;} -	virtual ~TestReflectionData() {delete mPtr;} -	virtual const LLMetaClass& getMetaClass() const; -	 -	static U32 getPropertyCount() {return 5;} -	 -  private: -   -	friend class LLMetaClassT<TestReflectionData>; -    S32 mInt; -	std::string mString; -	TestAggregatedData* mNullPtr; -	TestAggregatedData* mPtr; -	TestAggregatedData mObj; -	TestAggregatedData& mRef; -  }; -} - -template <> -void LLMetaClassT<tut::TestReflectionData>::reflectProperties(LLMetaClass& meta_class) -{ -	reflectProperty(meta_class, "mInt", &tut::TestReflectionData::mInt); -	reflectProperty(meta_class, "mString", &tut::TestReflectionData::mString); -	reflectPtrProperty(meta_class, "mNullPtr", &tut::TestReflectionData::mNullPtr); -	reflectPtrProperty(meta_class, "mPtr", &tut::TestReflectionData::mPtr); -	reflectProperty(meta_class, "mObj", &tut::TestReflectionData::mObj); -	//reflectProperty(meta_class, "mRef", &tut::TestReflectionData::mRef); // AARGH! -} - -namespace tut -{ -	// virtual -	const LLMetaClass& TestReflectionData::getMetaClass() const -	{ -	   return LLMetaClassT<TestReflectionData>::instance(); -    } -	 -	const LLMetaClass& TestAggregatedData::getMetaClass() const -	{ -	   return LLMetaClassT<TestAggregatedData>::instance(); -    } -} - -namespace tut -{ -  typedef tut::test_group<TestReflectionData> TestReflectionGroup; -  typedef TestReflectionGroup::object TestReflectionObject; -  TestReflectionGroup gTestReflectionGroup("reflection"); - -  template<> template<> -  void TestReflectionObject::test<1>() -  { -	// Check properties can be found. -    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	const LLMetaProperty* null = NULL; -	ensure_not_equals(meta_class.findProperty("mInt"), null); -	ensure_not_equals(meta_class.findProperty("mString"), null); -  } -   -  template<> template<> -  void TestReflectionObject::test<2>() -  { -	// Check non-existent property cannot be found. -    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	const LLMetaProperty* null = NULL; -	ensure_equals(meta_class.findProperty("foo"), null); -  } -   -  template<> template<> -  void TestReflectionObject::test<3>() -  { -	// Check integer property has correct value.	 -    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	ensure_equals(meta_class.findProperty("mInt")->getLLSD(this).asInteger(), 42); -  } -   -  template<> template<> -  void TestReflectionObject::test<4>() -  { -	// Check string property has correct value.	 -    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	ensure_equals(meta_class.findProperty("mString")->getLLSD(this).asString(), std::string("foo")); -  } -   -  template<> template<> -  void TestReflectionObject::test<5>() -  { -	// Check NULL reference property has correct value. -	const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	const LLReflective* null = NULL; -	ensure_equals(meta_class.findProperty("mNullPtr")->get(this), null); -  } -   -  template<> template<> -  void TestReflectionObject::test<6>() -  { -	// Check reference property has correct value. -	const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	const LLReflective* null = NULL; -	const LLReflective* ref = meta_class.findProperty("mPtr")->get(this); -	ensure_not_equals(ref, null); -  } -   -  template<> template<> -  void TestReflectionObject::test<7>() -  { -	// Check reflective property has correct value. -	const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	const LLReflective* null = NULL; -	const LLReflective* ref = meta_class.findProperty("mObj")->get(this); -	ensure_not_equals(ref, null); -  } - -  template<> template<> -  void TestReflectionObject::test<8>() -  { -	// Check property count. -    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	ensure_equals(meta_class.getPropertyCount(), TestReflectionData::getPropertyCount()); -  } -   -  template<> template<> -  void TestReflectionObject::test<9>() -  { -	// Check property iteration. -    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	U32 count = 0; -	LLMetaClass::PropertyIterator iter; -	for(iter = meta_class.beginProperties(); iter != meta_class.endProperties(); ++iter) -	{ -		++count; -	} -	ensure_equals(count, TestReflectionData::getPropertyCount()); -  } -   -  template<> template<> -  void TestReflectionObject::test<10>() -  { -	// Check meta classes of different types do not compare equal. -	const LLMetaClass* reflection_data_meta_class = &(LLMetaClassT<TestReflectionData>::instance()); -	const LLMetaClass* aggregated_data_meta_class = &(LLMetaClassT<TestAggregatedData>::instance()); -	ensure_not_equals(reflection_data_meta_class, aggregated_data_meta_class); -  } -   -  template<> template<> -  void TestReflectionObject::test<11>() -  { -	// Check class cast checks. -	const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); -	TestAggregatedData* aggregated_data = new TestAggregatedData(); -	LLMetaClass::PropertyIterator iter; -	U32 exception_count = 0; -	for(iter = meta_class.beginProperties(); iter != meta_class.endProperties(); ++iter) -	{ -		try -		{ -			const LLMetaProperty* property = (*iter).second; -			const LLReflective* reflective = property->get(aggregated_data); // Wrong reflective type, should throw exception. - -			// useless op to get rid of compiler warning. -			reflective = reflective; -		} -		catch(...) -		{ -			++exception_count; -		} -	} -	ensure_equals(exception_count, getPropertyCount()); -	 -  } -} diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h index 21a916b13b..402e725152 100755 --- a/indra/llcorehttp/_refcounted.h +++ b/indra/llcorehttp/_refcounted.h @@ -72,7 +72,7 @@ private:  inline void RefCounted::addRef() const  { -	S32 count(mRefCount++); +	S32 count(++mRefCount);  	llassert_always(count >= 0);  } @@ -82,7 +82,7 @@ inline void RefCounted::release() const  	S32 count(mRefCount);  	llassert_always(count != NOT_REF_COUNTED);  	llassert_always(count > 0); -	count = mRefCount--; +	count = --mRefCount;  	// clean ourselves up if that was the last reference  	if (0 == count) diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 1c25256e95..50df2ebe55 100755 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -50,6 +50,7 @@ LLMutex* LLImage::sMutex = NULL;  bool LLImage::sUseNewByteRange = false;  S32  LLImage::sMinimalReverseByteRangePercent = 75;  LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ; +LLTrace::MemStatHandle	LLImageBase::sMemStat("LLImage");  //static  void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent) @@ -158,6 +159,7 @@ void LLImageBase::sanityCheck()  void LLImageBase::deleteData()  {  	FREE_MEM(sPrivatePoolp, mData) ; +	memDisclaimAmount(mDataSize);  	mData = NULL;  	mDataSize = 0;  } @@ -201,6 +203,7 @@ U8* LLImageBase::allocateData(S32 size)  			mBadBufferAllocation = true ;  		}  		mDataSize = size; +		memClaimAmount(mDataSize);  	}  	return mData; @@ -222,7 +225,9 @@ U8* LLImageBase::reallocateData(S32 size)  		FREE_MEM(sPrivatePoolp, mData) ;  	}  	mData = new_datap; +	memDisclaimAmount(mDataSize);  	mDataSize = size; +	memClaimAmount(mDataSize);  	return mData;  } @@ -288,7 +293,6 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)  LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)  	: LLImageBase()  { -  	if(no_copy)  	{  		setDataAndSize(data, width, height, components); @@ -1608,7 +1612,9 @@ static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8*  void LLImageBase::setDataAndSize(U8 *data, S32 size)  {   	ll_assert_aligned(data, 16); +	memDisclaimAmount(mDataSize);  	mData = data; mDataSize = size;  +	memClaimAmount(mDataSize);  }	  //static diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 4fc40ecff7..504b7e4795 100755 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -30,6 +30,7 @@  #include "lluuid.h"  #include "llstring.h"  #include "llthread.h" +#include "lltrace.h"  const S32 MIN_IMAGE_MIP =  2; // 4x4, only used for expand/contract power of 2  const S32 MAX_IMAGE_MIP = 11; // 2048x2048 @@ -110,7 +111,9 @@ protected:  //============================================================================  // Image base class -class LLImageBase : public LLThreadSafeRefCount +class LLImageBase  +:	public LLThreadSafeRefCount, +	public LLTrace::MemTrackable<LLImageBase>  {  protected:  	virtual ~LLImageBase(); @@ -162,6 +165,8 @@ public:  	static void destroyPrivatePool() ;  	static LLPrivateMemoryPool* getPrivatePool() {return sPrivatePoolp;} +	static LLTrace::MemStatHandle sMemStat; +  private:  	U8 *mData;  	S32 mDataSize; diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index e255d65b43..b6f2694742 100755 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -31,6 +31,8 @@  #include "../llimageworker.h"  // For timer class  #include "../llcommon/lltimer.h" +// for lltrace class +#include "../llcommon/lltrace.h"  // Tut header  #include "../test/lltut.h" @@ -42,6 +44,9 @@  // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)  // * A simulator for a class can be implemented here. Please comment and document thoroughly. +LLTrace::MemStatHandle	LLImageBase::sMemStat("LLImage"); + +  LLImageBase::LLImageBase()   : mData(NULL),  mDataSize(0), @@ -114,11 +119,13 @@ namespace tut  		// Constructor and destructor of the test wrapper  		imagedecodethread_test()  		{ +			LLTrace::init();  			mThread = NULL;  		}  		~imagedecodethread_test()  		{  			delete mThread; +			LLTrace::cleanup();  		}  	}; @@ -136,6 +143,8 @@ namespace tut  		imagerequest_test()  		{  			done = false; +			LLTrace::init(); +  			mRequest = new LLImageDecodeThread::ImageRequest(0, 0,  											 LLQueuedThread::PRIORITY_NORMAL, 0, FALSE,  											 new responder_test(&done)); @@ -145,6 +154,7 @@ namespace tut  			// We should delete the object *but*, because its destructor is protected, that cannot be  			// done from outside an LLImageDecodeThread instance... So we leak memory here... It's fine...  			//delete mRequest; +			LLTrace::cleanup();  		}  	}; diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h index eb2ecf71ba..47fcf688a2 100755 --- a/indra/llinventory/lleconomy.h +++ b/indra/llinventory/lleconomy.h @@ -27,6 +27,7 @@  #define LL_LLECONOMY_H  #include "llsingleton.h" +#include <list>  class LLMessageSystem;  class LLVector3; diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 41d58c6deb..2a319c635f 100755 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -28,6 +28,7 @@  #include "llinventory.h"  #include "lldbstrings.h" +#include "llfasttimer.h"  #include "llinventorydefines.h"  #include "llxorcipher.h"  #include "llsd.h" diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index 7e013de11a..55067cde73 100755 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -31,7 +31,6 @@  // library includes  #include "message.h" -#include "metapropertyt.h"  #include "llsd.h"  ///---------------------------------------------------------------------------- @@ -895,21 +894,6 @@ std::ostream& operator<<(std::ostream &s, const LLPermissions &perm)  	return s;  } -template <> -void LLMetaClassT<LLPermissions>::reflectProperties(LLMetaClass& meta_class) -{ -	reflectProperty(meta_class, "mCreator", &LLPermissions::mCreator); -	reflectProperty(meta_class, "mOwner", &LLPermissions::mOwner); -	reflectProperty(meta_class, "mGroup", &LLPermissions::mGroup); -	reflectProperty(meta_class, "mIsGroupOwned", &LLPermissions::mIsGroupOwned); -} - -// virtual -const LLMetaClass& LLPermissions::getMetaClass() const -{ -	return LLMetaClassT<LLPermissions>::instance(); -} -  ///----------------------------------------------------------------------------  /// Class LLAggregatePermissions  ///---------------------------------------------------------------------------- diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index 3ecc922370..89c66f6ebd 100755 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -31,7 +31,6 @@  #include "llsd.h"  #include "lluuid.h"  #include "llxmlnode.h" -#include "reflective.h"  #include "llinventorytype.h"  // prototypes @@ -83,7 +82,7 @@ template<class T> class LLMetaClassT;  // logical consistency.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLPermissions : public LLReflective +class LLPermissions  {  private:  	LLUUID			mCreator;				// null if object created by system @@ -324,9 +323,6 @@ public:  	friend std::ostream& operator<<(std::ostream &s, const LLPermissions &perm); -	// Reflection. -	friend class LLMetaClassT<LLPermissions>; -	virtual const LLMetaClass& getMetaClass() const;  };  // Inlines diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index 62c245f125..14fbf344ab 100755 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -43,7 +43,9 @@  // End Stubbing  // ------------------------------------------------------------------------------------------- -// Stubb the LL Image Classes +// Stub the LL Image Classes +LLTrace::MemStatHandle	LLImageBase::sMemStat("LLImage"); +  LLImageRaw::LLImageRaw() { }  LLImageRaw::~LLImageRaw() { }  U8* LLImageRaw::allocateData(S32 ) { return NULL; } diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index 22ba26f99b..6551b52462 100755 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -161,7 +161,7 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer)  // ---------------- test methods  ----------------  -S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius)  +S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius, const LLPlane* planes)   {  	static const LLVector4a scaler[] = {  		LLVector4a(-1,-1,-1), @@ -174,6 +174,12 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius)  		LLVector4a( 1, 1, 1)  	}; +	if(!planes) +	{ +		//use agent space +		planes = mAgentPlanes; +	} +  	U8 mask = 0;  	bool result = false;  	LLVector4a rscale, maxp, minp; @@ -183,7 +189,7 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius)  		mask = mPlaneMask[i];  		if (mask != 0xff)  		{ -			const LLPlane& p(mAgentPlanes[i]); +			const LLPlane& p(planes[i]);  			p.getAt<3>(d);  			rscale.setMul(radius, scaler[mask]);  			minp.setSub(center, rscale); @@ -204,8 +210,14 @@ S32 LLCamera::AABBInFrustum(const LLVector4a ¢er, const LLVector4a& radius)  	return result?1:2;  } +//exactly same as the function AABBInFrustum(...) +//except uses mRegionPlanes instead of mAgentPlanes. +S32 LLCamera::AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius)  +{ +	return AABBInFrustum(center, radius, mRegionPlanes); +} -S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)  +S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes)   {  	static const LLVector4a scaler[] = {  		LLVector4a(-1,-1,-1), @@ -218,6 +230,12 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&  		LLVector4a( 1, 1, 1)  	}; +	if(!planes) +	{ +		//use agent space +		planes = mAgentPlanes; +	} +  	U8 mask = 0;  	bool result = false;  	LLVector4a rscale, maxp, minp; @@ -227,7 +245,7 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&  		mask = mPlaneMask[i];  		if ((i != 5) && (mask != 0xff))  		{ -			const LLPlane& p(mAgentPlanes[i]); +			const LLPlane& p(planes[i]);  			p.getAt<3>(d);  			rscale.setMul(radius, scaler[mask]);  			minp.setSub(center, rscale); @@ -248,6 +266,13 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&  	return result?1:2;  } +//exactly same as the function AABBInFrustumNoFarClip(...) +//except uses mRegionPlanes instead of mAgentPlanes. +S32 LLCamera::AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)  +{ +	return AABBInFrustumNoFarClip(center, radius, mRegionPlanes); +} +  int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)   {  	LLVector3 dist = sphere_center-mFrustCenter; @@ -584,6 +609,23 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)  	}  } +//calculate regional planes from mAgentPlanes. +//vector "shift" is the vector of the region origin in the agent space. +void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift)  +{ +	F32 d; +	LLVector3 n; +	for(S32 i = 0 ; i < 7; i++) +	{ +		if (mPlaneMask[i] != 0xff) +		{ +			n.setVec(mAgentPlanes[i][0], mAgentPlanes[i][1], mAgentPlanes[i][2]); +			d = mAgentPlanes[i][3] - n * shift; +			mRegionPlanes[i].setVec(n, d); +		} +	} +} +  void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom)  {  	LLVector3 a, b, c; diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 0b591be622..898d73ed7e 100755 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -109,6 +109,7 @@ public:  private:  	LL_ALIGN_16(LLPlane mAgentPlanes[7]);  //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP +	LL_ALIGN_16(LLPlane mRegionPlanes[7]);  //frustum planes in a local region space, derived from mAgentPlanes  	U8 mPlaneMask[8];         // 8 for alignment	  	F32 mView;					// angle between top and bottom frustum planes in radians. @@ -178,6 +179,7 @@ public:  	// Return number of bytes copied.  	size_t readFrustumFromBuffer(const char *buffer);  	void calcAgentFrustumPlanes(LLVector3* frust); +	void calcRegionFrustumPlanes(const LLVector3& shift); //calculate regional planes from mAgentPlanes.  	void ignoreAgentFrustumPlane(S32 idx);  	// Returns 1 if partly in, 2 if fully in. @@ -186,8 +188,10 @@ public:  	S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const;  	S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }  	S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); } -	S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius); -	S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius); +	S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL); +	S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius); +	S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL); +	S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);  	//does a quick 'n dirty sphere-sphere check  	S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius);  diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index b047f86e6e..0d632f59be 100755 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -49,10 +49,10 @@ class LLColor4  		LLColor4();						// Initializes LLColor4 to (0, 0, 0, 1)  		LLColor4(F32 r, F32 g, F32 b);		// Initializes LLColor4 to (r, g, b, 1)  		LLColor4(F32 r, F32 g, F32 b, F32 a);		// Initializes LLColor4 to (r. g, b, a) -		LLColor4(U32 clr);							// Initializes LLColor4 to (r=clr>>24, etc)) -		LLColor4(const F32 *vec);			// Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)  		LLColor4(const LLColor3 &vec, F32 a = 1.f);	// Initializes LLColor4 to (vec, a)  		explicit LLColor4(const LLSD& sd); +		explicit LLColor4(const F32 *vec);			// Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1) +		explicit LLColor4(U32 clr);							// Initializes LLColor4 to (r=clr>>24, etc))  		explicit LLColor4(const LLColor4U& color4u);  // "explicit" to avoid automatic conversion  		explicit LLColor4(const LLVector4& vector4);  // "explicit" to avoid automatic conversion diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp index 9b86daebe5..430c9503ac 100755 --- a/indra/llmessage/llassetstorage.cpp +++ b/indra/llmessage/llassetstorage.cpp @@ -50,10 +50,14 @@  #include "lltransfertargetvfile.h" // For debugging  #include "llmetrics.h" +#include "lltrace.h"  LLAssetStorage *gAssetStorage = NULL;  LLMetrics *LLAssetStorage::metric_recipient = NULL; +static LLTrace::CountStatHandle<> sFailedDownloadCount("faileddownloads", "Number of times LLAssetStorage::getAssetData() has failed"); + +  const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-000000000010"));  const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000);		// microseconds @@ -450,6 +454,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL  		if (callback)  		{ +			add(sFailedDownloadCount, 1);  			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE);  		}  		return; @@ -460,6 +465,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL  		// Special case early out for NULL uuid and for shutting down  		if (callback)  		{ +			add(sFailedDownloadCount, 1);  			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);  		}  		return; @@ -572,6 +578,7 @@ void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType at  		llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;  		if (callback)  		{ +			add(sFailedDownloadCount, 1);  			callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);  		}  	} @@ -649,6 +656,10 @@ void LLAssetStorage::downloadCompleteCallback(  		LLAssetRequest* tmp = *curiter;  		if (tmp->mDownCallback)  		{ +			if (result != LL_ERR_NOERR) +			{ +				add(sFailedDownloadCount, 1); +			}  			tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status);  		}  		delete tmp; @@ -669,6 +680,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen  		// Special case early out for NULL uuid  		if (callback)  		{ +			add(sFailedDownloadCount, 1);  			callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);  		}  		return; @@ -741,6 +753,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen  			llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;  			if (callback)  			{ +				add(sFailedDownloadCount, 1);  				callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);  			}  		} @@ -783,6 +796,10 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(  		}  	} +	if (result != LL_ERR_NOERR) +	{ +		add(sFailedDownloadCount, 1); +	}  	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);  } @@ -883,6 +900,7 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age  			llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;  			if (callback)  			{ +				add(sFailedDownloadCount, 1);  				callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);  			}  		} @@ -925,6 +943,10 @@ void LLAssetStorage::downloadInvItemCompleteCallback(  		}  	} +	if (result != LL_ERR_NOERR) +	{ +		add(sFailedDownloadCount, 1); +	}  	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);  } @@ -1237,6 +1259,7 @@ bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* re  		}  		if (req->mDownCallback)  		{ +			add(sFailedDownloadCount, 1);  			req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED);  		}  		if (req->mInfoCallback) @@ -1363,6 +1386,10 @@ void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAss  		}  	} +	if (status != LL_ERR_NOERR) +	{ +		add(sFailedDownloadCount, 1); +	}  	legacy->mDownCallback(filename.c_str(), uuid, legacy->mUserData, status, ext_status);  	delete legacy;  } diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp index 01da20f060..1722b48f44 100755 --- a/indra/llmessage/llbuffer.cpp +++ b/indra/llmessage/llbuffer.cpp @@ -32,6 +32,7 @@  #include "llmath.h"  #include "llstl.h"  #include "llthread.h" +#include <iterator>  #define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED llassert(!mMutexp || mMutexp->isSelfLocked()); diff --git a/indra/llmessage/lldatapacker.h b/indra/llmessage/lldatapacker.h index b0a638c16e..226752d52e 100755 --- a/indra/llmessage/lldatapacker.h +++ b/indra/llmessage/lldatapacker.h @@ -170,6 +170,7 @@ public:  				S32			getBufferSize() const	{ return mBufferSize; }  				const U8*   getBuffer() const   { return mBufferp; }      				void		reset()				{ mCurBufferp = mBufferp; mWriteEnabled = (mCurBufferp != NULL); } +				void        shift(S32 offset)   { reset(); mCurBufferp += offset;}  				void		freeBuffer()		{ delete [] mBufferp; mBufferp = mCurBufferp = NULL; mBufferSize = 0; mWriteEnabled = FALSE; }  				void		assignBuffer(U8 *bufferp, S32 size)  				{ diff --git a/indra/llmessage/lldispatcher.cpp b/indra/llmessage/lldispatcher.cpp index b2dc414a68..7ac3651a76 100755 --- a/indra/llmessage/lldispatcher.cpp +++ b/indra/llmessage/lldispatcher.cpp @@ -29,6 +29,7 @@  #include "lldispatcher.h"  #include <algorithm> +#include <iterator>  #include "llstl.h"  #include "message.h" diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp index e0ca056a5f..dbb8c4e28d 100755 --- a/indra/llmessage/llfiltersd2xmlrpc.cpp +++ b/indra/llmessage/llfiltersd2xmlrpc.cpp @@ -80,6 +80,7 @@  #include "llbuffer.h"  #include "llbufferstream.h" +#include "llfasttimer.h"  #include "llmemorystream.h"  #include "llsd.h"  #include "llsdserialize.h" diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 1236fc8b71..f9d37b2e39 100755 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -33,6 +33,7 @@  #include "llapr.h"  #include "llbuffer.h"  #include "llbufferstream.h" +#include "llfasttimer.h"  #include "llhttpnode.h"  #include "lliopipe.h"  #include "lliosocket.h" diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h index cbd17b5a3d..9a0a427efd 100755 --- a/indra/llmessage/lliopipe.h +++ b/indra/llmessage/lliopipe.h @@ -31,6 +31,7 @@  #include <boost/intrusive_ptr.hpp>  #include <boost/shared_ptr.hpp> +#include "llwin32headerslean.h"  #include "apr_poll.h"  #include "llsd.h" diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index 2043bae5e7..27e3cc7898 100755 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -32,6 +32,7 @@  #include "llapr.h"  #include "llbuffer.h" +#include "llfasttimer.h"  #include "llhost.h"  #include "llpumpio.h" diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h index be0f7dfcc6..ec998552d0 100755 --- a/indra/llmessage/lliosocket.h +++ b/indra/llmessage/lliosocket.h @@ -38,6 +38,7 @@   */  #include "lliopipe.h" +#include "llwin32headerslean.h"  #include "apr_pools.h"  #include "apr_network_io.h"  #include "llchainio.h" diff --git a/indra/llmessage/llioutil.cpp b/indra/llmessage/llioutil.cpp index 8c50fd5069..9fd49d23d4 100755 --- a/indra/llmessage/llioutil.cpp +++ b/indra/llmessage/llioutil.cpp @@ -28,6 +28,7 @@  #include "linden_common.h"  #include "llioutil.h" +#include "llfasttimer.h"  /**   * LLIOFlush diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp index 08b31e9c7a..dc27f2ca4a 100755 --- a/indra/llmessage/llmail.cpp +++ b/indra/llmessage/llmail.cpp @@ -29,12 +29,7 @@  #include "llmail.h"  // APR on Windows needs full windows headers -#ifdef LL_WINDOWS -#	undef WIN32_LEAN_AND_MEAN -#	include <winsock2.h> -#	include <windows.h> -#endif - +#include "llwin32headers.h"  #include <string>  #include <sstream> diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index 9988fcd9c0..9b8d19cc3e 100755 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -57,13 +57,15 @@ LLProxy::LLProxy():  		mAuthMethodSelected(METHOD_NOAUTH),  		mSocksUsername(),  		mSocksPassword() -{ -} +{}  LLProxy::~LLProxy()  { -	stopSOCKSProxy(); -	disableHTTPProxy(); +	if (ll_apr_is_initialized()) +	{ +		stopSOCKSProxy(); +		disableHTTPProxy(); +	}  }  /** diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 0623e99f0a..e3f09f34ee 100755 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -34,6 +34,7 @@  #include "apr_poll.h"  #include "llapr.h" +#include "llfasttimer.h"  #include "llstl.h"  // These should not be enabled in production, but they can be diff --git a/indra/llmessage/llsdrpcclient.cpp b/indra/llmessage/llsdrpcclient.cpp index fcda0e81a3..05b27f582c 100755 --- a/indra/llmessage/llsdrpcclient.cpp +++ b/indra/llmessage/llsdrpcclient.cpp @@ -30,6 +30,7 @@  #include "llsdrpcclient.h"  #include "llbufferstream.h" +#include "llfasttimer.h"  #include "llfiltersd2xmlrpc.h"  #include "llpumpio.h"  #include "llsd.h" diff --git a/indra/llmessage/llsdrpcserver.cpp b/indra/llmessage/llsdrpcserver.cpp index f26ee52f71..2c233c1c0d 100755 --- a/indra/llmessage/llsdrpcserver.cpp +++ b/indra/llmessage/llsdrpcserver.cpp @@ -31,6 +31,7 @@  #include "llbuffer.h"  #include "llbufferstream.h" +#include "llfasttimer.h"  #include "llpumpio.h"  #include "llsdserialize.h"  #include "llstl.h" diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 627d591839..7281ac35af 100755 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -33,6 +33,7 @@  #include <openssl/x509_vfy.h>  #include <openssl/ssl.h>  #include "llcurl.h" +#include "llfasttimer.h"  #include "llioutil.h"  #include "llproxy.h"  #include "llpumpio.h" @@ -284,6 +285,8 @@ LLIOPipe::EStatus LLURLRequest::handleError(  static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST("URL Request");  static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");  static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform"); +static LLFastTimer::DeclareTimer FTM_PROCESS_URL_PUMP_RESPOND("Pump Respond"); +static LLFastTimer::DeclareTimer FTM_URL_ADJUST_TIMEOUT("Adjust Timeout");  // virtual  LLIOPipe::EStatus LLURLRequest::process_impl( @@ -303,7 +306,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  	const S32 MIN_ACCUMULATION = 100000;  	if(pump && (mDetail->mByteAccumulator > MIN_ACCUMULATION))  	{ -		static LLFastTimer::DeclareTimer FTM_URL_ADJUST_TIMEOUT("Adjust Timeout");  		LLFastTimer t(FTM_URL_ADJUST_TIMEOUT);  		 // This is a pretty sloppy calculation, but this  		 // tries to make the gross assumption that if data @@ -402,7 +404,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(  						link.mChannels = LLBufferArray::makeChannelConsumer(  							channels);  						chain.push_back(link); -						static LLFastTimer::DeclareTimer FTM_PROCESS_URL_PUMP_RESPOND("Pump Respond");  						{  							LLFastTimer t(FTM_PROCESS_URL_PUMP_RESPOND);  							pump->respond(chain, buffer, context); diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 1589ea29c1..e94e2282a0 100755 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -50,9 +50,9 @@  #include "lltimer.h"  #include "llpacketring.h"  #include "llhost.h" -#include "llhttpclient.h" +#include "llcurl.h"  #include "llhttpnode.h" -#include "llpacketack.h" +//#include "llpacketack.h"  #include "llsingleton.h"  #include "message_prehash.h"  #include "llstl.h" @@ -158,7 +158,6 @@ const F32 LL_MAX_LOST_TIMEOUT				= 5.f;				// Maximum amount of time before cons  const S32 MAX_MESSAGE_COUNT_NUM = 1024;  // Forward declarations -class LLCircuit;  class LLVector3;  class LLVector4;  class LLVector3d; @@ -214,19 +213,19 @@ class LLMessageSystem : public LLMessageSenderInterface   public:  	LLPacketRing				mPacketRing; -	LLReliablePacketParams			mReliablePacketParams; +	LLReliablePacketParams		mReliablePacketParams;  	// Set this flag to TRUE when you want *very* verbose logs. -	BOOL mVerboseLog; +	BOOL						mVerboseLog; -	F32                                     mMessageFileVersionNumber; +	F32                         mMessageFileVersionNumber;  	typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t;  	typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;  private:  	message_template_name_map_t		mMessageTemplates; -	message_template_number_map_t		mMessageNumbers; +	message_template_number_map_t	mMessageNumbers;  public:  	S32					mSystemVersionMajor; @@ -235,7 +234,7 @@ public:  	S32					mSystemVersionServer;  	U32					mVersionFlags; -	BOOL					mbProtected; +	BOOL				mbProtected;  	U32					mNumberHighFreqMessages;  	U32					mNumberMediumFreqMessages; @@ -255,11 +254,11 @@ public:  	U32					mReliablePacketsIn;	    // total reliable packets in  	U32					mReliablePacketsOut;	    // total reliable packets out -	U32                                     mDroppedPackets;            // total dropped packets in -	U32                                     mResentPackets;             // total resent packets out -	U32                                     mFailedResendPackets;       // total resend failure packets out -	U32                                     mOffCircuitPackets;         // total # of off-circuit packets rejected -	U32                                     mInvalidOnCircuitPackets;   // total # of on-circuit but invalid packets rejected +	U32                 mDroppedPackets;            // total dropped packets in +	U32                 mResentPackets;             // total resent packets out +	U32                 mFailedResendPackets;       // total resend failure packets out +	U32                 mOffCircuitPackets;         // total # of off-circuit packets rejected +	U32                 mInvalidOnCircuitPackets;   // total # of on-circuit but invalid packets rejected  	S64					mUncompressedBytesIn;	    // total uncompressed size of compressed packets in  	S64					mUncompressedBytesOut;	    // total uncompressed size of compressed packets out @@ -268,14 +267,14 @@ public:  	S64					mTotalBytesIn;		    // total size of all uncompressed packets in  	S64					mTotalBytesOut;		    // total size of all uncompressed packets out -	BOOL                                    mSendReliable;              // does the outgoing message require a pos ack? +	BOOL                mSendReliable;              // does the outgoing message require a pos ack? -	LLCircuit 	 			mCircuitInfo; +	LLCircuit 	 		mCircuitInfo;  	F64					mCircuitPrintTime;	    // used to print circuit debug info every couple minutes  	F32					mCircuitPrintFreq;	    // seconds -	std::map<U64, U32>			mIPPortToCircuitCode; -	std::map<U32, U64>			mCircuitCodeToIPPort; +	std::map<U64, U32>	mIPPortToCircuitCode; +	std::map<U32, U64>	mCircuitCodeToIPPort;  	U32					mOurCircuitCode;  	S32					mSendPacketFailureCount;  	S32					mUnackedListDepth; @@ -494,7 +493,7 @@ public:  		void (*callback)(void **,S32),   		void ** callback_data); -	LLHTTPClient::ResponderPtr createResponder(const std::string& name); +	LLCurl::ResponderPtr createResponder(const std::string& name);  	S32		sendMessage(const LLHost &host);  	S32		sendMessage(const U32 circuit);  private: diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index 85aef5da00..1c9508214c 100755 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -26,15 +26,13 @@  #include "linden_common.h" -#include "net.h" +//#include "net.h"  // system library includes  #include <stdexcept>  #if LL_WINDOWS -	#define WIN32_LEAN_AND_MEAN -	#include <winsock2.h> -	#include <windows.h> +#include "llwin32headerslean.h"  #else  	#include <sys/types.h>  	#include <sys/socket.h> diff --git a/indra/llplugin/llpluginprocesschild.h b/indra/llplugin/llpluginprocesschild.h index a9d6794e40..531422e792 100755 --- a/indra/llplugin/llpluginprocesschild.h +++ b/indra/llplugin/llpluginprocesschild.h @@ -29,6 +29,7 @@  #ifndef LL_LLPLUGINPROCESSCHILD_H  #define LL_LLPLUGINPROCESSCHILD_H +#include <queue>  #include "llpluginmessage.h"  #include "llpluginmessagepipe.h"  #include "llplugininstance.h" diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h index 990fc5cbae..24be7eb148 100755 --- a/indra/llplugin/llpluginprocessparent.h +++ b/indra/llplugin/llpluginprocessparent.h @@ -29,6 +29,8 @@  #ifndef LL_LLPLUGINPROCESSPARENT_H  #define LL_LLPLUGINPROCESSPARENT_H +#include <queue> +  #include "llapr.h"  #include "llprocess.h"  #include "llpluginmessage.h" diff --git a/indra/llplugin/tests/llplugincookiestore_test.cpp b/indra/llplugin/tests/llplugincookiestore_test.cpp index aefa1ca144..c2cb236cba 100755 --- a/indra/llplugin/tests/llplugincookiestore_test.cpp +++ b/indra/llplugin/tests/llplugincookiestore_test.cpp @@ -27,6 +27,7 @@   */  #include "linden_common.h" +#include <list>  #include "../test/lltut.h"  #include "../llplugincookiestore.h" diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 1768a06a27..d15ed1ca1f 100755 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -33,7 +33,6 @@ set(llprimitive_SOURCE_FILES      lltextureentry.cpp      lltreeparams.cpp      llvolumemessage.cpp -    llvolumexml.cpp      material_codes.cpp      ) @@ -51,7 +50,6 @@ set(llprimitive_HEADER_FILES      lltreeparams.h      lltree_common.h      llvolumemessage.h -    llvolumexml.h      material_codes.h      object_flags.h      ) diff --git a/indra/llprimitive/llvolumexml.cpp b/indra/llprimitive/llvolumexml.cpp deleted file mode 100755 index bf2297a029..0000000000 --- a/indra/llprimitive/llvolumexml.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**  - * @file llvolumexml.cpp - * @brief LLVolumeXml base class - * - * $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 "linden_common.h" - -#include "llvolumexml.h" - -//============================================================================ - -// LLVolumeXml is just a wrapper class; all members are static - -//============================================================================ - -LLPointer<LLXMLNode> LLVolumeXml::exportProfileParams(const LLProfileParams* params) -{ -	LLPointer<LLXMLNode> ret = new LLXMLNode("profile", FALSE); - -	ret->createChild("curve_type", TRUE)->setByteValue(1, ¶ms->getCurveType()); -	ret->createChild("interval", FALSE)->setFloatValue(2, ¶ms->getBegin()); -	ret->createChild("hollow", FALSE)->setFloatValue(1, ¶ms->getHollow()); - -	return ret; -} - - -LLPointer<LLXMLNode> LLVolumeXml::exportPathParams(const LLPathParams* params) -{ -	LLPointer<LLXMLNode> ret = new LLXMLNode("path", FALSE);  -	ret->createChild("curve_type", TRUE)->setByteValue(1, ¶ms->getCurveType()); -	ret->createChild("interval", FALSE)->setFloatValue(2, ¶ms->getBegin()); -	ret->createChild("scale", FALSE)->setFloatValue(2, params->getScale().mV); -	ret->createChild("shear", FALSE)->setFloatValue(2, params->getShear().mV); -	ret->createChild("twist_interval", FALSE)->setFloatValue(2, ¶ms->getTwistBegin()); -	ret->createChild("radius_offset", FALSE)->setFloatValue(1, ¶ms->getRadiusOffset()); -	ret->createChild("taper", FALSE)->setFloatValue(2, params->getTaper().mV); -	ret->createChild("revolutions", FALSE)->setFloatValue(1, ¶ms->getRevolutions()); -	ret->createChild("skew", FALSE)->setFloatValue(1, ¶ms->getSkew()); - -	return ret; -} - - -LLPointer<LLXMLNode> LLVolumeXml::exportVolumeParams(const LLVolumeParams* params) -{ -	LLPointer<LLXMLNode> ret = new LLXMLNode("shape", FALSE); -	 -	LLPointer<LLXMLNode> node ; -	node = exportPathParams(¶ms->getPathParams()) ; -	node->setParent(ret); -	node = exportProfileParams(¶ms->getProfileParams()) ; -	node->setParent(ret); - -	return ret; -} - diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index c4f36cabd0..a646a0d35a 100755 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -29,6 +29,7 @@  #include "llfontgl.h"  // Linden library includes +#include "llfasttimer.h"  #include "llfontfreetype.h"  #include "llfontbitmapcache.h"  #include "llfontregistry.h" diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index f5ca8d5b04..77aa3fcd2c 100755 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -34,13 +34,15 @@  #include "llcontrol.h"  #include "lldir.h"  #include "llwindow.h" +#include "llxmlnode.h"  extern LLControlGroup gSavedSettings;  using std::string;  using std::map; -bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc); +bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc); +bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);  LLFontDescriptor::LLFontDescriptor():  	mStyle(0) @@ -207,7 +209,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)  		if (root->hasName("fonts"))  		{  			// Expect a collection of children consisting of "font" or "font_size" entries -			bool init_succ = initFromXML(root); +			bool init_succ = init_from_xml(this, root);  			success = success || init_succ;  		}  	} @@ -230,7 +232,7 @@ std::string currentOsName()  #endif  } -bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc) +bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)  {  	if (node->hasName("font"))  	{ @@ -263,14 +265,14 @@ bool fontDescInitFromXML(LLXMLNodePtr node, LLFontDescriptor& desc)  		{  			if (child_name == currentOsName())  			{ -				fontDescInitFromXML(child, desc); +				font_desc_init_from_xml(child, desc);  			}  		}  	}  	return true;  } -bool LLFontRegistry::initFromXML(LLXMLNodePtr node) +bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)  {  	LLXMLNodePtr child; @@ -281,17 +283,17 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)  		if (child->hasName("font"))  		{  			LLFontDescriptor desc; -			bool font_succ = fontDescInitFromXML(child, desc); +			bool font_succ = font_desc_init_from_xml(child, desc);  			LLFontDescriptor norm_desc = desc.normalize();  			if (font_succ)  			{  				// if this is the first time we've seen this font name,  				// create a new template map entry for it. -				const LLFontDescriptor *match_desc = getMatchingFontDesc(desc); +				const LLFontDescriptor *match_desc = registry->getMatchingFontDesc(desc);  				if (match_desc == NULL)  				{  					// Create a new entry (with no corresponding font). -					mFontMap[norm_desc] = NULL; +					registry->mFontMap[norm_desc] = NULL;  				}  				// otherwise, find the existing entry and combine data.   				else @@ -306,8 +308,8 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)  											desc.getFileNames().end());  					LLFontDescriptor new_desc = *match_desc;  					new_desc.getFileNames() = match_file_names; -					mFontMap.erase(*match_desc); -					mFontMap[new_desc] = NULL; +					registry->mFontMap.erase(*match_desc); +					registry->mFontMap[new_desc] = NULL;  				}  			}  		} @@ -318,7 +320,7 @@ bool LLFontRegistry::initFromXML(LLXMLNodePtr node)  			if (child->getAttributeString("name",size_name) &&  				child->getAttributeF32("size",size_value))  			{ -				mFontSizes[size_name] = size_value; +				registry->mFontSizes[size_name] = size_value;  			}  		} diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 059248fbbd..177eb6c8a5 100755 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -28,7 +28,7 @@  #ifndef LL_LLFONTREGISTRY_H  #define LL_LLFONTREGISTRY_H -#include "llxmlnode.h" +#include "llpointer.h"  class LLFontGL; @@ -65,6 +65,7 @@ private:  class LLFontRegistry  {  public: +	friend bool init_from_xml(LLFontRegistry*, LLPointer<class LLXMLNode>);  	// create_gl_textures - set to false for test apps with no OpenGL window,  	// such as llui_libtest  	LLFontRegistry(bool create_gl_textures); @@ -72,7 +73,6 @@ public:  	// Load standard font info from XML file(s).  	bool parseFontInfo(const std::string& xml_filename);  -	bool initFromXML(LLXMLNodePtr node);  	// Clear cached glyphs for all fonts.  	void reset(); @@ -94,6 +94,7 @@ public:  	const string_vec_t& getUltimateFallbackList() const;  private: +	LLFontRegistry(const LLFontRegistry& other); // no-copy  	LLFontGL *createFont(const LLFontDescriptor& desc);  	typedef std::map<LLFontDescriptor,LLFontGL*> font_reg_map_t;  	typedef std::map<std::string,F32> font_size_map_t; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 509de51f4d..c9ce0d5588 100755 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -540,9 +540,7 @@ extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;  // LL_WINDOWS  // windows gl headers depend on things like APIENTRY, so include windows. -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> +#include "llwin32headerslean.h"  //----------------------------------------------------------------------------  #include <GL/gl.h> diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 5c171d372c..2c3fcfcec1 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -32,6 +32,7 @@  #include "llimagegl.h"  #include "llerror.h" +#include "llfasttimer.h"  #include "llimage.h"  #include "llmath.h" @@ -50,9 +51,9 @@ U32 wpo2(U32 i);  U32 LLImageGL::sUniqueCount				= 0;  U32 LLImageGL::sBindCount				= 0; -S32 LLImageGL::sGlobalTextureMemoryInBytes		= 0; -S32 LLImageGL::sBoundTextureMemoryInBytes		= 0; -S32 LLImageGL::sCurBoundTextureMemory	= 0; +LLUnit<LLUnits::Bytes, S32> LLImageGL::sGlobalTextureMemory		= 0; +LLUnit<LLUnits::Bytes, S32> LLImageGL::sBoundTextureMemory		= 0; +LLUnit<LLUnits::Bytes, S32> LLImageGL::sCurBoundTextureMemory	= 0;  S32 LLImageGL::sCount					= 0;  LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];  U32 LLImageGL::sCurTexName = 1; @@ -247,7 +248,7 @@ void LLImageGL::updateStats(F32 current_time)  {  	LLFastTimer t(FTM_IMAGE_UPDATE_STATS);  	sLastFrameTime = current_time; -	sBoundTextureMemoryInBytes = sCurBoundTextureMemory; +	sBoundTextureMemory = sCurBoundTextureMemory;  	sCurBoundTextureMemory = 0;  } @@ -255,7 +256,7 @@ void LLImageGL::updateStats(F32 current_time)  S32 LLImageGL::updateBoundTexMem(const S32 mem, const S32 ncomponents, S32 category)  {  	LLImageGL::sCurBoundTextureMemory += mem ; -	return LLImageGL::sCurBoundTextureMemory; +	return LLImageGL::sCurBoundTextureMemory.value();  }  //---------------------------------------------------------------------------- @@ -624,7 +625,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)  	{  		is_compressed = true;  	} -	 +  	if (mUseMipMaps) @@ -1142,7 +1143,7 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip  						sDeadTextureList[type][format].push_back(textures[i]);  					}	  				}				 -			} +			}	  			break;  		}  	} @@ -1440,7 +1441,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_  	if (old_name != 0)  	{ -		sGlobalTextureMemoryInBytes -= mTextureMemory; +		sGlobalTextureMemory -= mTextureMemory;  		LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name); @@ -1448,7 +1449,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_  	}  	mTextureMemory = getMipBytes(discard_level); -	sGlobalTextureMemoryInBytes += mTextureMemory; +	sGlobalTextureMemory += mTextureMemory;  	mTexelsInGLTexture = getWidth() * getHeight() ;  	// mark this as bound at this point, so we don't throw it out immediately @@ -1607,7 +1608,7 @@ void LLImageGL::destroyGLTexture()  	{  		if(mTextureMemory)  		{ -			sGlobalTextureMemoryInBytes -= mTextureMemory; +			sGlobalTextureMemory -= mTextureMemory;  			mTextureMemory = 0;  		} diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 57a052b258..2b568e5e0f 100755 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -34,6 +34,7 @@  #include "llpointer.h"  #include "llrefcount.h"  #include "v2math.h" +#include "llunit.h"  #include "llrender.h"  class LLTextureAtlas ; @@ -245,9 +246,9 @@ public:  	static F32 sLastFrameTime;  	// Global memory statistics -	static S32 sGlobalTextureMemoryInBytes;		// Tracks main memory texmem -	static S32 sBoundTextureMemoryInBytes;	// Tracks bound texmem for last completed frame -	static S32 sCurBoundTextureMemory;		// Tracks bound texmem for current frame +	static LLUnit<LLUnits::Bytes, S32> sGlobalTextureMemory;	// Tracks main memory texmem +	static LLUnit<LLUnits::Bytes, S32> sBoundTextureMemory;	// Tracks bound texmem for last completed frame +	static LLUnit<LLUnits::Bytes, S32> sCurBoundTextureMemory;		// Tracks bound texmem for current frame  	static U32 sBindCount;					// Tracks number of texture binds for current frame  	static U32 sUniqueCount;				// Tracks number of unique texture binds for current frame  	static BOOL sGlobalUseAnisotropic; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c60eb8d9d9..918f5585a8 100755 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -245,6 +245,11 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)  		return texture->bindDefaultImage(mIndex);  	} +	if(texture->isActiveFetching()) //in debug +	{ +		return texture->bindDebugImage(mIndex); +	} +  	//in audit, replace the selected texture by the default one.  	if ((mCurrTexture != gl_tex->getTexName()) || forceBind)  	{ diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index d3cfbaf03a..9d23a64e4c 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -35,6 +35,7 @@  #include "llrect.h"  #include "llgl.h"  #include "lltexture.h" +#include "llfasttimer.h"  // Project includes  #include "llrender2dutils.h" @@ -353,6 +354,11 @@ void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const  	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );  } +void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color, const LLRectf& uv_rect)
 +{
 +	gl_draw_scaled_rotated_image(x, y, width, height, 0.f, NULL, color, uv_rect, target);
 +}
 +  void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)  {  	if (NULL == image) @@ -639,99 +645,111 @@ void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LL  	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );  } -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect) -{ -	if (NULL == image) -	{ -		llwarns << "image == NULL; aborting function" << llendl; -		return; -	} - -	LLGLSUIDefault gls_ui; - - -	gGL.getTexUnit(0)->bind(image, true); - -	gGL.color4fv(color.mV); - -	if (degrees == 0.f) -	{ -		const S32 NUM_VERTICES = 4; // 9 quads -		LLVector2 uv[NUM_VERTICES]; -		LLVector3 pos[NUM_VERTICES]; - -		gGL.begin(LLRender::QUADS); -		{ -			LLVector3 ui_scale = gGL.getUIScale(); -			LLVector3 ui_translation = gGL.getUITranslation(); -			ui_translation.mV[VX] += x; -			ui_translation.mV[VY] += y; -			ui_translation.scaleVec(ui_scale); -			S32 index = 0; -			S32 scaled_width = llround(width * ui_scale.mV[VX]); -			S32 scaled_height = llround(height * ui_scale.mV[VY]); - -			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); -			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f); -			index++; - -			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); -			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); -			index++; - -			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); -			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); -			index++; - -			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); -			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); -			index++; - -			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); -		} -		gGL.end(); -	} -	else -	{ -		gGL.pushUIMatrix(); -		gGL.translateUI((F32)x, (F32)y, 0.f); -	 -		F32 offset_x = F32(width/2); -		F32 offset_y = F32(height/2); - -		gGL.translateUI(offset_x, offset_y, 0.f); - -		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD); -		 -		gGL.getTexUnit(0)->bind(image, true); - -		gGL.color4fv(color.mV); -		 -		gGL.begin(LLRender::QUADS); -		{ -			LLVector3 v; - -			v = LLVector3(offset_x, offset_y, 0.f) * quat; -			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); -			gGL.vertex2f(v.mV[0], v.mV[1] ); - -			v = LLVector3(-offset_x, offset_y, 0.f) * quat; -			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop); -			gGL.vertex2f(v.mV[0], v.mV[1] ); - -			v = LLVector3(-offset_x, -offset_y, 0.f) * quat; -			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); -			gGL.vertex2f(v.mV[0], v.mV[1] ); - -			v = LLVector3(offset_x, -offset_y, 0.f) * quat; -			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); -			gGL.vertex2f(v.mV[0], v.mV[1] ); -		} -		gGL.end(); -		gGL.popUIMatrix(); -	} -} - +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect, LLRenderTarget* target)
 +{
 +	if (!image && !target)
 +	{
 +		llwarns << "image == NULL; aborting function" << llendl;
 +		return;
 +	}
 +
 +	LLGLSUIDefault gls_ui;
 +
 +	if(image != NULL)
 +	{
 +		gGL.getTexUnit(0)->bind(image, true);
 +	}
 +	else
 +	{
 +		gGL.getTexUnit(0)->bind(target);
 +	}
 +
 +	gGL.color4fv(color.mV);
 +
 +	if (degrees == 0.f)
 +	{
 +		const S32 NUM_VERTICES = 4; // 9 quads
 +		LLVector2 uv[NUM_VERTICES];
 +		LLVector3 pos[NUM_VERTICES];
 +
 +		gGL.begin(LLRender::QUADS);
 +		{
 +			LLVector3 ui_scale = gGL.getUIScale();
 +			LLVector3 ui_translation = gGL.getUITranslation();
 +			ui_translation.mV[VX] += x;
 +			ui_translation.mV[VY] += y;
 +			ui_translation.scaleVec(ui_scale);
 +			S32 index = 0;
 +			S32 scaled_width = llround(width * ui_scale.mV[VX]);
 +			S32 scaled_height = llround(height * ui_scale.mV[VY]);
 +
 +			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
 +			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
 +			index++;
 +
 +			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
 +			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
 +			index++;
 +
 +			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
 +			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
 +			index++;
 +
 +			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
 +			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
 +			index++;
 +
 +			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
 +		}
 +		gGL.end();
 +	}
 +	else
 +	{
 +		gGL.pushUIMatrix();
 +		gGL.translateUI((F32)x, (F32)y, 0.f);
 +
 +		F32 offset_x = F32(width/2);
 +		F32 offset_y = F32(height/2);
 +
 +		gGL.translateUI(offset_x, offset_y, 0.f);
 +
 +		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
 +
 +		if(image != NULL)
 +		{
 +			gGL.getTexUnit(0)->bind(image, true);
 +		}
 +		else
 +		{
 +			gGL.getTexUnit(0)->bind(target);
 +		}
 +
 +		gGL.color4fv(color.mV);
 +
 +		gGL.begin(LLRender::QUADS);
 +		{
 +			LLVector3 v;
 +
 +			v = LLVector3(offset_x, offset_y, 0.f) * quat;
 +			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
 +			gGL.vertex2f(v.mV[0], v.mV[1] );
 +
 +			v = LLVector3(-offset_x, offset_y, 0.f) * quat;
 +			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
 +			gGL.vertex2f(v.mV[0], v.mV[1] );
 +
 +			v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
 +			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
 +			gGL.vertex2f(v.mV[0], v.mV[1] );
 +
 +			v = LLVector3(offset_x, -offset_y, 0.f) * quat;
 +			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
 +			gGL.vertex2f(v.mV[0], v.mV[1] );
 +		}
 +		gGL.end();
 +		gGL.popUIMatrix();
 +	}
 +}
  void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )  { @@ -1044,6 +1062,8 @@ void gl_rect_2d_simple( S32 width, S32 height )  	gGL.end();  } +static LLFastTimer::DeclareTimer FTM_RENDER_SEGMENTED_RECT ("Render segmented rectangle"); +  void gl_segmented_rect_2d_tex(const S32 left,   							  const S32 top,   							  const S32 right,  @@ -1053,6 +1073,8 @@ void gl_segmented_rect_2d_tex(const S32 left,  							  const S32 border_size,   							  const U32 edges)  { +	LLFastTimer _(FTM_RENDER_SEGMENTED_RECT); +  	S32 width = llabs(right - left);  	S32 height = llabs(top - bottom); @@ -1202,18 +1224,19 @@ void gl_segmented_rect_2d_tex(const S32 left,  	gGL.popUIMatrix();  } -//FIXME: rewrite to use scissor? -void gl_segmented_rect_2d_fragment_tex(const S32 left,  -									   const S32 top,  -									   const S32 right,  -									   const S32 bottom,  -									   const S32 texture_width,  -									   const S32 texture_height,  -									   const S32 border_size,  -									   const F32 start_fragment,  -									   const F32 end_fragment,  -									   const U32 edges) +void gl_segmented_rect_2d_fragment_tex(const LLRect& rect,  +	const S32 texture_width,  +	const S32 texture_height,  +	const S32 border_size,  +	const F32 start_fragment,  +	const F32 end_fragment,  +	const U32 edges)  { +	LLFastTimer _(FTM_RENDER_SEGMENTED_RECT); +	const S32 left = rect.mLeft; +	const S32 right = rect.mRight; +	const S32 top = rect.mTop; +	const S32 bottom = rect.mBottom;  	S32 width = llabs(right - left);  	S32 height = llabs(top - bottom); @@ -1251,9 +1274,9 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,  	{  		if (start_fragment < middle_start)  		{ -			u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX]; +			u_min = (start_fragment / middle_start)			* border_uv_scale.mV[VX];  			u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX]; -			x_min = (start_fragment / middle_start) * border_width_left; +			x_min = (start_fragment / middle_start)			* border_width_left;  			x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;  			// draw bottom left @@ -1281,7 +1304,7 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,  			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);  			gGL.vertex2fv((x_min + height_vec - border_height_top).mV); -			 +  			// draw top left  			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);  			gGL.vertex2fv((x_min + height_vec - border_height_top).mV); @@ -1343,10 +1366,10 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,  		if (end_fragment > middle_end)  		{ -			u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX]; -			u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]; -			x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right); -			x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right); +			u_min = 1.f			- ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]); +			u_max = 1.f			- ((1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX]); +			x_min = width_vec	- ((1.f - llmax(0.f, (start_fragment - middle_end) / middle_start)) * border_width_right); +			x_max = width_vec	- ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);  			// draw bottom right  			gGL.texCoord2f(u_min, 0.f); @@ -1396,6 +1419,8 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,  void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect,   							 const LLVector3& width_vec, const LLVector3& height_vec)  { +	LLFastTimer _(FTM_RENDER_SEGMENTED_RECT); +  	gGL.begin(LLRender::QUADS);  	{  		// draw bottom left diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h index 4884422c58..2b8964742b 100644 --- a/indra/llrender/llrender2dutils.h +++ b/indra/llrender/llrender2dutils.h @@ -71,9 +71,10 @@ void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4&  void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);  void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_target(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* target, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));  void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));  void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); -void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); +void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), LLRenderTarget* target = NULL);  void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));  void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f)); @@ -105,7 +106,7 @@ typedef enum e_rounded_edge  void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL); -void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL); +void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);  void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);  inline void gl_rect_2d( const LLRect& rect, BOOL filled ) diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h index 093bac20d1..ff711b8004 100755 --- a/indra/llrender/lltexture.h +++ b/indra/llrender/lltexture.h @@ -57,10 +57,12 @@ public:  	virtual S8         getType() const = 0 ;  	virtual void       setKnownDrawSize(S32 width, S32 height) = 0 ;  	virtual bool       bindDefaultImage(const S32 stage = 0) = 0 ; +	virtual bool       bindDebugImage(const S32 stage = 0) = 0;  	virtual void       forceImmediateUpdate() = 0 ;  	virtual void       setActive() = 0 ;  	virtual S32	       getWidth(S32 discard_level = -1) const = 0 ;  	virtual S32	       getHeight(S32 discard_level = -1) const = 0 ; +	virtual bool       isActiveFetching() = 0;  private:  	//note: do not make this function public. diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4909b43e8a..55a616ef34 100755 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -26,7 +26,7 @@  #include "linden_common.h" -#include <boost/static_assert.hpp> +#include "llfasttimer.h"  #include "llsys.h"  #include "llvertexbuffer.h"  // #include "llrender.h" diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 34a08603fa..c4270a62bd 100755 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -61,7 +61,6 @@ set(llui_SOURCE_FILES      llfolderview.cpp      llfolderviewitem.cpp      llfolderviewmodel.cpp -    llfunctorregistry.cpp      lliconctrl.cpp      llkeywords.cpp      lllayoutstack.cpp diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 43462bd244..53720a6044 100755 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -444,9 +444,9 @@ void LLAccordionCtrlTab::changeOpenClose(bool is_open)  	}  } -void LLAccordionCtrlTab::handleVisibilityChange(BOOL new_visibility) +void LLAccordionCtrlTab::onVisibilityChange(BOOL new_visibility)  { -	LLUICtrl::handleVisibilityChange(new_visibility); +	LLUICtrl::onVisibilityChange(new_visibility);  	notifyParent(LLSD().with("child_visibility_change", new_visibility));  } diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index dddaa581e6..7a78700e0f 100755 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -158,7 +158,7 @@ public:  	/**  	 * Raises notifyParent event with "child_visibility_change" = new_visibility  	 */ -	void handleVisibilityChange(BOOL new_visibility); +	void onVisibilityChange(BOOL new_visibility);  	// Changes expand/collapse state and triggers expand/collapse callbacks  	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index a8149a9a1d..ce4d137478 100755 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -779,11 +779,11 @@ void LLButton::draw()  	{  		mCurGlowStrength = lerp(mCurGlowStrength,  					mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress() || mNeedsHighlight? 1.0 : 0.0) : mHoverGlowStrength, -					LLCriticalDamp::getInterpolant(0.05f)); +					LLSmoothInterpolation::getInterpolant(0.05f));  	}  	else  	{ -		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f)); +		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLSmoothInterpolation::getInterpolant(0.05f));  	}  	// Draw button image, if available. diff --git a/indra/llui/llcontainerview.cpp b/indra/llui/llcontainerview.cpp index e08ccb0b78..06f8e72c9c 100755 --- a/indra/llui/llcontainerview.cpp +++ b/indra/llui/llcontainerview.cpp @@ -49,7 +49,6 @@ LLContainerView::LLContainerView(const LLContainerView::Params& p)  	mLabel(p.label),  	mDisplayChildren(p.display_children)  { -	mCollapsible = TRUE;  	mScrollContainer = NULL;  } @@ -75,6 +74,11 @@ bool LLContainerView::addChild(LLView* child, S32 tab_group)  	return res;  } +BOOL LLContainerView::handleDoubleClick(S32 x, S32 y, MASK mask) +{ +	return handleMouseDown(x, y, mask); +} +  BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask)  {  	BOOL handled = FALSE; @@ -84,7 +88,7 @@ BOOL LLContainerView::handleMouseDown(S32 x, S32 y, MASK mask)  	}  	if (!handled)  	{ -		if( mCollapsible && mShowLabel && (y >= getRect().getHeight() - 10) ) +		if( mShowLabel && (y >= getRect().getHeight() - 10) )  		{  			setDisplayChildren(!mDisplayChildren);  			reshape(getRect().getWidth(), getRect().getHeight(), FALSE); diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h index e81600fd6c..ac92b19977 100755 --- a/indra/llui/llcontainerview.h +++ b/indra/llui/llcontainerview.h @@ -66,6 +66,7 @@ public:  	/*virtual*/ BOOL postBuild();  	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); +	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); @@ -87,8 +88,5 @@ public:  protected:  	BOOL mDisplayChildren;  	std::string mLabel; -public: -	BOOL mCollapsible; -  };  #endif // LL_CONTAINERVIEW_ diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 09e27a264a..d06e2c9334 100755 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -598,7 +598,7 @@ LLControlGroup*	LLFloater::getControlGroup()  void LLFloater::setVisible( BOOL visible )  { -	LLPanel::setVisible(visible); // calls handleVisibilityChange() +	LLPanel::setVisible(visible); // calls onVisibilityChange()  	if( visible && mFirstLook )  	{  		mFirstLook = FALSE; @@ -641,21 +641,21 @@ void LLFloater::setIsSingleInstance(BOOL is_single_instance)  // virtual -void LLFloater::handleVisibilityChange ( BOOL new_visibility ) +void LLFloater::onVisibilityChange ( BOOL new_visibility )  {  	if (new_visibility)  	{  		if (getHost())  			getHost()->setFloaterFlashing(this, FALSE);  	} -	LLPanel::handleVisibilityChange ( new_visibility ); +	LLPanel::onVisibilityChange ( new_visibility );  }  void LLFloater::openFloater(const LLSD& key)  {  	llinfos << "Opening floater " << getName() << llendl;  	mKey = key; // in case we need to open ourselves again - +	  	if (getSoundFlags() != SILENT   	// don't play open sound for hosted (tabbed) windows  		&& !getHost()  @@ -803,7 +803,7 @@ void LLFloater::closeFloater(bool app_quitting)  		}  		else  		{ -			setVisible(FALSE); // hide before destroying (so handleVisibilityChange() gets called) +			setVisible(FALSE); // hide before destroying (so onVisibilityChange() gets called)  			if (!mReuseInstance)  			{  				destroy(); @@ -1157,11 +1157,11 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)  			{  				setDocked( false, false);  			} -			storeRectControl(); -			mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; -			LLRect screen_rect = calcScreenRect(); -			mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); -		} +		storeRectControl(); +		mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; +		LLRect screen_rect = calcScreenRect(); +		mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); +	}  		// gather all snapped dependents  		for(handle_set_iter_t dependent_it = mDependents.begin(); @@ -3149,7 +3149,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str  			parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName());  			setupParamsForExport(output_params, parent);  			output_node->setName(node->getName()->mString); -			parser.writeXUI(output_node, output_params, &default_params); +			parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params);  			return TRUE;  		} @@ -3179,9 +3179,8 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str  	{  		Params output_params(params);  		setupParamsForExport(output_params, parent); -        Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>());  		output_node->setName(node->getName()->mString); -		parser.writeXUI(output_node, output_params, &default_params); +		parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params);  	}  	// Default floater position to top-left corner of screen diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 4dba1e645f..ad0b800f1c 100755 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -302,7 +302,7 @@ public:  	virtual BOOL	canClose() { return TRUE; }  	/*virtual*/ void setVisible(BOOL visible); // do not override -	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override +	/*virtual*/ void onVisibilityChange ( BOOL new_visibility ); // do not override  	void			setFrontmost(BOOL take_focus = TRUE);      virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());     diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index a1e1f8a988..e3b17dcb4f 100755 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -30,6 +30,7 @@  #include "llrect.h"  #include "llsd.h" +#include <list>  #include <boost/function.hpp>  //******************************************************* diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index fdb4108afb..c7910cb883 100755..100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -489,7 +489,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )  	// No handler needed for focus lost since this class has no  	// state that depends on it.  	gFocusMgr.setMouseCapture( this ); -     +  	if (!mIsSelected)  	{  		if(mask & MASK_CONTROL) @@ -706,7 +706,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo                  bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);              }          	gl_rect_2d(FOCUS_LEFT, -					   focus_top, +					   focus_top,   					   getRect().getWidth() - 2,  					   focus_bottom,  					   bg_color, hasKeyboardFocus); @@ -860,7 +860,7 @@ void LLFolderViewItem::draw()  						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,  						  S32_MAX, S32_MAX, &right_x, FALSE );  	} -     +  	//--------------------------------------------------------------------------------//  	// Highlight string match  	// @@ -882,7 +882,7 @@ const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) c  {  	return getRoot()->getFolderViewModel();  } - +		  LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )  {  	return getRoot()->getFolderViewModel(); @@ -919,11 +919,11 @@ void LLFolderViewFolder::updateLabelRotation()  	}  	else if (isOpen())  	{ -		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f)); +		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLSmoothInterpolation::getInterpolant(0.04f));  	}  	else  	{ -		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f)); +		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLSmoothInterpolation::getInterpolant(0.025f));  	}  } @@ -1056,7 +1056,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )  	// animate current height towards target height  	if (llabs(mCurHeight - mTargetHeight) > 1.f)  	{ -		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT)); +		mCurHeight = lerp(mCurHeight, mTargetHeight, LLSmoothInterpolation::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));  		requestArrange(); @@ -1577,7 +1577,7 @@ void LLFolderViewFolder::addItem(LLFolderViewItem* item)  	item->setVisible(FALSE);  	addChild(item); - +	  	// When the model is already hooked into a hierarchy (i.e. has a parent), do not reparent it  	// Note: this happens when models are created before views or shared between views  	if (!item->getViewModelItem()->hasParent()) diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index e33ac1d5c2..edb32954c6 100755 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -41,12 +41,6 @@ static const F32 MAX_FRACTIONAL_SIZE = 1.f;  static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");  static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel"); -void LLLayoutStack::OrientationNames::declareValues() -{ -	declare("horizontal", HORIZONTAL); -	declare("vertical", VERTICAL); -} -  //  // LLLayoutPanel  // @@ -140,7 +134,7 @@ S32 LLLayoutPanel::getVisibleDim() const  						+ (((F32)mTargetDim - min_dim) * (1.f - mCollapseAmt))));  } -void LLLayoutPanel::setOrientation( LLLayoutStack::ELayoutOrientation orientation ) +void LLLayoutPanel::setOrientation( LLView::EOrientation orientation )  {  	mOrientation = orientation;  	S32 layout_dim = llround((F32)((mOrientation == LLLayoutStack::HORIZONTAL) @@ -590,7 +584,7 @@ bool LLLayoutStack::animatePanels()  			{  				if (!mAnimatedThisFrame)  				{ -					panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(mOpenTimeConstant)); +					panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 1.f, LLSmoothInterpolation::getInterpolant(mOpenTimeConstant));  					if (panelp->mVisibleAmt > 0.99f)  					{  						panelp->mVisibleAmt = 1.f; @@ -615,7 +609,7 @@ bool LLLayoutStack::animatePanels()  			{  				if (!mAnimatedThisFrame)  				{ -					panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); +					panelp->mVisibleAmt = lerp(panelp->mVisibleAmt, 0.f, LLSmoothInterpolation::getInterpolant(mCloseTimeConstant));  					if (panelp->mVisibleAmt < 0.001f)  					{  						panelp->mVisibleAmt = 0.f; @@ -642,7 +636,7 @@ bool LLLayoutStack::animatePanels()  			{  				if (!mAnimatedThisFrame)  				{ -					panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); +					panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLSmoothInterpolation::getInterpolant(mCloseTimeConstant));  				}  				if (llabs(panelp->mCollapseAmt - collapse_state) < 0.001f) diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 02c664f1a0..5930741d5c 100755 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -38,24 +38,13 @@ class LLLayoutPanel;  class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>  {  public: -	typedef enum e_layout_orientation -	{ -		HORIZONTAL, -		VERTICAL -	} ELayoutOrientation; - -	struct OrientationNames -	:	public LLInitParam::TypeValuesHelper<ELayoutOrientation, OrientationNames> -	{ -		static void declareValues(); -	};  	struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry>  	{};  	struct Params : public LLInitParam::Block<Params, LLView::Params>  	{ -		Mandatory<ELayoutOrientation, OrientationNames>	orientation; +		Mandatory<EOrientation>	orientation;  		Optional<S32>			border_size;  		Optional<bool>			animate,  								clip; @@ -105,7 +94,7 @@ private:  	bool animatePanels();  	void createResizeBar(LLLayoutPanel* panel); -	const ELayoutOrientation mOrientation; +	const EOrientation mOrientation;  	typedef std::vector<LLLayoutPanel*> e_panel_list_t;  	e_panel_list_t mPanels; @@ -183,7 +172,7 @@ public:  	bool isCollapsed() const { return mCollapsed;} -	void setOrientation(LLLayoutStack::ELayoutOrientation orientation); +	void setOrientation(LLView::EOrientation orientation);  	void storeOriginalDim();  	void setIgnoreReshape(bool ignore) { mIgnoreReshape = ignore; } @@ -202,7 +191,7 @@ protected:  	F32		mFractionalSize;  	S32		mTargetDim;  	bool	mIgnoreReshape; -	LLLayoutStack::ELayoutOrientation mOrientation; +	LLView::EOrientation mOrientation;  	class LLResizeBar* mResizeBar;  }; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index f7bf39c897..385dbc6e19 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -549,13 +549,13 @@ BOOL LLMenuItemGL::setLabelArg( const std::string& key, const LLStringExplicit&  	return TRUE;  } -void LLMenuItemGL::handleVisibilityChange(BOOL new_visibility) +void LLMenuItemGL::onVisibilityChange(BOOL new_visibility)  {  	if (getMenu())  	{  		getMenu()->needsArrange();  	} -	LLView::handleVisibilityChange(new_visibility); +	LLView::onVisibilityChange(new_visibility);  }  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1146,13 +1146,13 @@ void LLMenuItemBranchGL::updateBranchParent(LLView* parentp)  	}  } -void LLMenuItemBranchGL::handleVisibilityChange( BOOL new_visibility ) +void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility )  {  	if (new_visibility == FALSE && getBranch() && !getBranch()->getTornOff())  	{  		getBranch()->setVisible(FALSE);  	} -	LLMenuItemGL::handleVisibilityChange(new_visibility); +	LLMenuItemGL::onVisibilityChange(new_visibility);  }  BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) @@ -1794,7 +1794,7 @@ bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)  	{  		return appendMenu(menup);  	} -	 +  	return false;  } @@ -3749,7 +3749,7 @@ void LLTearOffMenu::draw()  	if (getRect().getHeight() != mTargetHeight)  	{  		// animate towards target height -		reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLCriticalDamp::getInterpolant(0.05f)))); +		reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f))));  	}  	LLFloater::draw();  } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 51df5df1f8..feafaab199 100755 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -82,7 +82,7 @@ protected:  	friend class LLUICtrlFactory;  public:  	// LLView overrides -	/*virtual*/ void handleVisibilityChange(BOOL new_visibility); +	/*virtual*/ void onVisibilityChange(BOOL new_visibility);  	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); @@ -637,7 +637,7 @@ public:  	virtual void updateBranchParent( LLView* parentp );  	// LLView Functionality -	virtual void handleVisibilityChange( BOOL curVisibilityIn ); +	virtual void onVisibilityChange( BOOL curVisibilityIn );  	virtual void draw(); diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index d992212650..c1b1a357ed 100755 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -100,6 +100,3 @@ private:  };  #endif  // LL_MULTI_FLOATER_H - - - diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 1789f003b9..37b0a52036 100755 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -516,7 +516,7 @@ LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) :  LLSD LLNotification::asLLSD(bool excludeTemplateElements) -{ +{   	LLParamSDParser parser;  	Params p; @@ -544,12 +544,12 @@ LLSD LLNotification::asLLSD(bool excludeTemplateElements)          mForm->getElements(dynamicElements, templateForm->getNumElements());          p.form_elements = dynamicElements;      } -     +      if(mResponder)      {          p.functor.responder_sd = mResponder->asLLSD();      } -     +  	if(!mResponseFunctorName.empty())  	{  		p.functor.name = mResponseFunctorName; diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 87573c2a56..2948f88755 100755 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -92,6 +92,7 @@  #include "llevents.h"  #include "llfunctorregistry.h"  #include "llinitparam.h" +#include "llinstancetracker.h"  #include "llmortician.h"  #include "llnotificationptr.h"  #include "llpointer.h" @@ -845,7 +846,7 @@ public:      Iterator begin();      Iterator end();  	size_t size(); - +	  	std::string summarize();  private: diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h index 18a82190b5..0315ddbea8 100755 --- a/indra/llui/llnotificationtemplate.h +++ b/indra/llui/llnotificationtemplate.h @@ -28,32 +28,9 @@  #ifndef LL_LLNOTIFICATION_TEMPLATE_H  #define LL_LLNOTIFICATION_TEMPLATE_H -//#include <string> -//#include <list> -//#include <vector> -//#include <map> -//#include <set> -//#include <iomanip> -//#include <sstream> -// -//#include <boost/utility.hpp> -//#include <boost/shared_ptr.hpp> -//#include <boost/enable_shared_from_this.hpp> -//#include <boost/type_traits.hpp> -// -//// we want to minimize external dependencies, but this one is important -//#include "llsd.h" -// -//// and we need this to manage the notification callbacks -//#include "llevents.h" -//#include "llfunctorregistry.h" -//#include "llpointer.h"  #include "llinitparam.h" -//#include "llnotificationptr.h" -//#include "llcachename.h"  #include "llnotifications.h" -  typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;  // This is the class of object read from the XML file (notifications.xml,  diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 67472ad166..f157d6a923 100755 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -342,9 +342,9 @@ BOOL LLPanel::handleKeyHere( KEY key, MASK mask )  	return handled;  } -void LLPanel::handleVisibilityChange ( BOOL new_visibility ) +void LLPanel::onVisibilityChange ( BOOL new_visibility )  { -	LLUICtrl::handleVisibilityChange ( new_visibility ); +	LLUICtrl::onVisibilityChange ( new_visibility );  	if (mVisibleSignal)  		(*mVisibleSignal)(this, LLSD(new_visibility) ); // Pass BOOL as LLSD  } @@ -520,7 +520,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu  				Params output_params(params);  				setupParamsForExport(output_params, parent);  				output_node->setName(node->getName()->mString); -				parser.writeXUI(output_node, output_params, &default_params); +				parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params);  				return TRUE;  			} @@ -551,7 +551,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu  			Params output_params(params);  			setupParamsForExport(output_params, parent);  			output_node->setName(node->getName()->mString); -			parser.writeXUI(output_node, output_params, &default_params); +			parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &default_params);  		}  		params.from_xui = true; diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index e63b41f97c..ac8583ece9 100755 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -115,7 +115,7 @@ public:  	/*virtual*/ BOOL 	isPanel() const;  	/*virtual*/ void	draw();	  	/*virtual*/ BOOL	handleKeyHere( KEY key, MASK mask ); -	/*virtual*/ void 	handleVisibilityChange ( BOOL new_visibility ); +	/*virtual*/ void 	onVisibilityChange ( BOOL new_visibility );  	// From LLFocusableElement  	/*virtual*/ void	setFocus( BOOL b ); diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 13887cbe73..bef1854748 100755 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -493,11 +493,11 @@ void LLScrollbar::draw()  	BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y));  	if (hovered)  	{ -		mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLCriticalDamp::getInterpolant(0.05f)); +		mCurGlowStrength = lerp(mCurGlowStrength, mHoverGlowStrength, LLSmoothInterpolation::getInterpolant(0.05f));  	}  	else  	{ -		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLCriticalDamp::getInterpolant(0.05f)); +		mCurGlowStrength = lerp(mCurGlowStrength, 0.f, LLSmoothInterpolation::getInterpolant(0.05f));  	}  	// Draw background and thumb. diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 21fd2d631e..e2bf52c14b 100755 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -40,13 +40,11 @@ class LLScrollbar  {  public: -	enum ORIENTATION { HORIZONTAL, VERTICAL }; -	  	typedef boost::function<void (S32, LLScrollbar*)> callback_t;  	struct Params   	:	public LLInitParam::Block<Params, LLUICtrl::Params>  	{ -		Mandatory<ORIENTATION>			orientation; +		Mandatory<EOrientation>			orientation;  		Mandatory<S32>					doc_size;  		Mandatory<S32>					doc_pos;  		Mandatory<S32>					page_size; @@ -124,7 +122,7 @@ public:  	void				onLineUpBtnPressed(const LLSD& data);  	void				onLineDownBtnPressed(const LLSD& data); -		 +  	S32					getThickness() const { return mThickness; }  	void				setThickness(S32 thickness); @@ -134,7 +132,7 @@ private:  	callback_t			mChangeCallback; -	const ORIENTATION	mOrientation;	 +	const EOrientation	mOrientation;	  	S32					mDocSize;		// Size of the document that the scrollbar is modeling.  Units depend on the user.  0 <= mDocSize.  	S32					mDocPos;		// Position within the doc that the scrollbar is modeling, in "lines" (user size)  	S32					mPageSize;		// Maximum number of lines that can be seen at one time. diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index cbcce0ece5..3b5fb2adfb 100755 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -144,7 +144,7 @@ LLScrollContainer::~LLScrollContainer( void )  {  	// mScrolledView and mScrollbar are child views, so the LLView  	// destructor takes care of memory deallocation. -	for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) +	for( S32 i = 0; i < ORIENTATION_COUNT; i++ )  	{  		mScrollbar[i] = NULL;  	} @@ -215,7 +215,7 @@ BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)  	{  		return TRUE;  	} -	for( S32 i = 0; i < SCROLLBAR_COUNT; i++ ) +	for( S32 i = 0; i < ORIENTATION_COUNT; i++ )  	{  		if( mScrollbar[i]->handleKeyHere(key, mask) )  		{ diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index 4eb43539b8..b67236c939 100755 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -56,7 +56,6 @@ class LLScrollContainer : public LLUICtrl  public:  	// Note: vertical comes before horizontal because vertical  	// scrollbars have priority for mouse and keyboard events. -	enum SCROLL_ORIENTATION { VERTICAL, HORIZONTAL, SCROLLBAR_COUNT };  	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>  	{ @@ -130,7 +129,7 @@ private:  	void updateScroll();  	void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const; -	LLScrollbar* mScrollbar[SCROLLBAR_COUNT]; +	LLScrollbar* mScrollbar[ORIENTATION_COUNT];  	S32			mSize;  	BOOL		mIsOpaque;  	LLUIColor	mBackgroundColor; diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h index 700c17ea3e..3b492d8182 100755 --- a/indra/llui/llslider.h +++ b/indra/llui/llslider.h @@ -34,8 +34,6 @@  class LLSlider : public LLF32UICtrl  {  public: -	enum ORIENTATION { HORIZONTAL, VERTICAL }; -  	struct Params : public LLInitParam::Block<Params, LLF32UICtrl::Params>  	{  		Optional<std::string> orientation; @@ -98,7 +96,7 @@ private:  	LLPointer<LLUIImage>	mTrackHighlightHorizontalImage;  	LLPointer<LLUIImage>	mTrackHighlightVerticalImage; -	const ORIENTATION	mOrientation; +	const EOrientation	mOrientation;  	LLRect		mThumbRect;  	LLUIColor	mTrackColor; diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 04cce7878e..6966df8213 100755 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -34,8 +34,9 @@  #include "llgl.h"  #include "llfontgl.h" -#include "llstat.h"  #include "lluictrlfactory.h" +#include "lltracerecording.h" +#include "llcriticaldamp.h"  /////////////////////////////////////////////////////////////////////////////////// @@ -45,68 +46,105 @@ LLStatBar::LLStatBar(const Params& p)  	  mUnitLabel(p.unit_label),  	  mMinBar(p.bar_min),  	  mMaxBar(p.bar_max), -	  mStatp(LLStat::getStat(p.stat)), +	  mCurMaxBar(p.bar_max),  	  mTickSpacing(p.tick_spacing), -	  mLabelSpacing(p.label_spacing),  	  mPrecision(p.precision),  	  mUpdatesPerSec(p.update_rate), +	  mUnitScale(p.unit_scale), +	  mNumFrames(p.num_frames), +	  mMaxHeight(p.max_height),  	  mPerSec(p.show_per_sec),  	  mDisplayBar(p.show_bar),  	  mDisplayHistory(p.show_history), -	  mDisplayMean(p.show_mean) +	  mDisplayMean(p.show_mean), +	  mOrientation(p.orientation), +	  mScaleRange(p.scale_range)  { +	setStat(p.stat);  }  BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask)  { -	if (mDisplayBar) +	BOOL handled = LLView::handleMouseDown(x, y, mask); +	if (!handled)  	{ -		if (mDisplayHistory) +		if (mDisplayBar)  		{ -			mDisplayBar = FALSE; -			mDisplayHistory = FALSE; +			if (mDisplayHistory || mOrientation == HORIZONTAL) +			{ +				mDisplayBar = FALSE; +				mDisplayHistory = FALSE; +			} +			else +			{ +				mDisplayHistory = TRUE; +			}  		}  		else  		{ -			mDisplayHistory = TRUE; +			mDisplayBar = TRUE; +			if (mOrientation == HORIZONTAL) +			{ +				mDisplayHistory = TRUE; +			}  		} +		LLView* parent = getParent(); +		parent->reshape(parent->getRect().getWidth(), parent->getRect().getHeight(), FALSE);  	} -	else -	{ -		mDisplayBar = TRUE; -	} - -	LLView* parent = getParent(); -	parent->reshape(parent->getRect().getWidth(), parent->getRect().getHeight(), FALSE); - -	return FALSE; +	return TRUE;  }  void LLStatBar::draw()  { -	if (!mStatp) +	F32 current = 0.f,  +		min     = 0.f,  +		max     = 0.f, +		mean    = 0.f; + +	LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); + +	if (mCountFloatp)  	{ -//		llinfos << "No stats for statistics bar!" << llendl; -		return; -	} +		LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording();  -	// Get the values. -	F32 current, min, max, mean; -	if (mPerSec) +		if (mPerSec) +		{ +			current = last_frame_recording.getPerSec(*mCountFloatp); +			min     = frame_recording.getPeriodMinPerSec(*mCountFloatp, mNumFrames); +			max     = frame_recording.getPeriodMaxPerSec(*mCountFloatp, mNumFrames); +			mean    = frame_recording.getPeriodMeanPerSec(*mCountFloatp, mNumFrames); +		} +		else +		{ +			current = last_frame_recording.getSum(*mCountFloatp); +			min     = frame_recording.getPeriodMin(*mCountFloatp, mNumFrames); +			max     = frame_recording.getPeriodMax(*mCountFloatp, mNumFrames); +			mean    = frame_recording.getPeriodMean(*mCountFloatp, mNumFrames); +		} +	} +	else if (mEventFloatp)  	{ -		current = mStatp->getCurrentPerSec(); -		min = mStatp->getMinPerSec(); -		max = mStatp->getMaxPerSec(); -		mean = mStatp->getMeanPerSec(); +		LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); + +		current = last_frame_recording.getMean(*mEventFloatp); +		min     = frame_recording.getPeriodMin(*mEventFloatp, mNumFrames); +		max     = frame_recording.getPeriodMax(*mEventFloatp, mNumFrames); +		mean    = frame_recording.getPeriodMean(*mEventFloatp, mNumFrames);  	} -	else +	else if (mSampleFloatp)  	{ -		current = mStatp->getCurrent(); -		min = mStatp->getMin(); -		max = mStatp->getMax(); -		mean = mStatp->getMean(); +		LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); + +		current = last_frame_recording.getLastValue(*mSampleFloatp); +		min     = frame_recording.getPeriodMin(*mSampleFloatp, mNumFrames); +		max     = frame_recording.getPeriodMax(*mSampleFloatp, mNumFrames); +		mean    = frame_recording.getPeriodMean(*mSampleFloatp, mNumFrames);  	} +	current *= mUnitScale; +	min     *= mUnitScale; +	max     *= mUnitScale; +	mean    *= mUnitScale;  	if ((mUpdatesPerSec == 0.f) || (mUpdateTimer.getElapsedTimeF32() > 1.f/mUpdatesPerSec) || (mValue == 0.f))  	{ @@ -121,15 +159,41 @@ void LLStatBar::draw()  		mUpdateTimer.reset();  	} -	S32 width = getRect().getWidth() - 40; -	S32 max_width = width; -	S32 bar_top = getRect().getHeight() - 15; // 16 pixels from top. -	S32 bar_height = bar_top - 20; -	S32 tick_height = 4; -	S32 tick_width = 1; -	S32 left, top, right, bottom; +	S32 bar_top, bar_left, bar_right, bar_bottom; +	if (mOrientation == HORIZONTAL) +	{ +		bar_top    = llmax(5, getRect().getHeight() - 15);  +		bar_left   = 0; +		bar_right  = getRect().getWidth() - 40; +		bar_bottom = llmin(bar_top - 5, 0); +	} +	else // VERTICAL +	{ +		bar_top    = llmax(5, getRect().getHeight() - 15);  +		bar_left   = 0; +		bar_right  = getRect().getWidth(); +		bar_bottom = llmin(bar_top - 5, 20); +	} +	const S32 tick_length = 4; +	const S32 tick_width = 1; -	F32 value_scale = max_width/(mMaxBar - mMinBar); +	if (mScaleRange && min < max) +	{ +		F32 cur_max = mTickSpacing; +		while(max > cur_max && mMaxBar > cur_max) +		{ +			cur_max += mTickSpacing; +		} +		mCurMaxBar = LLSmoothInterpolation::lerp(mCurMaxBar, cur_max, 0.05f); +	} +	else +	{ +		mCurMaxBar = mMaxBar; +	} + +	F32 value_scale = (mOrientation == HORIZONTAL)  +					? (bar_top - bar_bottom)/(mCurMaxBar - mMinBar) +					: (bar_right - bar_left)/(mCurMaxBar - mMinBar);  	LLFontGL::getFontMonospace()->renderUTF8(mLabel, 0, 0, getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, 1.f),  											 LLFontGL::LEFT, LLFontGL::TOP); @@ -148,120 +212,231 @@ void LLStatBar::draw()  	}  	// Draw the value. -	LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, width, getRect().getHeight(),  -											 LLColor4(1.f, 1.f, 1.f, 0.5f), -											 LLFontGL::RIGHT, LLFontGL::TOP); +	if (mOrientation == HORIZONTAL) +	{ +		LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_right, getRect().getHeight(),  +			LLColor4(1.f, 1.f, 1.f, 0.5f), +			LLFontGL::RIGHT, LLFontGL::TOP); +	} +	else +	{ +		LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_right, getRect().getHeight(),  +			LLColor4(1.f, 1.f, 1.f, 0.5f), +			LLFontGL::RIGHT, LLFontGL::TOP); +	}  	value_format = llformat( "%%.%df", mPrecision); -	if (mDisplayBar) +	if (mDisplayBar && (mCountFloatp || mEventFloatp || mSampleFloatp))  	{  		std::string tick_label;  		// Draw the tick marks. -		F32 tick_value; -		top = bar_top; -		bottom = bar_top - bar_height - tick_height/2; -  		LLGLSUIDefault gls_ui;  		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - -		for (tick_value = mMinBar; tick_value <= mMaxBar; tick_value += mTickSpacing) -		{ -			left = llfloor((tick_value - mMinBar)*value_scale); -			right = left + tick_width; -			gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.1f)); -		} - -		// Draw the tick labels (and big ticks). -		bottom = bar_top - bar_height - tick_height; -		for (tick_value = mMinBar; tick_value <= mMaxBar; tick_value += mLabelSpacing) +		S32 last_tick = 0; +		S32 last_label = 0; +		const S32 MIN_TICK_SPACING  = mOrientation == HORIZONTAL ? 20 : 30; +		const S32 MIN_LABEL_SPACING = mOrientation == HORIZONTAL ? 40 : 60; +		for (F32 tick_value = mMinBar + mTickSpacing; tick_value <= mCurMaxBar; tick_value += mTickSpacing)  		{ -			left = llfloor((tick_value - mMinBar)*value_scale); -			right = left + tick_width; -			gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f)); +			const S32 begin = llfloor((tick_value - mMinBar)*value_scale); +			const S32 end = begin + tick_width; +			if (begin - last_tick < MIN_TICK_SPACING) +			{ +				continue; +			} +			last_tick = begin;  			tick_label = llformat( value_format.c_str(), tick_value); -			// draw labels for the tick marks -			LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, left - 1, bar_top - bar_height - tick_height, -													 LLColor4(1.f, 1.f, 1.f, 0.5f), -													 LLFontGL::LEFT, LLFontGL::TOP); -		} -		// Now, draw the bars -		top = bar_top; -		bottom = bar_top - bar_height; +			if (mOrientation == HORIZONTAL) +			{ +				if (begin - last_label > MIN_LABEL_SPACING) +				{ +					gl_rect_2d(bar_left, end, bar_right - tick_length, begin, LLColor4(1.f, 1.f, 1.f, 0.25f)); +					LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, bar_right, begin, +						LLColor4(1.f, 1.f, 1.f, 0.5f), +						LLFontGL::LEFT, LLFontGL::VCENTER); +					last_label = begin; +				} +				else +				{ +					gl_rect_2d(bar_left, end, bar_right - tick_length/2, begin, LLColor4(1.f, 1.f, 1.f, 0.1f)); +				} +			} +			else +			{ +				if (begin - last_label > MIN_LABEL_SPACING) +				{ +					gl_rect_2d(begin, bar_top, end, bar_bottom - tick_length, LLColor4(1.f, 1.f, 1.f, 0.25f)); +					LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, begin - 1, bar_bottom - tick_length, +						LLColor4(1.f, 1.f, 1.f, 0.5f), +						LLFontGL::RIGHT, LLFontGL::TOP); +					last_label = begin; +				} +				else +				{ +					gl_rect_2d(begin, bar_top, end, bar_bottom - tick_length/2, LLColor4(1.f, 1.f, 1.f, 0.1f)); +				} +			} +		}  		// draw background bar. -		left = 0; -		right = width; -		gl_rect_2d(left, top, right, bottom, LLColor4(0.f, 0.f, 0.f, 0.25f)); +		gl_rect_2d(bar_left, bar_top, bar_right, bar_bottom, LLColor4(0.f, 0.f, 0.f, 0.25f)); -		if (mStatp->getNumValues() == 0) +		if (frame_recording.getNumPeriods() == 0)  		{  			// No data, don't draw anything...  			return;  		} +  		// draw min and max -		left = (S32) ((min - mMinBar) * value_scale); +		S32 begin = (S32) ((min - mMinBar) * value_scale); -		if (left < 0) +		if (begin < 0)  		{ -			left = 0; +			begin = 0;  			llwarns << "Min:" << min << llendl;  		} -		right = (S32) ((max - mMinBar) * value_scale); -		gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f)); +		S32 end = (S32) ((max - mMinBar) * value_scale); +		if (mOrientation == HORIZONTAL) +		{ +			gl_rect_2d(bar_left, end, bar_right, begin, LLColor4(1.f, 0.f, 0.f, 0.25f)); +		} +		else // VERTICAL +		{ +			gl_rect_2d(begin, bar_top, end, bar_bottom, LLColor4(1.f, 0.f, 0.f, 0.25f)); +		} + +		F32 span = (mOrientation == HORIZONTAL) +					? (bar_right - bar_left) +					: (bar_top - bar_bottom); -		S32 num_values = mStatp->getNumValues() - 1; -		if (mDisplayHistory) +		if (mDisplayHistory && (mCountFloatp || mEventFloatp || mSampleFloatp))  		{ +			const S32 num_values = frame_recording.getNumPeriods() - 1; +			F32 begin = 0; +			F32 end = 0;  			S32 i; -			for (i = 0; i < num_values; i++) +			gGL.color4f( 1.f, 0.f, 0.f, 1.f ); +			gGL.begin( LLRender::QUADS ); +			const S32 max_frame = llmin(mNumFrames, num_values); +			U32 num_samples = 0; +			for (i = 1; i <= max_frame; i++)  			{ -				if (i == mStatp->getNextBin()) +				F32 offset = ((F32)i / (F32)mNumFrames) * span; +				LLTrace::Recording& recording = frame_recording.getPrevRecording(i); +				if (mPerSec)  				{ -					continue; +					if (mCountFloatp) +					{ +						begin       = ((recording.getPerSec(*mCountFloatp)  - mMinBar) * value_scale); +						end         = ((recording.getPerSec(*mCountFloatp)  - mMinBar) * value_scale) + 1; +						num_samples = recording.getSampleCount(*mCountFloatp); +					} +					else if (mEventFloatp) +					{ +						//rate isn't defined for measurement stats, so use mean +						begin       = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale); +						end         = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale) + 1; +						num_samples = recording.getSampleCount(*mEventFloatp); +					} +					else if (mSampleFloatp) +					{ +						//rate isn't defined for sample stats, so use mean +						begin       = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale); +						end         = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale) + 1; +						num_samples = recording.getSampleCount(*mEventFloatp); +					}  				} -				if (mPerSec) +				else +				{ +					if (mCountFloatp) +					{ +						begin       = ((recording.getSum(*mCountFloatp)  - mMinBar) * value_scale); +						end         = ((recording.getSum(*mCountFloatp)  - mMinBar) * value_scale) + 1; +						num_samples = recording.getSampleCount(*mCountFloatp); +					} +					else if (mEventFloatp) +					{ +						begin       = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale); +						end         = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale) + 1; +						num_samples = recording.getSampleCount(*mEventFloatp); +					} +					else if (mSampleFloatp) +					{ +						begin       = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale); +						end         = ((recording.getMean(*mEventFloatp)  - mMinBar) * value_scale) + 1; +						num_samples = recording.getSampleCount(*mEventFloatp); +					} + 				} +				 +				if (!num_samples) continue; + +				if (mOrientation == HORIZONTAL)  				{ -					left = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale); -					right = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale) + 1; -					gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f)); +					gGL.vertex2f((F32)bar_right - offset, end); +					gGL.vertex2f((F32)bar_right - offset, begin); +					gGL.vertex2f((F32)bar_right - offset - 1.f, begin); +					gGL.vertex2f((F32)bar_right - offset - 1.f, end);  				}  				else  				{ -					left = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale); -					right = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale) + 1; -					gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f)); +					gGL.vertex2f(begin, (F32)bar_bottom+offset+1.f); +					gGL.vertex2f(begin, (F32)bar_bottom+offset); +					gGL.vertex2f(end, (F32)bar_bottom+offset); +					gGL.vertex2f(end, (F32)bar_bottom+offset+1.f);  				}  			} +			gGL.end();  		}  		else  		{ +			S32 begin = (S32) ((current - mMinBar) * value_scale) - 1; +			S32 end = (S32) ((current - mMinBar) * value_scale) + 1;  			// draw current -			left = (S32) ((current - mMinBar) * value_scale) - 1; -			right = (S32) ((current - mMinBar) * value_scale) + 1; -			gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 1.f)); +			if (mOrientation == HORIZONTAL) +			{ +				gl_rect_2d(bar_left, end, bar_right, begin, LLColor4(1.f, 0.f, 0.f, 1.f)); +			} +			else +			{ +				gl_rect_2d(begin, bar_top, end, bar_bottom, LLColor4(1.f, 0.f, 0.f, 1.f)); +			}  		}  		// draw mean bar -		top = bar_top + 2; -		bottom = bar_top - bar_height - 2; -		left = (S32) ((mean - mMinBar) * value_scale) - 1; -		right = (S32) ((mean - mMinBar) * value_scale) + 1; -		gl_rect_2d(left, top, right, bottom, LLColor4(0.f, 1.f, 0.f, 1.f)); +		{ +			const S32 begin = (S32) ((mean - mMinBar) * value_scale) - 1; +			const S32 end = (S32) ((mean - mMinBar) * value_scale) + 1; +			if (mOrientation == HORIZONTAL) +			{ +				gl_rect_2d(bar_left - 2, begin, bar_right + 2, end, LLColor4(0.f, 1.f, 0.f, 1.f)); +			} +			else +			{ +				gl_rect_2d(begin, bar_top + 2, end, bar_bottom - 2, LLColor4(0.f, 1.f, 0.f, 1.f)); +			} +		}  	}  	LLView::draw();  } -void LLStatBar::setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing) +void LLStatBar::setStat(const std::string& stat_name)  { -	mMinBar = bar_min; -	mMaxBar = bar_max; -	mTickSpacing = tick_spacing; -	mLabelSpacing = label_spacing; +	mCountFloatp	= LLTrace::TraceType<LLTrace::CountAccumulator>::getInstance(stat_name); +	mEventFloatp	= LLTrace::TraceType<LLTrace::EventAccumulator>::getInstance(stat_name); +	mSampleFloatp	= LLTrace::TraceType<LLTrace::SampleAccumulator>::getInstance(stat_name); +} + + +void LLStatBar::setRange(F32 bar_min, F32 bar_max, F32 tick_spacing) +{ +	mMinBar			= bar_min; +	mMaxBar			= bar_max; +	mTickSpacing	= tick_spacing;  }  LLRect LLStatBar::getRequiredRect() @@ -272,7 +447,7 @@ LLRect LLStatBar::getRequiredRect()  	{  		if (mDisplayHistory)  		{ -			rect.mTop = 35 + mStatp->getNumBins(); +			rect.mTop = mMaxHeight;  		}  		else  		{ @@ -285,3 +460,4 @@ LLRect LLStatBar::getRequiredRect()  	}  	return rect;  } + diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index 513fff3234..3daec297bb 100755 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -29,41 +29,54 @@  #include "llview.h"  #include "llframetimer.h" - -class LLStat; +#include "lltracerecording.h"  class LLStatBar : public LLView  {  public: +  	struct Params : public LLInitParam::Block<Params, LLView::Params>  	{ -		Optional<std::string> label; -		Optional<std::string> unit_label; -		Optional<F32> bar_min; -		Optional<F32> bar_max; -		Optional<F32> tick_spacing; -		Optional<F32> label_spacing; -		Optional<U32> precision; -		Optional<F32> update_rate; -		Optional<bool> show_per_sec; -		Optional<bool> show_bar; -		Optional<bool> show_history; -		Optional<bool> show_mean; -		Optional<std::string> stat; +		Optional<std::string>	label, +								unit_label; + +		Optional<F32>			bar_min, +								bar_max, +								tick_spacing, +								update_rate, +								unit_scale; + +		Optional<U32>			precision; + +		Optional<bool>			show_per_sec, +								show_bar, +								show_history, +								show_mean, +								scale_range; + +		Optional<S32>			num_frames, +								max_height; +		Optional<std::string>	stat; +		Optional<EOrientation>	orientation; +  		Params()  			: label("label"),  			  unit_label("unit_label"),  			  bar_min("bar_min", 0.0f),  			  bar_max("bar_max", 50.0f),  			  tick_spacing("tick_spacing", 10.0f), -			  label_spacing("label_spacing", 10.0f),  			  precision("precision", 0),  			  update_rate("update_rate", 5.0f), -			  show_per_sec("show_per_sec", TRUE), -			  show_bar("show_bar", TRUE), -			  show_history("show_history", FALSE), -			  show_mean("show_mean", TRUE), -			  stat("stat") +			  unit_scale("unit_scale", 1.f), +			  show_per_sec("show_per_sec", true), +			  show_bar("show_bar", true), +			  show_history("show_history", false), +			  show_mean("show_mean", true), +			  scale_range("scale_range", true), +			  num_frames("num_frames", 300), +			  max_height("max_height", 200), +			  stat("stat"), +			  orientation("orientation", VERTICAL)  		{  			changeDefault(follows.flags, FOLLOWS_TOP | FOLLOWS_LEFT);  		} @@ -73,30 +86,39 @@ public:  	virtual void draw();  	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); -	void setStat(LLStat* stat) { mStatp = stat; } -	void setRange(F32 bar_min, F32 bar_max, F32 tick_spacing, F32 label_spacing); +	void setStat(const std::string& stat_name); + +	void setRange(F32 bar_min, F32 bar_max, F32 tick_spacing);  	void getRange(F32& bar_min, F32& bar_max) { bar_min = mMinBar; bar_max = mMaxBar; }  	/*virtual*/ LLRect getRequiredRect();	// Return the height of this object, given the set options.  private: -	F32 mMinBar; -	F32 mMaxBar; -	F32 mTickSpacing; -	F32 mLabelSpacing; -	U32 mPrecision; -	F32 mUpdatesPerSec; -	BOOL mPerSec;				// Use the per sec stats. -	BOOL mDisplayBar;			// Display the bar graph. -	BOOL mDisplayHistory; -	BOOL mDisplayMean;			// If true, display mean, if false, display current value - -	LLStat* mStatp; +	F32          mMinBar; +	F32          mMaxBar; +	F32			 mCurMaxBar; +	F32          mTickSpacing; +	F32          mLabelSpacing; +	U32          mPrecision; +	F32          mUpdatesPerSec; +	F32          mUnitScale; +	S32			 mNumFrames; +	S32			 mMaxHeight; +	bool         mPerSec;				// Use the per sec stats. +	bool         mDisplayBar;			// Display the bar graph. +	bool         mDisplayHistory; +	bool         mDisplayMean;			// If true, display mean, if false, display current value +	bool		 mScaleRange; +	EOrientation mOrientation; + +	LLTrace::TraceType<LLTrace::CountAccumulator>*			mCountFloatp; +	LLTrace::TraceType<LLTrace::EventAccumulator>*			mEventFloatp; +	LLTrace::TraceType<LLTrace::SampleAccumulator>*			mSampleFloatp;  	LLFrameTimer mUpdateTimer; -	LLUIString mLabel; -	std::string mUnitLabel; -	F32 mValue; +	LLUIString   mLabel; +	std::string  mUnitLabel; +	F32          mValue;  };  #endif diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index e44887ebf0..a44bc18733 100755 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -32,48 +32,51 @@  #include "llmath.h"  #include "llui.h" -#include "llstat.h"  #include "llgl.h"  #include "llglheaders.h" +#include "lltracerecording.h" +#include "lltracethreadrecorder.h"  //#include "llviewercontrol.h"  /////////////////////////////////////////////////////////////////////////////////// -LLStatGraph::LLStatGraph(const LLView::Params& p) -:	LLView(p) +LLStatGraph::LLStatGraph(const Params& p) +:	LLView(p), +	mMin(p.min), +	mMax(p.max), +	mPerSec(true), +	mPrecision(p.precision), +	mValue(p.value), +	mNewStatFloatp(p.stat.count_stat_float)  { -	mStatp = NULL;  	setToolTip(p.name()); -	mNumThresholds = 3; -	mThresholdColors[0] = LLColor4(0.f, 1.f, 0.f, 1.f); -	mThresholdColors[1] = LLColor4(1.f, 1.f, 0.f, 1.f); -	mThresholdColors[2] = LLColor4(1.f, 0.f, 0.f, 1.f); -	mThresholdColors[3] = LLColor4(1.f, 0.f, 0.f, 1.f); -	mThresholds[0] = 50.f; -	mThresholds[1] = 75.f; -	mThresholds[2] = 100.f; -	mMin = 0.f; -	mMax = 125.f; -	mPerSec = TRUE; -	mValue = 0.f; -	mPrecision = 0; + +	for(LLInitParam::ParamIterator<ThresholdParams>::const_iterator it = p.thresholds.threshold.begin(), end_it = p.thresholds.threshold.end(); +		it != end_it; +		++it) +	{ +		mThresholds.push_back(Threshold(it->value(), it->color)); +	}  }  void LLStatGraph::draw()  {  	F32 range, frac;  	range = mMax - mMin; -	if (mStatp) +	if (mNewStatFloatp)  	{ +		LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecording(); +  		if (mPerSec)  		{ -			mValue = mStatp->getMeanPerSec(); +			mValue = recording.getPerSec(*mNewStatFloatp);  		}  		else  		{ -			mValue = mStatp->getMean(); +			mValue = recording.getSum(*mNewStatFloatp);  		}  	} +  	frac = (mValue - mMin) / range;  	frac = llmax(0.f, frac);  	frac = llmin(1.f, frac); @@ -91,19 +94,13 @@ void LLStatGraph::draw()  	LLColor4 color; -	S32 i; -	for (i = 0; i < mNumThresholds - 1; i++) +	threshold_vec_t::iterator it = std::lower_bound(mThresholds.begin(), mThresholds.end(), Threshold(mValue / mMax, LLUIColor())); + +	if (it != mThresholds.begin())  	{ -		if (mThresholds[i] > mValue) -		{ -			break; -		} +		it--;  	} -	//gl_drop_shadow(0,  getRect().getHeight(), getRect().getWidth(), 0, -	//				LLUIColorTable::instance().getColor("ColorDropShadow"),  -	//				(S32) gSavedSettings.getF32("DropShadowFloater") ); -  	color = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" );  	gGL.color4fv(color.mV);  	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, TRUE); @@ -111,16 +108,11 @@ void LLStatGraph::draw()  	gGL.color4fv(LLColor4::black.mV);  	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, FALSE); -	color = mThresholdColors[i]; +	color = it->mColor;  	gGL.color4fv(color.mV);  	gl_rect_2d(1, llround(frac*getRect().getHeight()), getRect().getWidth() - 1, 0, TRUE);  } -void LLStatGraph::setValue(const LLSD& value) -{ -	mValue = (F32)value.asReal(); -} -  void LLStatGraph::setMin(const F32 min)  {  	mMin = min; @@ -131,27 +123,3 @@ void LLStatGraph::setMax(const F32 max)  	mMax = max;  } -void LLStatGraph::setStat(LLStat *statp) -{ -	mStatp = statp; -} - -void LLStatGraph::setLabel(const std::string& label) -{ -	mLabel = label; -} - -void LLStatGraph::setUnits(const std::string& units) -{ -	mUnits = units; -} - -void LLStatGraph::setPrecision(const S32 precision) -{ -	mPrecision = precision; -} - -void LLStatGraph::setThreshold(const S32 i, F32 value) -{ -	mThresholds[i] = value; -} diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index 757525e232..38fe12d18b 100755 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -30,29 +30,84 @@  #include "llview.h"  #include "llframetimer.h"  #include "v4color.h" - -class LLStat; +#include "lltrace.h"  class LLStatGraph : public LLView  {  public: -	LLStatGraph(const LLView::Params&); +	struct ThresholdParams : public LLInitParam::Block<ThresholdParams> +	{ +		Mandatory<F32>	value; +		Optional<LLUIColor>	color; -	virtual void draw(); +		ThresholdParams() +		:	value("value"), +			color("color", LLColor4::white) +		{} +	}; + +	struct Thresholds : public LLInitParam::Block<Thresholds> +	{ +		Multiple<ThresholdParams> threshold; + +		Thresholds() +		:	threshold("threshold") +		{} +	}; + +	struct StatParams : public LLInitParam::ChoiceBlock<StatParams> +	{ +		Alternative<LLTrace::TraceType<LLTrace::CountAccumulator>* >	count_stat_float; +		Alternative<LLTrace::TraceType<LLTrace::EventAccumulator>* >	event_stat_float; +		Alternative<LLTrace::TraceType<LLTrace::SampleAccumulator>* >	sample_stat_float; +	}; + +	struct Params : public LLInitParam::Block<Params, LLView::Params> +	{ +		Mandatory<StatParams>	stat; +		Optional<std::string>	label, +								units; +		Optional<S32>			precision; +		Optional<F32>			min, +								max; +		Optional<bool>			per_sec; +		Optional<F32>			value; + +		Optional<Thresholds>	thresholds; + +		Params() +		:	stat("stat"), +			label("label"), +			units("units"), +			precision("precision", 0), +			min("min", 0.f), +			max("max", 125.f), +			per_sec("per_sec", true), +			value("value", 0.f), +			thresholds("thresholds") +		{ +			Thresholds _thresholds; +			_thresholds.threshold.add(ThresholdParams().value(0.f).color(LLColor4::green)) +								.add(ThresholdParams().value(0.33f).color(LLColor4::yellow)) +								.add(ThresholdParams().value(0.5f).color(LLColor4::red)) +								.add(ThresholdParams().value(0.75f).color(LLColor4::red)); +			thresholds = _thresholds; +		} +	}; +	LLStatGraph(const Params&); -	void setLabel(const std::string& label); -	void setUnits(const std::string& units); -	void setPrecision(const S32 precision); -	void setStat(LLStat *statp); -	void setThreshold(const S32 i, F32 value);  	void setMin(const F32 min);  	void setMax(const F32 max); +	virtual void draw(); +  	/*virtual*/ void setValue(const LLSD& value); -	LLStat *mStatp; -	BOOL mPerSec;  private: +	LLTrace::TraceType<LLTrace::CountAccumulator>*	mNewStatFloatp; + +	BOOL mPerSec; +  	F32 mValue;  	F32 mMin; @@ -62,9 +117,25 @@ private:  	std::string mUnits;  	S32 mPrecision; // Num of digits of precision after dot -	S32 mNumThresholds; -	F32 mThresholds[4]; -	LLColor4 mThresholdColors[4]; +	struct Threshold +	{ +		Threshold(F32 value, const LLUIColor& color) +		:	mValue(value), +			mColor(color) +		{} + +		F32 mValue; +		LLUIColor mColor; +		bool operator <(const Threshold& other) +		{ +			return mValue < other.mValue; +		} +	}; +	typedef std::vector<Threshold> threshold_vec_t; +	threshold_vec_t mThresholds; +	//S32 mNumThresholds; +	//F32 mThresholds[4]; +	//LLColor4 mThresholdColors[4];  };  #endif  // LL_LLSTATGRAPH_H diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index fd98155704..415da0b3d6 100755 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -406,7 +406,7 @@ void LLTabContainer::draw()  		}  	} -	setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f))); +	setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLSmoothInterpolation::getInterpolant(0.08f)));  	BOOL has_scroll_arrows = !getTabsHidden() && ((mMaxScrollPos > 0) || (mScrollPosPixels > 0));  	if (!mIsVertical) diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index a45c4ced2e..7243931dbb 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -48,6 +48,8 @@ const F32	CURSOR_FLASH_DELAY = 1.0f;  // in seconds  const S32	CURSOR_THICKNESS = 2;  const F32	TRIPLE_CLICK_INTERVAL = 0.3f;	// delay between double and triple click. +LLTrace::MemStatHandle	LLTextSegment::sMemStat("LLTextSegment"); +  LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num)   :	mDocIndexStart(index_start),   	mDocIndexEnd(index_end), @@ -575,7 +577,7 @@ void LLTextBase::drawText()  		if ( (mSpellCheckStart != start) || (mSpellCheckEnd != end) )  		{  			const LLWString& wstrText = getWText();  -			mMisspellRanges.clear(); +			memDisclaim(mMisspellRanges).clear();  			segment_set_t::const_iterator seg_it = getSegIterContaining(start);  			while (mSegments.end() != seg_it) @@ -651,6 +653,7 @@ void LLTextBase::drawText()  			mSpellCheckStart = start;  			mSpellCheckEnd = end; +			memClaim(mMisspellRanges);  		}  	} @@ -916,9 +919,11 @@ void LLTextBase::createDefaultSegment()  	if (mSegments.empty())  	{  		LLStyleConstSP sp(new LLStyle(getStyleParams())); +		memDisclaim(mSegments);  		LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);  		mSegments.insert(default_segment);  		default_segment->linkToDocument(this); +		memClaim(mSegments);  	}  } @@ -929,6 +934,8 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)  		return;  	} +	memDisclaim(mSegments); +  	segment_set_t::iterator cur_seg_iter = getSegIterContaining(segment_to_insert->getStart());  	S32 reflow_start_index = 0; @@ -1001,6 +1008,7 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)  	// layout potentially changed  	needsReflow(reflow_start_index); +	memClaim(mSegments);  }  BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) @@ -1254,13 +1262,13 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c)  }  //virtual -void LLTextBase::handleVisibilityChange( BOOL new_visibility ) +void LLTextBase::onVisibilityChange( BOOL new_visibility )  {  	if(!new_visibility && mPopupMenu)  	{  		mPopupMenu->hide();  	} -	LLUICtrl::handleVisibilityChange(new_visibility); +	LLUICtrl::onVisibilityChange(new_visibility);  }  //virtual @@ -1311,8 +1319,11 @@ void LLTextBase::replaceWithSuggestion(U32 index)  			removeStringNoUndo(it->first, it->second - it->first);  			// Insert the suggestion in its place +			memDisclaim(mSuggestionList);  			LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);  			insertStringNoUndo(it->first, utf8str_to_wstring(mSuggestionList[index])); +			memClaim(mSuggestionList); +  			setCursorPos(it->first + (S32)suggestion.length());  			break; @@ -1374,7 +1385,7 @@ bool LLTextBase::isMisspelledWord(U32 pos) const  void LLTextBase::onSpellCheckSettingsChange()  {  	// Recheck the spelling on every change -	mMisspellRanges.clear(); +	memDisclaim(mMisspellRanges).clear();  	mSpellCheckStart = mSpellCheckEnd = -1;  } @@ -1652,7 +1663,7 @@ LLRect LLTextBase::getTextBoundingRect()  void LLTextBase::clearSegments()  { -	mSegments.clear(); +	memDisclaim(mSegments).clear();  	createDefaultSegment();  } @@ -3154,7 +3165,9 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip)  		llwarns << "LLTextSegment::setToolTip: cannot replace keyword tooltip." << llendl;  		return;  	} +	memDisclaim(mTooltip);  	mTooltip = tooltip; +	memClaim(mTooltip);  }  bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 20a73387b5..74dc7f9693 100755 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -51,7 +51,10 @@ class LLUrlMatch;  /// includes a start/end offset from the start of the string, a  /// style to render with, an optional tooltip, etc.  /// -class LLTextSegment : public LLRefCount, public LLMouseHandler +class LLTextSegment  +:	public LLRefCount,  +	public LLMouseHandler, +	public LLTrace::MemTrackable<LLTextSegment>  {  public:  	LLTextSegment(S32 start, S32 end) : mStart(start), mEnd(end){}; @@ -92,10 +95,12 @@ public:  	/*virtual*/ void			localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;  	/*virtual*/ BOOL			hasMouseCapture(); -	S32							getStart() const 					{ return mStart; } -	void						setStart(S32 start)					{ mStart = start; } -	S32							getEnd() const						{ return mEnd; } -	void						setEnd( S32 end )					{ mEnd = end; } +	S32						getStart() const 					{ return mStart; } +	void					setStart(S32 start)					{ mStart = start; } +	S32						getEnd() const						{ return mEnd; } +	void					setEnd( S32 end )					{ mEnd = end; } + +	static LLTrace::MemStatHandle sMemStat;  protected:  	S32				mStart; @@ -325,7 +330,7 @@ public:  	/*virtual*/ BOOL		acceptsTextInput() const { return !mReadOnly; }  	/*virtual*/ void		setColor( const LLColor4& c );  	virtual     void 		setReadOnlyColor(const LLColor4 &c); -	virtual	    void		handleVisibilityChange( BOOL new_visibility ); +	virtual	    void		onVisibilityChange( BOOL new_visibility );  	/*virtual*/ void		setValue(const LLSD& value );  	/*virtual*/ LLTextViewModel* getViewModel() const; @@ -603,7 +608,7 @@ protected:  	S32							mSelectionStart;  	S32							mSelectionEnd;  	LLTimer		                mTripleClickTimer; - +	  	BOOL						mIsSelecting;		// Are we in the middle of a drag-select?   	// spell checking diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp index 00d52fe10d..ccb92ffbb2 100755 --- a/indra/llui/lltoggleablemenu.cpp +++ b/indra/llui/lltoggleablemenu.cpp @@ -52,7 +52,7 @@ boost::signals2::connection LLToggleableMenu::setVisibilityChangeCallback(const  }  // virtual -void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn) +void LLToggleableMenu::onVisibilityChange (BOOL curVisibilityIn)  {  	S32 x,y;  	LLUI::getMousePositionLocal(LLUI::getRootView(), &x, &y); diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h index dfe70cbf54..55a6483021 100755 --- a/indra/llui/lltoggleablemenu.h +++ b/indra/llui/lltoggleablemenu.h @@ -45,7 +45,7 @@ public:  	boost::signals2::connection setVisibilityChangeCallback( const commit_signal_t::slot_type& cb ); -	virtual void handleVisibilityChange (BOOL curVisibilityIn); +	virtual void onVisibilityChange (BOOL curVisibilityIn);  	virtual bool addChild (LLView* view, S32 tab_group = 0); diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 3d9f5cbbc2..f683758962 100755 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -42,9 +42,9 @@  namespace LLToolBarEnums  { -	LLLayoutStack::ELayoutOrientation getOrientation(SideType sideType) +	LLView::EOrientation getOrientation(SideType sideType)  	{ -		LLLayoutStack::ELayoutOrientation orientation = LLLayoutStack::HORIZONTAL; +		LLView::EOrientation orientation = LLLayoutStack::HORIZONTAL;  		if ((sideType == SIDE_LEFT) || (sideType == SIDE_RIGHT))  		{ @@ -173,7 +173,7 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p)  	// Initialize the base object  	LLUICtrl::initFromParams(p); -	LLLayoutStack::ELayoutOrientation orientation = getOrientation(p.side); +	LLView::EOrientation orientation = getOrientation(p.side);  	LLLayoutStack::Params centering_stack_p;  	centering_stack_p.name = "centering_stack"; @@ -525,7 +525,7 @@ int LLToolBar::getRankFromPosition(S32 x, S32 y)  	int rank = 0;  	// Convert the toolbar coord into button panel coords -	LLLayoutStack::ELayoutOrientation orientation = getOrientation(mSideType); +	LLView::EOrientation orientation = getOrientation(mSideType);  	S32 button_panel_x = 0;  	S32 button_panel_y = 0;  	localPointToOtherView(x, y, &button_panel_x, &button_panel_y, mButtonPanel); @@ -644,7 +644,7 @@ void LLToolBar::updateLayoutAsNeeded()  {  	if (!mNeedsLayout) return; -	LLLayoutStack::ELayoutOrientation orientation = getOrientation(mSideType); +	LLView::EOrientation orientation = getOrientation(mSideType);  	// our terminology for orientation-agnostic layout is such that  	// length refers to a distance in the direction we stack the buttons  diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h index 31424a36d4..6936cb37f7 100755 --- a/indra/llui/lltoolbar.h +++ b/indra/llui/lltoolbar.h @@ -125,7 +125,7 @@ namespace LLToolBarEnums  		SIDE_TOP,  	}; -	LLLayoutStack::ELayoutOrientation getOrientation(SideType sideType); +	LLView::EOrientation getOrientation(SideType sideType);  }  // NOTE: This needs to occur before Param block declaration for proper compilation. diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 0a0e0e164e..4ebfd0fd6e 100755 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -29,9 +29,11 @@  #define LL_LLUI_H  #include "llrect.h" +#include "llcoord.h"  #include "llcontrol.h"  #include "llcoord.h" -#include "v2math.h" +#include "llcontrol.h" +#include "llglslshader.h"  #include "llinitparam.h"  #include "llregistry.h"  #include "llrender2dutils.h" @@ -40,8 +42,8 @@  #include "lluicolortable.h"  #include "lluiimage.h"  #include <boost/signals2.hpp> -#include "lllazyvalue.h"  #include "llframetimer.h" +#include "v2math.h"  #include <limits>  // for initparam specialization diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index b9c843e931..08358484ef 100755 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -118,6 +118,7 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)  	mDoubleClickSignal(NULL),  	mTransparencyType(TT_DEFAULT)  { +	memClaim(viewmodel.get());  }  void LLUICtrl::initFromParams(const Params& p) @@ -940,7 +941,7 @@ boost::signals2::connection LLUICtrl::setCommitCallback( boost::function<void (L  }  boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function<bool (const LLSD& data)> cb )  { -	if (!mValidateSignal) mValidateSignal = new enable_signal_t(); +	if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t());  	return mValidateSignal->connect(boost::bind(cb, _2));  } @@ -1003,55 +1004,55 @@ boost::signals2::connection LLUICtrl::setValidateCallback(const EnableCallbackPa  boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb )   {  -	if (!mCommitSignal) mCommitSignal = new commit_signal_t(); +	if (!mCommitSignal) mCommitSignal = memClaim(new commit_signal_t());  	return mCommitSignal->connect(cb);   }  boost::signals2::connection LLUICtrl::setValidateCallback( const enable_signal_t::slot_type& cb )   {  -	if (!mValidateSignal) mValidateSignal = new enable_signal_t(); +	if (!mValidateSignal) mValidateSignal = memClaim(new enable_signal_t());  	return mValidateSignal->connect(cb);   }  boost::signals2::connection LLUICtrl::setMouseEnterCallback( const commit_signal_t::slot_type& cb )   {  -	if (!mMouseEnterSignal) mMouseEnterSignal = new commit_signal_t(); +	if (!mMouseEnterSignal) mMouseEnterSignal = memClaim(new commit_signal_t());  	return mMouseEnterSignal->connect(cb);   }  boost::signals2::connection LLUICtrl::setMouseLeaveCallback( const commit_signal_t::slot_type& cb )   {  -	if (!mMouseLeaveSignal) mMouseLeaveSignal = new commit_signal_t(); +	if (!mMouseLeaveSignal) mMouseLeaveSignal = memClaim(new commit_signal_t());  	return mMouseLeaveSignal->connect(cb);   }  boost::signals2::connection LLUICtrl::setMouseDownCallback( const mouse_signal_t::slot_type& cb )   {  -	if (!mMouseDownSignal) mMouseDownSignal = new mouse_signal_t(); +	if (!mMouseDownSignal) mMouseDownSignal = memClaim(new mouse_signal_t());  	return mMouseDownSignal->connect(cb);   }  boost::signals2::connection LLUICtrl::setMouseUpCallback( const mouse_signal_t::slot_type& cb )   {  -	if (!mMouseUpSignal) mMouseUpSignal = new mouse_signal_t(); +	if (!mMouseUpSignal) mMouseUpSignal = memClaim(new mouse_signal_t());  	return mMouseUpSignal->connect(cb);   }  boost::signals2::connection LLUICtrl::setRightMouseDownCallback( const mouse_signal_t::slot_type& cb )   {  -	if (!mRightMouseDownSignal) mRightMouseDownSignal = new mouse_signal_t(); +	if (!mRightMouseDownSignal) mRightMouseDownSignal = memClaim(new mouse_signal_t());  	return mRightMouseDownSignal->connect(cb);   }  boost::signals2::connection LLUICtrl::setRightMouseUpCallback( const mouse_signal_t::slot_type& cb )   {  -	if (!mRightMouseUpSignal) mRightMouseUpSignal = new mouse_signal_t(); +	if (!mRightMouseUpSignal) mRightMouseUpSignal = memClaim(new mouse_signal_t());  	return mRightMouseUpSignal->connect(cb);   }  boost::signals2::connection LLUICtrl::setDoubleClickCallback( const mouse_signal_t::slot_type& cb )   {  -	if (!mDoubleClickSignal) mDoubleClickSignal = new mouse_signal_t(); +	if (!mDoubleClickSignal) mDoubleClickSignal = memClaim(new mouse_signal_t());  	return mDoubleClickSignal->connect(cb);   } diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 876bb5ef46..f2fe4334ee 100755 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -170,7 +170,7 @@ public:  			LLXMLNodePtr root_node;  			if (!LLUICtrlFactory::getLayeredXMLNode(filename, root_node)) -			{ +				{							  				llwarns << "Couldn't parse XUI file: " << instance().getCurFileName() << llendl;  				goto fail;  			} @@ -259,10 +259,8 @@ private:  			// We always want to output top-left coordinates  			typename T::Params output_params(params);  			T::setupParamsForExport(output_params, parent); -			// Export only the differences between this any default params -			typename T::Params default_params(getDefaultParams<T>());  			copyName(node, output_node); -			parser.writeXUI(output_node, output_params, &default_params); +			parser.writeXUI(output_node, output_params, LLInitParam::default_parse_rules(), &getDefaultParams<T>());  		}  		// Apply layout transformations, usually munging rect diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp index c4e073ccdb..23fc53ea88 100755 --- a/indra/llui/lluistring.cpp +++ b/indra/llui/lluistring.cpp @@ -26,6 +26,8 @@  #include "linden_common.h"  #include "lluistring.h" + +#include "llfasttimer.h"  #include "llsd.h"  #include "lltrans.h" diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 3613a40e2c..daeb4d7939 100755 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -30,7 +30,6 @@  #define LLVIEW_CPP  #include "llview.h" -#include <cassert>  #include <sstream>  #include <boost/tokenizer.hpp>  #include <boost/foreach.hpp> @@ -70,6 +69,7 @@ LLView* LLView::sPreviewClickedElement = NULL;  BOOL	LLView::sDrawPreviewHighlights = FALSE;  S32		LLView::sLastLeftXML = S32_MIN;  S32		LLView::sLastBottomXML = S32_MIN; +LLTrace::MemStatHandle	LLView::sMemStat("LLView");  std::vector<LLViewDrawContext*> LLViewDrawContext::sDrawContextStack;  LLView::DrilldownFunc LLView::sDrilldown = @@ -85,6 +85,16 @@ template class LLView* LLView::getChild<class LLView>(  static LLDefaultChildRegistry::Register<LLView> r("view"); +namespace LLInitParam +{ +	void TypeValues<LLView::EOrientation>::declareValues() +	{ +		declare("horizontal", LLView::HORIZONTAL); +		declare("vertical", LLView::VERTICAL);	 +	} +} + +  LLView::Follows::Follows()  :   string(""),  	flags("flags", FOLLOWS_LEFT | FOLLOWS_TOP) @@ -633,21 +643,21 @@ void LLView::setVisible(BOOL visible)  		{  			// tell all children of this view that the visibility may have changed  			dirtyRect(); -			handleVisibilityChange( visible ); +			onVisibilityChange( visible );  		}  		updateBoundingRect();  	}  }  // virtual -void LLView::handleVisibilityChange ( BOOL new_visibility ) +void LLView::onVisibilityChange ( BOOL new_visibility )  {  	BOOST_FOREACH(LLView* viewp, mChildList)  	{  		// only views that are themselves visible will have their overall visibility affected by their ancestors  		if (viewp->getVisible())  		{ -			viewp->handleVisibilityChange ( new_visibility ); +			viewp->onVisibilityChange ( new_visibility );  		}  	}  } diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 15b85a6418..0568fa889a 100755 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -100,9 +100,13 @@ class LLView  :	public LLMouseHandler,			// handles mouse events  	public LLFocusableElement,		// handles keyboard events  	public LLMortician,				// lazy deletion -	public LLHandleProvider<LLView>	// passes out weak references to self +	public LLHandleProvider<LLView>,     // passes out weak references to self +	public LLTrace::MemTrackable<LLView> // track memory usage  {  public: + +	enum EOrientation { HORIZONTAL, VERTICAL, ORIENTATION_COUNT }; +  	struct Follows : public LLInitParam::ChoiceBlock<Follows>  	{  		Alternative<std::string>	string; @@ -303,7 +307,7 @@ public:  	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text ); -	virtual void	handleVisibilityChange ( BOOL new_visibility ); +	virtual void	onVisibilityChange ( BOOL new_visibility );  	void			pushVisible(BOOL visible)	{ mLastVisible = mVisible; setVisible(visible); }  	void			popVisible()				{ setVisible(mLastVisible); } @@ -671,7 +675,18 @@ public:  	static S32 sLastLeftXML;  	static S32 sLastBottomXML;  	static BOOL sForceReshape; +	static LLTrace::MemStatHandle sMemStat; +}; + +namespace LLInitParam +{ +template<> +struct TypeValues<LLView::EOrientation> : public LLInitParam::TypeValuesHelper<LLView::EOrientation> +{ +	static void declareValues();  }; +} +  class LLCompareByTabOrder  { diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp index a9f8acc440..901260bec8 100755 --- a/indra/llui/llviewmodel.cpp +++ b/indra/llui/llviewmodel.cpp @@ -35,6 +35,8 @@  // external library headers  // other Linden headers +LLTrace::MemStatHandle	LLViewModel::sMemStat("LLViewModel"); +  ///  LLViewModel::LLViewModel()   : mDirty(false) @@ -80,7 +82,10 @@ LLTextViewModel::LLTextViewModel(const LLSD& value)  void LLTextViewModel::setValue(const LLSD& value)  {  	LLViewModel::setValue(value); +	memDisclaim(mDisplay);      mDisplay = utf8str_to_wstring(value.asString()); +	memClaim(mDisplay); +      // mDisplay and mValue agree      mUpdateFromDisplay = false;  } @@ -91,7 +96,9 @@ void LLTextViewModel::setDisplay(const LLWString& value)      // and do the utf8str_to_wstring() to get the corresponding mDisplay      // value. But a text editor might want to edit the display string      // directly, then convert back to UTF8 on commit. +	memDisclaim(mDisplay);      mDisplay = value; +	memClaim(mDisplay);      mDirty = true;      // Don't immediately convert to UTF8 -- do it lazily -- we expect many      // more setDisplay() calls than getValue() calls. Just flag that it needs diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h index ef2e314799..2c016d2560 100755 --- a/indra/llui/llviewmodel.h +++ b/indra/llui/llviewmodel.h @@ -39,6 +39,7 @@  #include "llrefcount.h"  #include "stdenums.h"  #include "llstring.h" +#include "lltrace.h"  #include <string>  class LLScrollListItem; @@ -60,7 +61,9 @@ typedef LLPointer<LLListViewModel> LLListViewModelPtr;   * LLViewModel data. This way, the LLViewModel is quietly deleted when the   * last referencing widget is destroyed.   */ -class LLViewModel: public LLRefCount +class LLViewModel  +:	public LLRefCount, +	public LLTrace::MemTrackable<LLViewModel>  {  public:      LLViewModel(); @@ -80,6 +83,8 @@ public:  	//       void setDirty() { mDirty = true; } +	static LLTrace::MemStatHandle sMemStat; +  protected:      LLSD mValue;      bool mDirty; diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index 3ad5ad7d42..dc273ec990 100755 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -29,7 +29,7 @@  #include "llxuiparser.h"  #include "llxmlnode.h" - +#include "llfasttimer.h"  #ifdef LL_STANDALONE  #include <expat.h>  #else @@ -334,6 +334,8 @@ LLXSDWriter::LLXSDWriter()  	registerInspectFunc<LLSD>(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4));  } +LLXSDWriter::~LLXSDWriter() {} +  void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)  {  	Schema schema(xml_namespace); @@ -858,11 +860,11 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo  	return any_parsed;  } -void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block) +void LLXUIParser::writeXUIImpl(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::predicate_rule_t rules, const LLInitParam::BaseBlock* diff_block)  {  	mWriteRootNode = node;  	name_stack_t name_stack = Parser::name_stack_t(); -	block.serializeBlock(*this, name_stack, diff_block); +	block.serializeBlock(*this, name_stack, rules, diff_block);  	mOutNodes.clear();  } diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h index e48663e5cc..ad2a39cab7 100755 --- a/indra/llui/llxuiparser.h +++ b/indra/llui/llxuiparser.h @@ -29,21 +29,15 @@  #include "llinitparam.h"  #include "llregistry.h" -#include "llpointer.h" +#include "llxmlnode.h"  #include <boost/function.hpp>  #include <iosfwd>  #include <stack>  #include <set> - -  class LLView; - -typedef LLPointer<class LLXMLNode> LLXMLNodePtr; - -  // lookup widget type by name  class LLWidgetTypeRegistry  :	public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry> @@ -59,8 +53,6 @@ class LLChildRegistryRegistry  : public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry>  {}; - -  class LLXSDWriter : public LLInitParam::Parser  {  	LOG_CLASS(LLXSDWriter); @@ -70,6 +62,7 @@ public:  	/*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; }  	LLXSDWriter(); +	~LLXSDWriter();  protected:  	void writeAttribute(const std::string& type, const Parser::name_stack_t&, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values); @@ -109,9 +102,26 @@ public:  	/*virtual*/ void parserError(const std::string& message);  	void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename = LLStringUtil::null, bool silent=false); -	void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL); +	template<typename BLOCK> +	void writeXUI(LLXMLNodePtr node,  +				const BLOCK& block,  +				const LLInitParam::predicate_rule_t rules = LLInitParam::default_parse_rules(), +				const LLInitParam::BaseBlock* diff_block = NULL) +	{ +		if (!diff_block  +			&& !rules.isAmbivalent(LLInitParam::HAS_DEFAULT_VALUE)) +		{ +			diff_block = &LLInitParam::defaultValue<BLOCK>(); +		} +		writeXUIImpl(node, block, rules, diff_block); +	}  private: +	LLXUIParser(const LLXUIParser& other); // no-copy +	void writeXUIImpl(LLXMLNodePtr node,  +		const LLInitParam::BaseBlock& block,  +		const LLInitParam::predicate_rule_t rules,  +		const LLInitParam::BaseBlock* diff_block);  	bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block);  	bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block); diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp index 0424f2379e..3b83d1b9e3 100755 --- a/indra/llvfs/llpidlock.cpp +++ b/indra/llvfs/llpidlock.cpp @@ -36,7 +36,7 @@  #if LL_WINDOWS   //For windows platform. -#include <windows.h> +#include "llwin32headerslean.h"  namespace {  	inline DWORD getpid() { diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index 03d2cc25e3..ed74488af4 100755 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -30,9 +30,10 @@  #include "llerror.h"  #include "llthread.h" -#include "llstat.h" -#include "llvfs.h" +#include "lltimer.h" +#include "llfasttimer.h"  #include "llmemory.h" +#include "llvfs.h"  const S32 LLVFile::READ			= 0x00000001;  const S32 LLVFile::WRITE		= 0x00000002; @@ -135,7 +136,7 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S  		data = NULL;  	}  	else -	{		 +	{  		data = (U8*) ll_aligned_malloc_16(file_size);  		file.read(data, file_size);	/* Flawfinder: ignore */  diff --git a/indra/llwindow/lldragdropwin32.h b/indra/llwindow/lldragdropwin32.h index 929e7f9e37..ba7fac0bd1 100755 --- a/indra/llwindow/lldragdropwin32.h +++ b/indra/llwindow/lldragdropwin32.h @@ -31,7 +31,7 @@  #ifndef LL_LLDRAGDROP32_H  #define LL_LLDRAGDROP32_H -#include <windows.h> +#include "llwin32headerslean.h"  #include <ole2.h>  class LLDragDropWin32 @@ -54,7 +54,7 @@ class LLDragDropWin32  #ifndef LL_LLDRAGDROP32_H  #define LL_LLDRAGDROP32_H -#include <windows.h> +#include "llwin32headerslean.h"  #include <ole2.h>  // imposter class that does nothing  diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index c155c1b362..276074d4ca 100755 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -28,6 +28,7 @@  #define LL_LLKEYBOARD_H  #include <map> +#include <boost/function.hpp>  #include "string_table.h"  #include "lltimer.h" diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index be3fe5deb0..b76d526c5a 100755 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -28,10 +28,7 @@  #include "linden_common.h" -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> - +#include "llwin32headerslean.h"  #include "llkeyboardwin32.h"  #include "llwindowcallbacks.h" diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index e9147d552e..c235d77656 100755 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -31,6 +31,7 @@  #include "llcoord.h"  #include "llstring.h"  #include "llcursortypes.h" +#include "llinstancetracker.h"  #include "llsd.h"  class LLSplashScreen; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 43c0090993..6d887926fa 100755 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -38,6 +38,7 @@  // Linden library includes  #include "llerror.h" +#include "llfasttimer.h"  #include "llgl.h"  #include "llstring.h"  #include "lldir.h" diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 54c9ac4d4d..169d264808 100755 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -28,9 +28,7 @@  #define LL_LLWINDOWWIN32_H  // Limit Windows API to small and manageable set. -#define WIN32_LEAN_AND_MEAN -#include <winsock2.h> -#include <windows.h> +#include "llwin32headerslean.h"  #include "llwindow.h"  #include "llwindowcallbacks.h" diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp index b12d2e4a16..e9b4d1fcbb 100755 --- a/indra/lscript/lscript_execute/lscript_execute.cpp +++ b/indra/lscript/lscript_execute/lscript_execute.cpp @@ -35,7 +35,6 @@  #include "lscript_library.h"  #include "lscript_heapruntime.h"  #include "lscript_alloc.h" -#include "llstat.h"  // Static diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index 24328202cb..eb18a3776f 100755 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -28,18 +28,10 @@  #include "linden_common.h" -#include "llgl.h" - -#include "llplugininstance.h" -#include "llpluginmessage.h" -#include "llpluginmessageclasses.h" -#include "media_plugin_base.h" - -#if LL_QUICKTIME_ENABLED -  #if defined(LL_DARWIN)  	#include <QuickTime/QuickTime.h>  #elif defined(LL_WINDOWS) +	#include "llwin32headers.h"  	#include "MacTypes.h"  	#include "QTML.h"  	#include "Movies.h" @@ -48,6 +40,17 @@  	#include "QTLoadLibraryUtils.h"  #endif +#include "llgl.h" + +#include "llplugininstance.h" +#include "llpluginmessage.h" +#include "llpluginmessageclasses.h" +#include "media_plugin_base.h" + +#if LL_QUICKTIME_ENABLED + + +  // TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint  ////////////////////////////////////////////////////////////////////////////////  // diff --git a/indra/media_plugins/webkit/mac_volume_catcher.cpp b/indra/media_plugins/webkit/mac_volume_catcher.cpp index 8a06bb8487..c20bcd374d 100755 --- a/indra/media_plugins/webkit/mac_volume_catcher.cpp +++ b/indra/media_plugins/webkit/mac_volume_catcher.cpp @@ -38,6 +38,7 @@  #include <Carbon/Carbon.h>  #include <QuickTime/QuickTime.h>  #include <AudioUnit/AudioUnit.h> +#include <list>  struct VolumeCatcherStorage; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 227644f14f..639982a305 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -237,7 +237,6 @@ set(viewer_SOURCE_FILES      llfloaterinspect.cpp      llfloaterinventory.cpp      llfloaterjoystick.cpp -    llfloaterlagmeter.cpp      llfloaterland.cpp      llfloaterlandholdings.cpp      llfloatermap.cpp @@ -262,6 +261,7 @@ set(viewer_SOURCE_FILES      llfloaterregiondebugconsole.cpp      llfloaterregioninfo.cpp      llfloaterreporter.cpp +    llfloatersceneloadstats.cpp      llfloaterscriptdebug.cpp      llfloaterscriptlimits.cpp      llfloatersearch.cpp @@ -484,6 +484,7 @@ set(viewer_SOURCE_FILES      llremoteparcelrequest.cpp      llsavedsettingsglue.cpp      llsaveoutfitcombobtn.cpp +    llscenemonitor.cpp      llsceneview.cpp      llscreenchannel.cpp      llscriptfloater.cpp @@ -605,6 +606,7 @@ set(viewer_SOURCE_FILES      llviewernetwork.cpp      llviewerobject.cpp      llviewerobjectlist.cpp +    llvieweroctree.cpp      llviewerparcelmedia.cpp      llviewerparcelmediaautoplay.cpp      llviewerparcelmgr.cpp @@ -818,7 +820,6 @@ set(viewer_HEADER_FILES      llfloaterinspect.h      llfloaterinventory.h      llfloaterjoystick.h -    llfloaterlagmeter.h      llfloaterland.h      llfloaterlandholdings.h      llfloatermap.h @@ -843,6 +844,7 @@ set(viewer_HEADER_FILES      llfloaterregiondebugconsole.h      llfloaterregioninfo.h      llfloaterreporter.h +    llfloatersceneloadstats.h      llfloaterscriptdebug.h      llfloaterscriptlimits.h      llfloatersearch.h @@ -1055,6 +1057,7 @@ set(viewer_HEADER_FILES      llrootview.h      llsavedsettingsglue.h      llsaveoutfitcombobtn.h +    llscenemonitor.h      llsceneview.h      llscreenchannel.h      llscriptfloater.h @@ -1176,6 +1179,7 @@ set(viewer_HEADER_FILES      llviewernetwork.h      llviewerobject.h      llviewerobjectlist.h +    llvieweroctree.h      llviewerparcelmedia.h      llviewerparcelmediaautoplay.h      llviewerparcelmgr.h @@ -1563,7 +1567,7 @@ endif (WINDOWS)  if (OPENAL)    set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL") -endif (OPENAL)           +endif (OPENAL)  if (FMODEX)    set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f356cff9d8..4d5b0c62e4 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -41,7 +41,7 @@              <string>                  Time before automatically setting AFK (away from keyboard) mode (seconds, 0=never).                  Valid values are: 0, 120, 300, 600, 1800 -</string> +    </string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -6642,6 +6642,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>ObjectCacheViewCullingEnabled</key> +    <map> +      <key>Comment</key> +      <string>Enable the object cache view culling. Needs to restart viewer.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>OpenDebugStatAdvanced</key>      <map>        <key>Comment</key> @@ -7134,6 +7145,17 @@        <key>Value</key>        <real>6.0</real>      </map> +    <key>ClothingLoadingDelay</key> +    <map> +      <key>Comment</key> +      <string>Time to wait for avatar appearance to resolve before showing world (seconds)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>10.0</real> +    </map>  	<key>PreferredMaturity</key>      <map>        <key>Comment</key> @@ -7689,7 +7711,6 @@        <key>Value</key>        <integer>1</integer>      </map> -    <key>OctreeMaxNodeCapacity</key>    <map>      <key>Comment</key> @@ -9766,6 +9787,39 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>SceneLoadingMonitorEnabled</key> +    <map> +      <key>Comment</key> +      <string>Enabled scene loading monitor if set</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>SceneLoadingMonitorSampleTime</key> +    <map> +      <key>Comment</key> +      <string>Time between screen samples when monitor scene load (seconds)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>0.25</real> +    </map> +    <key>SceneLoadingPixelDiffThreshold</key> +    <map> +      <key>Comment</key> +      <string>Amount of pixels changed required to consider the scene as still loading (fraction of pixels on screen)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>0.0003</real> +    </map>      <key>ScriptHelpFollowsCursor</key>      <map>        <key>Comment</key> @@ -12714,6 +12768,17 @@        <key>Value</key>        <integer>1</integer>      </map> +  <key>UseObjectCacheOcclusion</key> +  <map> +    <key>Comment</key> +    <string>Enable object cache level object culling based on occlusion (coverage) by other objects</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>    <key>RenderSynchronousOcclusion</key>    <map>      <key>Comment</key> @@ -14480,6 +14545,28 @@      <key>Value</key>      <integer>0</integer>    </map> +  <key>TeleportArrivalDelay</key> +  <map> +    <key>Comment</key> +    <string>Time to wait before displaying world during teleport (seconds)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>2</real> +  </map> +  <key>TeleportLocalDelay</key> +  <map> +    <key>Comment</key> +    <string>Delay to prevent teleports after starting an in-sim teleport. (seconds)</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>1</real> +  </map>    <key>DisablePrecacheDelayAfterTeleporting</key>    <map>      <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl new file mode 100644 index 0000000000..f1400c9b44 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl @@ -0,0 +1,49 @@ +/**  + * @file onetexturefilterF.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$ + */ + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2D tex0; +uniform float tolerance; + +VARYING vec2 vary_texcoord0; + +void main()  +{ +	frag_color = texture2D(tex0, vary_texcoord0.xy); +	 +	if(frag_color[0] + frag_color[1] + frag_color[2] < tolerance) +	{ +		discard; +	} +	else +	{		 +		frag_color[3] = 0.95f;	 +	}	 +} diff --git a/indra/llcommon/reflective.cpp b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl index 2cc0e7e1f2..a33ef7e92c 100755..100644 --- a/indra/llcommon/reflective.cpp +++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl @@ -1,12 +1,9 @@  /**  - * @file reflective.cpp - * @author Babbage - * @date 2006-05-15 - * @brief Implementation of LLReflective. + * @file onetexturefilterV.glsl   * - * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * 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 @@ -25,16 +22,17 @@   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ - -#include "linden_common.h"  -#include "reflective.h" +uniform mat4 modelview_projection_matrix; -LLReflective::LLReflective() -{ -} +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; -//virtual  -LLReflective::~LLReflective() +VARYING vec2 vary_texcoord0; + +void main()  { +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +	vary_texcoord0 = texcoord0;  } + diff --git a/indra/llcommon/metaproperty.cpp b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl index 98d850bf1e..6eeb2596b2 100755..100644 --- a/indra/llcommon/metaproperty.cpp +++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl @@ -1,12 +1,9 @@  /**  - * @file metaproperty.cpp - * @author Babbage - * @date 2006-05-15 - * @brief Implementation of LLMetaProperty. + * @file twotexturecompareF.glsl   * - * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * 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 @@ -26,31 +23,36 @@   * $/LicenseInfo$   */ -#include "linden_common.h"  +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif -#include "metaproperty.h" +uniform sampler2D tex0; +uniform sampler2D tex1; +uniform sampler2D dither_tex; +uniform float dither_scale; +uniform float dither_scale_s; +uniform float dither_scale_t; -#include "metaclass.h" +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; -LLMetaProperty::LLMetaProperty(const std::string& name, const LLMetaClass& object_class) :  -	mName(name), mObjectClass(object_class)  +void main()   { -} +	frag_color = abs(texture2D(tex0, vary_texcoord0.xy) - texture2D(tex1, vary_texcoord0.xy)); -//virtual  -LLMetaProperty::~LLMetaProperty() -{ -} +	vec2 dither_coord; +	dither_coord[0] = vary_texcoord0[0] * dither_scale_s; +	dither_coord[1] = vary_texcoord0[1] * dither_scale_t; +	vec4 dither_vec = texture(dither_tex, dither_coord.xy); -const LLMetaClass& LLMetaProperty::getObjectMetaClass() const -{ -	return mObjectClass; -} - -void LLMetaProperty::checkObjectClass(const LLReflective* object) const -{ -	if(! mObjectClass.isInstance(object)) +	for(int i = 0; i < 3; i++)  	{ -		throw "class cast exception"; +		if(frag_color[i] < dither_vec[i] * dither_scale) +		{ +			frag_color[i] = 0.f; +		}  	}  } diff --git a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl new file mode 100644 index 0000000000..67c6674f0c --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl @@ -0,0 +1,41 @@ +/**  + * @file twotexturecompareV.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$ + */ +  +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; +ATTRIBUTE vec2 texcoord0; +ATTRIBUTE vec2 texcoord1; + +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; + +void main() +{ +	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); +	vary_texcoord0 = texcoord0; +	vary_texcoord1 = texcoord1; +} + diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 8c42defa73..8ec74bb268 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -754,7 +754,7 @@ void LLAgent::setFlying(BOOL fly)  		}  		if( !was_flying )  		{ -			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT); +			add(LLStatViewer::FLY, 1);  		}  		setControlFlags(AGENT_CONTROL_FLY);  	} @@ -2830,10 +2830,10 @@ BOOL LLAgent::isInGroup(const LLUUID& group_id, BOOL ignore_god_mode /* FALSE */  	if (!ignore_god_mode && isGodlike())  		return true; -	S32 count = mGroups.count(); -	for(S32 i = 0; i < count; ++i) +	U32 count = mGroups.size(); +	for(U32 i = 0; i < count; ++i)  	{ -		if(mGroups.get(i).mID == group_id) +		if(mGroups[i].mID == group_id)  		{  			return TRUE;  		} @@ -2850,12 +2850,12 @@ BOOL LLAgent::hasPowerInGroup(const LLUUID& group_id, U64 power) const  	// GP_NO_POWERS can also mean no power is enough to grant an ability.  	if (GP_NO_POWERS == power) return FALSE; -	S32 count = mGroups.count(); -	for(S32 i = 0; i < count; ++i) +	U32 count = mGroups.size(); +	for(U32 i = 0; i < count; ++i)  	{ -		if(mGroups.get(i).mID == group_id) +		if(mGroups[i].mID == group_id)  		{ -			return (BOOL)((mGroups.get(i).mPowers & power) > 0); +			return (BOOL)((mGroups[i].mPowers & power) > 0);  		}  	}  	return FALSE; @@ -2871,12 +2871,12 @@ U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const  	if (isGodlike())  		return GP_ALL_POWERS; -	S32 count = mGroups.count(); -	for(S32 i = 0; i < count; ++i) +	U32 count = mGroups.size(); +	for(U32 i = 0; i < count; ++i)  	{ -		if(mGroups.get(i).mID == group_id) +		if(mGroups[i].mID == group_id)  		{ -			return (mGroups.get(i).mPowers); +			return (mGroups[i].mPowers);  		}  	} @@ -2885,12 +2885,12 @@ U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const  BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const  { -	S32 count = mGroups.count(); +	S32 count = mGroups.size();  	for(S32 i = 0; i < count; ++i)  	{ -		if(mGroups.get(i).mID == group_id) +		if(mGroups[i].mID == group_id)  		{ -			data = mGroups.get(i); +			data = mGroups[i];  			return TRUE;  		}  	} @@ -2899,12 +2899,12 @@ BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const  S32 LLAgent::getGroupContribution(const LLUUID& group_id) const  { -	S32 count = mGroups.count(); +	S32 count = mGroups.size();  	for(S32 i = 0; i < count; ++i)  	{ -		if(mGroups.get(i).mID == group_id) +		if(mGroups[i].mID == group_id)  		{ -			S32 contribution = mGroups.get(i).mContribution; +			S32 contribution = mGroups[i].mContribution;  			return contribution;  		}  	} @@ -2913,12 +2913,12 @@ S32 LLAgent::getGroupContribution(const LLUUID& group_id) const  BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution)  { -	S32 count = mGroups.count(); +	S32 count = mGroups.size();  	for(S32 i = 0; i < count; ++i)  	{ -		if(mGroups.get(i).mID == group_id) +		if(mGroups[i].mID == group_id)  		{ -			mGroups.get(i).mContribution = contribution; +			mGroups[i].mContribution = contribution;  			LLMessageSystem* msg = gMessageSystem;  			msg->newMessage("SetGroupContribution");  			msg->nextBlock("AgentData"); @@ -2936,13 +2936,13 @@ BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution)  BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile)  { -	S32 count = mGroups.count(); +	S32 count = mGroups.size();  	for(S32 i = 0; i < count; ++i)  	{ -		if(mGroups.get(i).mID == group_id) +		if(mGroups[i].mID == group_id)  		{ -			mGroups.get(i).mAcceptNotices = accept_notices; -			mGroups.get(i).mListInProfile = list_in_profile; +			mGroups[i].mAcceptNotices = accept_notices; +			mGroups[i].mListInProfile = list_in_profile;  			LLMessageSystem* msg = gMessageSystem;  			msg->newMessage("SetGroupAcceptNotices");  			msg->nextBlock("AgentData"); @@ -2962,7 +2962,7 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO  BOOL LLAgent::canJoinGroups() const  { -	return mGroups.count() < gMaxAgentGroups; +	return (S32)mGroups.size() < gMaxAgentGroups;  }  LLQuaternion LLAgent::getHeadRotation() @@ -3792,7 +3792,7 @@ bool LLAgent::teleportCore(bool is_local)  	gAgentCamera.resetView(FALSE);  	// local logic -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT); +	add(LLStatViewer::TELEPORT, 1);  	if (is_local)  	{  		gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL ); @@ -4109,7 +4109,7 @@ void LLAgent::setTeleportState(ETeleportState state)  		case TELEPORT_ARRIVING:  		// First two position updates after a teleport tend to be weird -		LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2; +		//LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;  		// Let the interested parties know we've teleported.  		LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal()); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index f5f26f69d8..4153fbbfff 100755 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -35,6 +35,7 @@  #include "llcoordframe.h"			// for mFrameAgent  #include "llavatarappearancedefines.h"  #include "llpermissionsflags.h" +#include "lldarray.h"  #include <boost/function.hpp>  #include <boost/shared_ptr.hpp> @@ -251,6 +252,7 @@ public:  	const LLVector3d &getLastPositionGlobal() const { return mLastPositionGlobal; }  	void			setLastPositionGlobal(const LLVector3d &pos) { mLastPositionGlobal = pos; } +  private:  	std::set<U64>	mRegionsVisited;		// Stat - what distinct regions has the avatar been to?  	F64				mDistanceTraveled;		// Stat - how far has the avatar moved? diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 0896aa5972..d02817df7b 100755 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -337,7 +337,7 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)  			LLVector3 agent_at_axis = gAgent.getAtAxis();  			agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector());  			agent_at_axis.normalize(); -			gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(0.3f))); +			gAgent.resetAxes(lerp(gAgent.getAtAxis(), agent_at_axis, LLSmoothInterpolation::getInterpolant(0.3f)));  		}  		setFocusOnAvatar(TRUE, ANIMATE); @@ -1070,8 +1070,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)  	LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation();  	LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation(); -	if 	((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) && -		 (root_at * last_at_axis > 0.95f)) +	if 	(LLTrace::get_frame_recording().getLastRecording().getLastValue(*gViewerWindow->getMouseVelocityStat()) < 0.01f +		&& (root_at * last_at_axis > 0.95f))  	{  		LLVector3 vel = gAgentAvatarp->getVelocity();  		if (vel.magVecSquared() > 4.f) @@ -1126,13 +1126,14 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)  	}  } +static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Camera"); +  //-----------------------------------------------------------------------------  // updateCamera()  //-----------------------------------------------------------------------------  void LLAgentCamera::updateCamera()  { -	static LLFastTimer::DeclareTimer ftm("Camera"); -	LLFastTimer t(ftm); +	LLFastTimer t(FTM_UPDATE_CAMERA);  	// - changed camera_skyward to the new global "mCameraUpVector"  	mCameraUpVector = LLVector3::z_axis; @@ -1234,7 +1235,7 @@ void LLAgentCamera::updateCamera()  	gAgentCamera.clearPanKeys();  	// lerp camera focus offset -	mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(CAMERA_FOCUS_HALF_LIFE)); +	mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLSmoothInterpolation::getInterpolant(CAMERA_FOCUS_HALF_LIFE));  	if ( mCameraMode == CAMERA_MODE_FOLLOW )  	{ @@ -1352,7 +1353,7 @@ void LLAgentCamera::updateCamera()  		{  			const F32 SMOOTHING_HALF_LIFE = 0.02f; -			F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE); +			F32 smoothing = LLSmoothInterpolation::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);  			if (!mFocusObject)  // we differentiate on avatar mode   			{ @@ -1382,7 +1383,7 @@ void LLAgentCamera::updateCamera()  	} -	mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(FOV_ZOOM_HALF_LIFE)); +	mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLSmoothInterpolation::getInterpolant(FOV_ZOOM_HALF_LIFE));  //	llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl; @@ -1796,7 +1797,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)  			if (mTargetCameraDistance != mCurrentCameraDistance)  			{ -				F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(CAMERA_ZOOM_HALF_LIFE); +				F32 camera_lerp_amt = LLSmoothInterpolation::getInterpolant(CAMERA_ZOOM_HALF_LIFE);  				mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);  			} @@ -1813,7 +1814,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)  			if (isAgentAvatarValid())  			{  				LLVector3d camera_lag_d; -				F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE); +				F32 lag_interp = LLSmoothInterpolation::getInterpolant(CAMERA_LAG_HALF_LIFE);  				LLVector3 target_lag;  				LLVector3 vel = gAgent.getVelocity(); @@ -1858,7 +1859,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)  				}  				else  				{ -					mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(0.15f)); +					mCameraLag = lerp(mCameraLag, LLVector3::zero, LLSmoothInterpolation::getInterpolant(0.15f));  				}  				camera_lag_d.setVec(mCameraLag); diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index c88694ef76..861991f3c2 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -39,6 +39,7 @@  #include "llinventoryfunctions.h"  #include "llinventoryobserver.h"  #include "llinventorypanel.h" +#include "lllocaltextureobject.h"  #include "llmd5.h"  #include "llnotificationsutil.h"  #include "lloutfitobserver.h" @@ -64,10 +65,10 @@ using namespace LLAvatarAppearanceDefines;  void wear_and_edit_cb(const LLUUID& inv_item)  {  	if (inv_item.isNull()) return; -	 +  	// Request editing the item after it gets worn.  	gAgentWearables.requestEditingWearable(inv_item); -	 +  	// Wear it.  	LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);  } @@ -180,7 +181,7 @@ void LLAgentWearables::initClass()  }  void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) -{ +{   	llassert(avatar);  	avatar->outputRezTiming("Sending wearables request");  	sendAgentWearablesRequest(); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 46252afbde..862b428e48 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -34,6 +34,7 @@  #include "llinventorymodel.h"  #include "llinventoryobserver.h"  #include "llviewerinventory.h" +#include "llhttpclient.h"  class LLWearableHoldingPattern;  class LLInventoryCallback; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fdc2cdb78d..42bf9b657b 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -61,7 +61,8 @@  #include "llcalc.h"  #include "llconversationlog.h"  #include "lltexturestats.h" -#include "lltexturestats.h" +#include "lltrace.h" +#include "lltracethreadrecorder.h"  #include "llviewerwindow.h"  #include "llviewerdisplay.h"  #include "llviewermedia.h" @@ -96,6 +97,7 @@  #include "llupdaterservice.h"  #include "llfloatertexturefetchdebugger.h"  #include "llspellcheck.h" +#include "llscenemonitor.h"  // Linden library includes  #include "llavatarnamecache.h" @@ -294,7 +296,7 @@ LLPumpIO* gServicePump = NULL;  U64 gFrameTime = 0;  F32 gFrameTimeSeconds = 0.f; -F32 gFrameIntervalSeconds = 0.f; +LLUnit<LLUnits::Seconds, F32> gFrameIntervalSeconds = 0.f;  F32 gFPSClamped = 10.f;						// Pretend we start at target rate.  F32 gFrameDTClamped = 0.f;					// Time between adjacent checks to network for packets  U64	gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds @@ -624,7 +626,7 @@ public:  		while (!LLAppViewer::instance()->isQuitting())  		{ -			LLFastTimer::writeLog(os); +			LLTrace::TimeBlock::writeLog(os);  			os.flush();  			ms_sleep(32);  		} @@ -722,7 +724,6 @@ bool LLAppViewer::init()  	// into the log files during normal startup until AFTER  	// we run the "program crashed last time" error handler below.  	// -	LLFastTimer::reset();  	// initialize LLWearableType translation bridge.  	// Memory will be cleaned up in ::cleanupClass() @@ -1082,9 +1083,9 @@ bool LLAppViewer::init()  	if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())  	{  		if (gGLManager.mIsIntel) -		{ -			LLNotificationsUtil::add("IntelOldDriver"); -		} +	{ +		LLNotificationsUtil::add("IntelOldDriver"); +	}  		else if (gGLManager.mIsNVIDIA)  		{  			LLNotificationsUtil::add("NVIDIAOldDriver"); @@ -1251,6 +1252,8 @@ LLFastTimer::DeclareTimer FTM_FRAME("Frame", true);  bool LLAppViewer::mainLoop()  { +	llinfos << "***********************Entering main_loop***********************" << llendflush; +  	mMainloopTimeout = new LLWatchdogTimeout();  	//------------------------------------------- @@ -1287,7 +1290,11 @@ bool LLAppViewer::mainLoop()  	while (!LLApp::isExiting())  	{  		LLFastTimer _(FTM_FRAME); -		LLFastTimer::nextFrame();  +		LLTrace::TimeBlock::processTimes(); +		LLTrace::get_frame_recording().nextPeriod(); +		LLTrace::TimeBlock::logStats(); + +		LLTrace::getUIThreadRecorder().pullFromSlaveThreads();  		//clear call stack records  		llclearcallstacks; @@ -1404,7 +1411,6 @@ bool LLAppViewer::mainLoop()  					LLFloaterSnapshot::update(); // take snapshots  					gGLActive = FALSE;  				} -  			}  			pingMainloopTimeout("Main:Sleep"); @@ -1459,20 +1465,9 @@ bool LLAppViewer::mainLoop()  				{  					S32 work_pending = 0;  					S32 io_pending = 0; -					F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); +					F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); -					{ -						LLFastTimer ftm(FTM_TEXTURE_CACHE); - 						work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread -					} -					{ -						LLFastTimer ftm(FTM_DECODE); -	 					work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread -					} -					{ -						LLFastTimer ftm(FTM_DECODE); -	 					work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread -					} +					work_pending += updateTextureThreads(max_time);  					{  						LLFastTimer ftm(FTM_VFS); @@ -1585,11 +1580,29 @@ bool LLAppViewer::mainLoop()  	destroyMainloopTimeout(); -	llinfos << "Exiting main_loop" << llendflush; +	llinfos << "***********************Exiting main_loop***********************" << llendflush;  	return true;  } +S32 LLAppViewer::updateTextureThreads(F32 max_time) +{ +	S32 work_pending = 0; +	{ +		LLFastTimer ftm(FTM_TEXTURE_CACHE); + 		work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread +	} +	{ +		LLFastTimer ftm(FTM_DECODE); +	 	work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread +	} +	{ +		LLFastTimer ftm(FTM_DECODE); +	 	work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread +	} +	return work_pending; +} +  void LLAppViewer::flushVFSIO()  {  	while (1) @@ -1613,12 +1626,15 @@ bool LLAppViewer::cleanup()  	// workaround for DEV-35406 crash on shutdown  	LLEventPumps::instance().reset(); +	//dump scene loading monitor results +	LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); +  	if (LLFastTimerView::sAnalyzePerformance)  	{  		llinfos << "Analyzing performance" << llendl; -		std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; -		std::string current_name  = LLFastTimer::sLogName + ".slp";  -		std::string report_name   = LLFastTimer::sLogName + "_report.csv"; +		std::string baseline_name = LLTrace::TimeBlock::sLogName + "_baseline.slp"; +		std::string current_name  = LLTrace::TimeBlock::sLogName + ".slp";  +		std::string report_name   = LLTrace::TimeBlock::sLogName + "_report.csv";  		LLFastTimerView::doAnalysis(  			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), @@ -1799,7 +1815,7 @@ bool LLAppViewer::cleanup()  	llinfos << "Cleaning up Objects" << llendflush;  	LLViewerObject::cleanupVOClasses(); - +	  	LLAvatarAppearance::cleanupClass();  	LLPostProcess::cleanupClass(); @@ -1970,9 +1986,9 @@ bool LLAppViewer::cleanup()  	{  		llinfos << "Analyzing performance" << llendl; -		std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; -		std::string current_name  = LLFastTimer::sLogName + ".slp";  -		std::string report_name   = LLFastTimer::sLogName + "_report.csv"; +		std::string baseline_name = LLTrace::TimeBlock::sLogName + "_baseline.slp"; +		std::string current_name  = LLTrace::TimeBlock::sLogName + ".slp";  +		std::string report_name   = LLTrace::TimeBlock::sLogName + "_report.csv";  		LLFastTimerView::doAnalysis(  			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), @@ -2097,10 +2113,10 @@ bool LLAppViewer::initThreads()  													enable_threads && true,  													app_metrics_qa_mode);	 -	if (LLFastTimer::sLog || LLFastTimer::sMetricLog) +	if (LLTrace::TimeBlock::sLog || LLTrace::TimeBlock::sMetricLog)  	{ -		LLFastTimer::sLogLock = new LLMutex(NULL); -		mFastTimerLogThread = new LLFastTimerLogThread(LLFastTimer::sLogName); +		LLTrace::TimeBlock::setLogLock(new LLMutex(NULL)); +		mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::TimeBlock::sLogName);  		mFastTimerLogThread->start();  	} @@ -2538,13 +2554,13 @@ bool LLAppViewer::initConfiguration()  	if (clp.hasOption("logperformance"))  	{ -		LLFastTimer::sLog = TRUE; -		LLFastTimer::sLogName = std::string("performance");		 +		LLTrace::TimeBlock::sLog = true; +		LLTrace::TimeBlock::sLogName = std::string("performance");		  	}  	if (clp.hasOption("logmetrics"))   	{ - 		LLFastTimer::sMetricLog = TRUE ; + 		LLTrace::TimeBlock::sMetricLog = true ;  		// '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test  		// In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...)  		std::string test_name = clp.getOption("logmetrics")[0]; @@ -2552,11 +2568,11 @@ bool LLAppViewer::initConfiguration()  		if (test_name == "")  		{  			llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl; -			LLFastTimer::sLogName = DEFAULT_METRIC_NAME; +			LLTrace::TimeBlock::sLogName = DEFAULT_METRIC_NAME;  		}  		else  		{ -			LLFastTimer::sLogName = test_name; +			LLTrace::TimeBlock::sLogName = test_name;  		}   	} @@ -2769,7 +2785,7 @@ bool LLAppViewer::initConfiguration()  	}  	initMarkerFile(); -         +		  	if (mSecondInstance)  	{  		// This is the second instance of SL. Turn off voice support, @@ -2989,7 +3005,7 @@ namespace {  			relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));  			substitutions["INFO_URL"] = relnotes_url.getString();  		} -		 +  		LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);  	} @@ -3771,7 +3787,7 @@ void LLAppViewer::requestQuit()  	// Try to send metrics back to the grid  	metricsSend(!gDisconnected); - +	  	// Try to send last batch of avatar rez metrics.  	if (!gDisconnected && isAgentAvatarValid())  	{ @@ -3972,7 +3988,7 @@ U32 LLAppViewer::getObjectCacheVersion()  {  	// Viewer object cache version, change if object update  	// format changes. JC -	const U32 INDRA_OBJECT_CACHE_VERSION = 14; +	const U32 INDRA_OBJECT_CACHE_VERSION = 15;  	return INDRA_OBJECT_CACHE_VERSION;  } @@ -4229,6 +4245,14 @@ void LLAppViewer::purgeCache()  	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*");  } +//purge cache immediately, do not wait until the next login. +void LLAppViewer::purgeCacheImmediate() +{ +	LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL; +	LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false); +	LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true); +} +  std::string LLAppViewer::getSecondLifeTitle() const  {  	return LLTrans::getString("APP_NAME"); @@ -4413,6 +4437,8 @@ static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World");  static LLFastTimer::DeclareTimer FTM_NETWORK("Network");  static LLFastTimer::DeclareTimer FTM_AGENT_NETWORK("Agent Network");  static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager"); +static LLFastTimer::DeclareTimer FTM_AGENT_POSITION("Agent Position"); +static LLFastTimer::DeclareTimer FTM_HUD_EFFECTS("HUD Effects");  ///////////////////////////////////////////////////////  // idle() @@ -4431,7 +4457,7 @@ void LLAppViewer::idle()  	LLFrameTimer::updateFrameCount();  	LLEventTimer::updateClass();  	LLNotificationsUI::LLToast::updateClass(); -	LLCriticalDamp::updateInterpolants(); +	LLSmoothInterpolation::updateInterpolants();  	LLMortician::updateClass();  	LLFilePickerThread::clearDead();  //calls LLFilePickerThread::notify() @@ -4456,6 +4482,7 @@ void LLAppViewer::idle()  	{  		if (gRenderStartTime.getElapsedTimeF32() > qas)  		{ +			llinfos << "Quitting after " << qas << " seconds. See setting \"QuitAfterSeconds\"." << llendl;  			LLAppViewer::instance()->forceQuit();  		}  	} @@ -4554,21 +4581,12 @@ void LLAppViewer::idle()  				llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl;  				gObjectList.mNumDeadObjectUpdates = 0;  			} -			if (gObjectList.mNumUnknownKills) -			{ -				llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl; -				gObjectList.mNumUnknownKills = 0; -			}  			if (gObjectList.mNumUnknownUpdates)  			{  				llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;  				gObjectList.mNumUnknownUpdates = 0;  			} -			// ViewerMetrics FPS piggy-backing on the debug timer. -			// The 5-second interval is nice for this purpose.  If the object debug -			// bit moves or is disabled, please give this a suitable home. -			LLViewerAssetStatsFF::record_fps_main(gFPSClamped);  		}  	} @@ -4649,8 +4667,7 @@ void LLAppViewer::idle()  	{  		// Handle pending gesture processing -		static LLFastTimer::DeclareTimer ftm("Agent Position"); -		LLFastTimer t(ftm); +		LLFastTimer t(FTM_AGENT_POSITION);  		LLGestureMgr::instance().update();  		gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY); @@ -4697,8 +4714,7 @@ void LLAppViewer::idle()  	//  	{ -		static LLFastTimer::DeclareTimer ftm("HUD Effects"); -		LLFastTimer t(ftm); +		LLFastTimer t(FTM_HUD_EFFECTS);  		LLSelectMgr::getInstance()->updateEffects();  		LLHUDManager::getInstance()->cleanupEffects();  		LLHUDManager::getInstance()->sendEffects(); @@ -5102,7 +5118,7 @@ void LLAppViewer::idleNetwork()  			gPrintMessagesThisFrame = FALSE;  		}  	} -	LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); +	add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);  	// Retransmit unacknowledged packets.  	gXferManager->retransmitUnackedPackets(); @@ -5181,6 +5197,7 @@ void LLAppViewer::disconnectViewer()  	{  		LLWorld::getInstance()->destroyClass();  	} +	LLVOCache::deleteSingleton();  	// call all self-registered classes  	LLDestroyClassList::instance().fireCallbacks(); @@ -5504,17 +5521,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle)  {  	if (0 != region_handle)  	{ -		LLViewerAssetStatsFF::set_region_main(region_handle); -		if (LLAppViewer::sTextureFetch) -		{ -			// Send a region update message into 'thread1' to get the new region. -			LLAppViewer::sTextureFetch->commandSetRegion(region_handle); -		} -		else -		{ -			// No 'thread1', a.k.a. TextureFetch, so update directly -			LLViewerAssetStatsFF::set_region_thread1(region_handle); -		} +		LLViewerAssetStatsFF::set_region(region_handle);  	}  } @@ -5525,7 +5532,7 @@ void LLAppViewer::metricsUpdateRegion(U64 region_handle)   */  void LLAppViewer::metricsSend(bool enable_reporting)  { -	if (! gViewerAssetStatsMain) +	if (! gViewerAssetStats)  		return;  	if (LLAppViewer::sTextureFetch) @@ -5538,7 +5545,10 @@ void LLAppViewer::metricsSend(bool enable_reporting)  			// Make a copy of the main stats to send into another thread.  			// Receiving thread takes ownership. -			LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStatsMain)); +			LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats)); +			main_stats->stop(); + +			main_stats->updateStats();  			// Send a report request into 'thread1' to get the rest of the data  			// and provide some additional parameters while here. @@ -5557,6 +5567,6 @@ void LLAppViewer::metricsSend(bool enable_reporting)  	// Reset even if we can't report.  Rather than gather up a huge chunk of  	// data, we'll keep to our sampling interval and retain the data  	// resolution in time. -	gViewerAssetStatsMain->reset(); +	gViewerAssetStats->reset();  } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index d3a8cf24d9..2e75de445f 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -32,6 +32,7 @@  #include "llsys.h"			// for LLOSInfo  #include "lltimer.h"  #include "llappcorehttp.h" +#include "llunit.h"  class LLCommandLineParser;  class LLFrameTimer; @@ -169,6 +170,8 @@ public:  	void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle  	void purgeCache(); // Clear the local cache.  +	void purgeCacheImmediate(); //clear local cache immediately. +	S32  updateTextureThreads(F32 max_time);  	// mute/unmute the system's master audio  	virtual void setMasterSystemAudioMute(bool mute); @@ -219,7 +222,7 @@ private:  	void initMarkerFile();   	static void recordMarkerVersion(LLAPRFile& marker_file);  	bool markerIsSameVersion(const std::string& marker_name) const; -	 +          void idle();       void idleShutdown();  	// update avatar SLID and display name caches @@ -334,7 +337,7 @@ extern LLPumpIO* gServicePump;  extern U64      gFrameTime;					// The timestamp of the most-recently-processed frame  extern F32		gFrameTimeSeconds;			// Loses msec precision after ~4.5 hours... -extern F32		gFrameIntervalSeconds;		// Elapsed time between current and previous gFrameTimeSeconds +extern LLUnit<LLUnits::Seconds, F32>		gFrameIntervalSeconds;		// Elapsed time between current and previous gFrameTimeSeconds  extern F32		gFPSClamped;				// Frames per second, smoothed, weighted toward last frame  extern F32		gFrameDTClamped;  extern U64		gStartTime; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 0ba3669487..a113ab2508 100755 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -29,11 +29,12 @@  #ifdef INCLUDE_VLD  #include "vld.h"  #endif +#include "llwin32headers.h" -#include "llappviewerwin32.h" +#include "llwindowwin32.h" // *FIX: for setting gIconResource. +#include "llappviewerwin32.h" -#include "llwindowwin32.h" // *FIX: for setting gIconResource.  #include "llgl.h"  #include "res/resource.h" // *FIX: for setting gIconResource. diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 14583e402d..3da77857c6 100755 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -32,13 +32,10 @@  #include "llcallingcard.h" -#include <vector>  #include <algorithm> -//#include <iterator>  #include "indra_constants.h" -#include "llavatarnamecache.h" -#include "llcachename.h" +//#include "llcachename.h"  #include "llstl.h"  #include "lltimer.h"  #include "lluuid.h" @@ -46,19 +43,14 @@  #include "llagent.h"  #include "llavatarnamecache.h" -#include "llbutton.h"  #include "llinventoryobserver.h"  #include "llinventorymodel.h"  #include "llnotifications.h" -#include "llnotificationsutil.h" -#include "llresmgr.h"  #include "llslurl.h"  #include "llimview.h"  #include "lltrans.h"  #include "llviewercontrol.h" -#include "llviewernetwork.h"  #include "llviewerobjectlist.h" -#include "llviewerwindow.h"  #include "llvoavatar.h"  #include "llavataractions.h" @@ -105,8 +97,6 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,  LLAvatarTracker::LLAvatarTracker() :  	mTrackingData(NULL),  	mTrackedAgentValid(false), -	//mInventory(NULL), -	//mInventoryObserver(NULL),  	mModifyMask(0x0)	  {  } @@ -641,11 +631,11 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)  					payload["from_id"] = agent_id;  					if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights)  					{ -						LLNotificationsUtil::add("GrantedModifyRights",args, payload); +						LLNotifications::instance().add("GrantedModifyRights",args, payload);  					}  					else  					{ -						LLNotificationsUtil::add("RevokedModifyRights",args, payload); +						LLNotifications::instance().add("RevokedModifyRights",args, payload);  					}  				}  				(mBuddyInfo[agent_id])->setRightsFrom(new_rights); @@ -729,7 +719,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,  	if (online)  	{  		notification = -			LLNotificationsUtil::add("FriendOnlineOffline", +			LLNotifications::instance().add("FriendOnlineOffline",  									 args,  									 payload.with("respond_on_mousedown", TRUE),  									 boost::bind(&LLAvatarActions::startIM, agent_id)); @@ -737,7 +727,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,  	else  	{  		notification = -			LLNotificationsUtil::add("FriendOnlineOffline", args, payload); +			LLNotifications::instance().add("FriendOnlineOffline", args, payload);  	}  	// If there's an open IM session with this agent, send a notification there too. diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 7d0331757b..b883941963 100755 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -618,24 +618,6 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL  	send_chat_from_viewer(utf8_out_text, type, channel);  } -/* -void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) -{ -	LLMessageSystem* msg = gMessageSystem; -	msg->newMessageFast(_PREHASH_ChatFromViewer); -	msg->nextBlockFast(_PREHASH_AgentData); -	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -	msg->nextBlockFast(_PREHASH_ChatData); -	msg->addStringFast(_PREHASH_Message, utf8_out_text); -	msg->addU8Fast(_PREHASH_Type, type); -	msg->addS32("Channel", channel); - -	gAgent.sendReliableMessage(); - -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); -} -*/  void LLChatBar::onCommitGesture(LLUICtrl* ctrl)  { diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 4588424474..d70d575eab 100755 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -424,8 +424,6 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,  	}  	else  	{ -		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); -  		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )  		{  			LLSD args; diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index aeecf054b8..1264f05d77 100755 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -40,7 +40,7 @@  #include "llsceneview.h"  #include "llviewertexture.h"  #include "llfloaterreg.h" - +#include "llscenemonitor.h"  //  // Globals  // @@ -66,6 +66,7 @@ LLDebugView::~LLDebugView()  	gDebugView = NULL;  	gTextureView = NULL;  	gSceneView = NULL; +	gSceneMonitorView = NULL;  }  void LLDebugView::init() @@ -99,6 +100,13 @@ void LLDebugView::init()  	addChild(gSceneView);  	gSceneView->setRect(rect); +	gSceneMonitorView = new LLSceneMonitorView(r); +	gSceneMonitorView->setFollowsTop(); +	gSceneMonitorView->setFollowsLeft(); +	gSceneMonitorView->setVisible(FALSE); +	addChild(gSceneMonitorView); +	gSceneMonitorView->setRect(rect); +	  	r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f),   									 (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index d7d9f82910..6fd0897919 100755 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -27,7 +27,6 @@  #include "llviewerprecompiledheaders.h"  #include "lldirpicker.h" -//#include "llviewermessage.h"  #include "llworld.h"  #include "llviewerwindow.h"  #include "llkeyboard.h" @@ -36,6 +35,7 @@  #include "lltrans.h"  #include "llwindow.h"	// beforeDialog()  #include "llviewercontrol.h" +#include "llwin32headerslean.h"  #if LL_LINUX || LL_SOLARIS  # include "llfilepicker.h" diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index 682f9d6476..2299341aba 100755 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -46,11 +46,6 @@  #endif -// Need commdlg.h for OPENDIRNAMEA -#ifdef LL_WINDOWS -#include <commdlg.h> -#endif -  class LLFilePicker;  class LLDirPicker diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 47306d3a6a..93fb484f06 100755 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -49,6 +49,7 @@  #include "llspatialpartition.h"  #include "llviewerobjectlist.h"  #include "llviewerwindow.h" +#include "llvocache.h"  const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;  const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -58,6 +59,7 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;  static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");  extern bool gShiftFrame; +LLTrace::MemStatHandle	LLDrawable::sMemStat("LLDrawable");  //////////////////////// @@ -75,43 +77,68 @@ extern bool gShiftFrame;  //  // static -U32 LLDrawable::sCurVisible = 0;  U32 LLDrawable::sNumZombieDrawables = 0;  F32 LLDrawable::sCurPixelAngle = 0; -LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList; +LLDynamicArray<LLPointer<LLDrawable>, 32 > LLDrawable::sDeadList;  #define FORCE_INVISIBLE_AREA 16.f  // static  void LLDrawable::incrementVisible()   { -	sCurVisible++; +	LLViewerOctreeEntryData::incrementVisible();  	sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView();  } -void LLDrawable::init() +LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry) +	: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE), +	  mVObjp(vobj) +{ +	init(new_entry);  +} + +void LLDrawable::init(bool new_entry)  {  	// mXform  	mParent = NULL;  	mRenderType = 0;  	mCurrentScale = LLVector3(1,1,1);  	mDistanceWRTCamera = 0.0f; -	mPositionGroup.clear(); -	mExtents[0].clear(); -	mExtents[1].clear(); -  	mState     = 0; -	mVObjp   = NULL; +  	// mFaces -	mSpatialGroupp = NULL; -	mVisible = sCurVisible - 2;//invisible for the current frame and the last frame.  	mRadius = 0.f; +	mGeneration = -1;	 +	mSpatialBridge = NULL; + +	LLViewerOctreeEntry* entry = NULL; +	LLVOCacheEntry* vo_entry = NULL; +	if(!new_entry && mVObjp && getRegion() != NULL) +	{ +		vo_entry = getRegion()->getCacheEntryForOctree(mVObjp->getLocalID()); +		if(vo_entry) +		{ +			entry = vo_entry->getEntry();			 +		} +	} +	setOctreeEntry(entry); +	if(vo_entry) +	{ +		if(!entry) +		{ +			vo_entry->setOctreeEntry(mEntry); +		} +		else if(vo_entry->getNumOfChildren() > 0) +		{ +			getRegion()->addVisibleCacheEntry(vo_entry); //to load all children. +		} -	mGeneration = -1; -	mBinRadius = 1.f; -	mBinIndex = -1; +		getRegion()->addActiveCacheEntry(vo_entry);		 +	} +	 +	llassert(!vo_entry || vo_entry->getEntry() == mEntry); -	mSpatialBridge = NULL; +	initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.  }  // static @@ -155,6 +182,7 @@ void LLDrawable::markDead()  		llwarns << "Warning!  Marking dead multiple times!" << llendl;  		return;  	} +	setState(DEAD);  	if (mSpatialBridge)  	{ @@ -165,7 +193,6 @@ void LLDrawable::markDead()  	sNumZombieDrawables++;  	// We're dead.  Free up all of our references to other objects -	setState(DEAD);  	cleanupReferences();  //	sDeadList.put(this);  } @@ -219,6 +246,8 @@ void LLDrawable::cleanupReferences()  	gPipeline.unlinkDrawable(this); +	removeFromOctree(); +  	{  		LLFastTimer t(FTM_DEREF_DRAWABLE);  		// Cleanup references to other objects @@ -227,6 +256,21 @@ void LLDrawable::cleanupReferences()  	}  } +void LLDrawable::removeFromOctree() +{ +	if(!mEntry) +	{ +		return; +	} + +	mEntry->removeData(this); +	if(mEntry->hasVOCacheEntry()) +	{ +		getRegion()->removeActiveCacheEntry((LLVOCacheEntry*)mEntry->getVOCacheEntry(), this); +	} +	mEntry = NULL; +} +  void LLDrawable::cleanupDeadDrawables()  {  	/* @@ -290,7 +334,7 @@ LLFace*	LLDrawable::addFace(const LLTextureEntry *te, LLViewerTexture *texturep)  	{  		LLFastTimer t(FTM_ALLOCATE_FACE); -		face = new LLFace(this, mVObjp); +	face = new LLFace(this, mVObjp);  	}  	face->setTEOffset(mFaces.size()); @@ -439,6 +483,12 @@ void LLDrawable::makeActive()  		}  		updatePartition();  	} +	else if (!isRoot() && !mParent->isActive()) //this should not happen, but occasionally it does... +	{ +		mParent->makeActive(); +		//NOTE: linked set will now NEVER become static +		mParent->setState(LLDrawable::ACTIVE_CHILD); +	}  	llassert(isAvatar() || isRoot() || mParent->isActive());  } @@ -455,7 +505,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled)  		//drawable became static with active parent, not acceptable  		llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled); - +		  		LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();  		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();  			 iter != child_list.end(); iter++) @@ -518,7 +568,7 @@ F32 LLDrawable::updateXform(BOOL undamped)  	if (damped && isVisible())  	{ -		F32 lerp_amt = llclamp(LLCriticalDamp::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f); +		F32 lerp_amt = llclamp(LLSmoothInterpolation::getInterpolant(OBJECT_DAMPING_TIME_CONSTANT), 0.f, 1.f);  		LLVector3 new_pos = lerp(old_pos, target_pos, lerp_amt);  		dist_squared = dist_vec_squared(new_pos, target_pos); @@ -647,7 +697,7 @@ BOOL LLDrawable::updateMove()  	{  		return FALSE;  	} -	 +  	makeActive();  	return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped(); @@ -733,7 +783,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)  		LLVOVolume* volume = getVOVolume();  		if (volume)  		{ -			if (getSpatialGroup()) +			if (getGroup())  			{  				pos.set(getPositionGroup().getF32ptr());  			} @@ -851,9 +901,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)  			}  		} -		mExtents[0].add(shift_vector); -		mExtents[1].add(shift_vector); -		mPositionGroup.add(shift_vector); +		shift(shift_vector);  	}  	else if (mSpatialBridge)  	{ @@ -861,9 +909,7 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)  	}  	else if (isAvatar())  	{ -		mExtents[0].add(shift_vector); -		mExtents[1].add(shift_vector); -		mPositionGroup.add(shift_vector); +		shift(shift_vector);  	}  	mVObjp->onShift(shift_vector); @@ -875,40 +921,24 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const  	return mXform.getPositionW();  } -const LLVector4a* LLDrawable::getSpatialExtents() const -{ -	return mExtents; -} - -void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max) -{  -	mExtents[0].load3(min.mV);  -	mExtents[1].load3(max.mV); -} - -void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) -{  -	mExtents[0] = min;  -	mExtents[1] = max; -} - -void LLDrawable::setPositionGroup(const LLVector4a& pos) -{ -	mPositionGroup = pos; -} -  void LLDrawable::updateSpatialExtents()  {  	if (mVObjp)  	{ -		mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]); +		const LLVector4a* exts = getSpatialExtents(); +		LLVector4a extents[2]; +		extents[0] = exts[0]; +		extents[1] = exts[1]; + +		mVObjp->updateSpatialExtents(extents[0], extents[1]); +		setSpatialExtents(extents[0], extents[1]);  	}  	updateBinRadius();  	if (mSpatialBridge.notNull())  	{ -		mPositionGroup.splat(0.f); +		getGroupPosition().splat(0.f);  	}  } @@ -917,11 +947,11 @@ void LLDrawable::updateBinRadius()  {  	if (mVObjp.notNull())  	{ -		mBinRadius = llmin(mVObjp->getBinRadius(), 256.f); +		setBinRadius(llmin(mVObjp->getBinRadius(), 256.f));  	}  	else  	{ -		mBinRadius = llmin(getRadius()*4.f, 256.f); +		setBinRadius(llmin(getRadius()*4.f, 256.f));  	}  } @@ -955,26 +985,56 @@ void LLDrawable::updateUVMinMax()  {  } -LLSpatialGroup* LLDrawable::getSpatialGroup() const +//virtual +bool LLDrawable::isVisible() const +{ +	if (LLViewerOctreeEntryData::isVisible())  {  -	llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1); -	return mSpatialGroupp;  +		return true;  } -void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)  { -	//precondition: mSpatialGroupp MUST be null or DEAD or mSpatialGroupp MUST NOT contain this -	llassert(!mSpatialGroupp || mSpatialGroupp->isDead() || !mSpatialGroupp->hasElement(this)); +		LLviewerOctreeGroup* group = mEntry->getGroup(); +		if (group && group->isVisible()) +		{ +			LLViewerOctreeEntryData::setVisible(); +			return true; +		} +	} -	//precondition: groupp MUST be null or groupp MUST contain this -	llassert(!groupp || groupp->hasElement(this)); +	return false; +} + +//virtual +bool LLDrawable::isRecentlyVisible() const +{ +	//currently visible or visible in the previous frame. +	bool vis = LLViewerOctreeEntryData::isRecentlyVisible(); -/*if (mSpatialGroupp && (groupp != mSpatialGroupp)) +	if(!vis)  	{ -		mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); -	}*/ +		LLviewerOctreeGroup* group = getGroup(); +		if (group && group->isRecentlyVisible()) +		{ +			LLViewerOctreeEntryData::setVisible(); +			vis = TRUE ; +		} +	} + +	return vis ; +} + +void LLDrawable::setGroup(LLviewerOctreeGroup *groupp) +	{ +	LLSpatialGroup* cur_groupp = (LLSpatialGroup*)getGroup(); +     +	//precondition: mGroupp MUST be null or DEAD or mGroupp MUST NOT contain this +	//llassert(!cur_groupp || cur_groupp->isDead() || !cur_groupp->hasElement(this)); + +	//precondition: groupp MUST be null or groupp MUST contain this +	llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this)); -	if (mSpatialGroupp != groupp && getVOVolume()) +	if (cur_groupp != groupp && getVOVolume())  	{ //NULL out vertex buffer references for volumes on spatial group change to maintain  		//requirement that every face vertex buffer is either NULL or points to a vertex buffer  		//contained by its drawable's spatial group @@ -990,10 +1050,10 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)  	//postcondition: if next group is NULL, previous group must be dead OR NULL OR binIndex must be -1  	//postcondition: if next group is NOT NULL, binIndex must not be -1 -	llassert(groupp == NULL ? (mSpatialGroupp == NULL || mSpatialGroupp->isDead()) || getBinIndex() == -1 : -							getBinIndex() != -1); +	//llassert(groupp == NULL ? (cur_groupp == NULL || cur_groupp->isDead()) || (!getEntry() || getEntry()->getBinIndex() == -1) : +	//						(getEntry() && getEntry()->getBinIndex() != -1)); -	mSpatialGroupp = groupp; +	LLViewerOctreeEntryData::setGroup(groupp);  }  LLSpatialPartition* LLDrawable::getSpatialPartition() @@ -1012,11 +1072,11 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()  		{  			if (mVObjp->isHUDAttachment())  			{ -				setSpatialBridge(new LLHUDBridge(this)); +				setSpatialBridge(new LLHUDBridge(this, getRegion()));  			}  			else  			{ -				setSpatialBridge(new LLVolumeBridge(this)); +				setSpatialBridge(new LLVolumeBridge(this, getRegion()));  			}  		}  		return mSpatialBridge->asPartition(); @@ -1035,89 +1095,26 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()  	return retval;  } -const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one. -//static  -S32 LLDrawable::getMinVisFrameRange() -{ -	return MIN_VIS_FRAME_RANGE ; -} - -BOOL LLDrawable::isRecentlyVisible() const +//virtual +S32 LLDrawable::getMinFrameRange() const  { -	//currently visible or visible in the previous frame. -	BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE)  ; - -	if(!vis) -	{ -		LLSpatialGroup* group = getSpatialGroup(); -		if (group && group->isRecentlyVisible()) -		{ -			mVisible = sCurVisible; -			vis = TRUE ; -		} -	} - -	return vis ; -} - -BOOL LLDrawable::isVisible() const -{ -	if (mVisible == sCurVisible) -	{ -		return TRUE; -	} -	 -#if 0 -	//disabling this code fixes DEV-20105.  Leaving in place in case some other bug pops up as a a result. -	//should be safe to just always ask the spatial group for visibility. -	if (isActive()) -	{ -		if (isRoot()) -		{ -			LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() : -									getSpatialGroup(); -			if (group && group->isVisible()) -			{ -				mVisible = sCurVisible; -				return TRUE; -			} -		} -		else -		{ -			if (getParent()->isVisible()) -			{ -				mVisible = sCurVisible; -				return TRUE; -			} -		} -	} -	else -#endif -	{ -		LLSpatialGroup* group = getSpatialGroup(); -		if (group && group->isVisible()) -		{ -			mVisible = sCurVisible; -			return TRUE; -		} -	} +const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one. -	return FALSE; +	return MIN_VIS_FRAME_RANGE ;  }  //=======================================  // Spatial Partition Bridging Drawable  //======================================= -LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) -: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) +LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) :  +	LLDrawable(root->getVObj(), true), +	LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp)  {  	mBridge = this;  	mDrawable = root;  	root->setSpatialBridge(this); -	mBinIndex = -1; -  	mRenderType = mDrawable->mRenderType;  	mDrawableType = mDrawable->mRenderType; @@ -1138,10 +1135,13 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat  LLSpatialBridge::~LLSpatialBridge()  {	 +	if(mEntry) +	{  	LLSpatialGroup* group = getSpatialGroup();  	if (group)  	{ -		group->mSpatialPartition->remove(this, group); +		group->getSpatialPartition()->remove(this, group); +	}  	}  	//delete octree here so listeners will still be able to access bridge specific state @@ -1163,8 +1163,9 @@ void LLSpatialBridge::updateSpatialExtents()  		root->rebound();  	} +	const LLVector4a* root_bounds = root->getBounds();  	LLVector4a offset; -	LLVector4a size = root->mBounds[1]; +	LLVector4a size = root_bounds[1];  	//VECTORIZE THIS  	LLMatrix4a mat; @@ -1176,7 +1177,7 @@ void LLSpatialBridge::updateSpatialExtents()  	LLVector4a center;  	mat.affineTransform(t, center); -	mat.rotate(root->mBounds[0], offset); +	mat.rotate(root_bounds[0], offset);  	center.add(offset);  	LLVector4a v[4]; @@ -1198,12 +1199,9 @@ void LLSpatialBridge::updateSpatialExtents()  	scale.mul(size);  	mat.rotate(scale, v[3]); -	 -	LLVector4a& newMin = mExtents[0]; -	LLVector4a& newMax = mExtents[1]; -	 +	LLVector4a newMin; +	LLVector4a newMax;	  	newMin = newMax = center; -	  	for (U32 i = 0; i < 4; i++)  	{  		LLVector4a delta; @@ -1216,19 +1214,21 @@ void LLSpatialBridge::updateSpatialExtents()  		newMin.setMin(newMin, min);  		newMax.setMax(newMax, max);  	} +	setSpatialExtents(newMin, newMax);  	LLVector4a diagonal;  	diagonal.setSub(newMax, newMin);  	mRadius = diagonal.getLength3().getF32() * 0.5f; -	mPositionGroup.setAdd(newMin,newMax); -	mPositionGroup.mul(0.5f); +	LLVector4a& pos = getGroupPosition(); +	pos.setAdd(newMin,newMax); +	pos.mul(0.5f);  	updateBinRadius();  }  void LLSpatialBridge::updateBinRadius()  { -	mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f); +	setBinRadius(llmin( mOctree->getSize()[0]*0.5f, 256.f));  }  LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) @@ -1262,7 +1262,7 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)  void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select)  { -	mVisible = sCurVisible; +	LLViewerOctreeEntryData::setVisible();  #if 0 && !LL_RELEASE_FOR_DOWNLOAD  	//crazy paranoid rules checking @@ -1297,21 +1297,21 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results,  #endif  } -class LLOctreeMarkNotCulled: public LLOctreeTraveler<LLDrawable> +class LLOctreeMarkNotCulled: public OctreeTraveler  {  public:  	LLCamera* mCamera;  	LLOctreeMarkNotCulled(LLCamera* camera_in) : mCamera(camera_in) { } -	virtual void traverse(const LLOctreeNode<LLDrawable>* node) +	virtual void traverse(const OctreeNode* node)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);  		group->setVisible(); -		LLOctreeTraveler<LLDrawable>::traverse(node); +		OctreeTraveler::traverse(node);  	} -	void visit(const LLOctreeNode<LLDrawable>* branch) +	void visit(const OctreeNode* branch)  	{  		gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera);  	} @@ -1355,7 +1355,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*  			}  			if (!group || -				LLDrawable::getCurrentFrame() - av->mVisible > 1 || +				LLDrawable::getCurrentFrame() - av->getVisible() > 1 ||  				impostor ||  				!loaded)  			{ @@ -1369,16 +1369,17 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*  	group->rebound();  	LLVector4a center; -	center.setAdd(mExtents[0], mExtents[1]); +	const LLVector4a* exts = getSpatialExtents(); +	center.setAdd(exts[0], exts[1]);  	center.mul(0.5f);  	LLVector4a size; -	size.setSub(mExtents[1], mExtents[0]); +	size.setSub(exts[1], exts[0]);  	size.mul(0.5f);  	if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) ||  		LLPipeline::sImpostorRender ||  		(camera_in.AABBInFrustumNoFarClip(center, size) &&  -		AABBSphereIntersect(mExtents[0], mExtents[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist))) +		AABBSphereIntersect(exts[0], exts[1], camera_in.getOrigin(), camera_in.mFrustumCornerDist)))  	{  		if (!LLPipeline::sImpostorRender &&  			!LLPipeline::sShadowRender &&  @@ -1493,9 +1494,7 @@ BOOL LLSpatialBridge::updateMove()  void LLSpatialBridge::shiftPos(const LLVector4a& vec)  { -	mExtents[0].add(vec); -	mExtents[1].add(vec); -	mPositionGroup.add(vec); +	LLDrawable::shift(vec);  }  void LLSpatialBridge::cleanupReferences() @@ -1503,11 +1502,8 @@ void LLSpatialBridge::cleanupReferences()  	LLDrawable::cleanupReferences();  	if (mDrawable)  	{ -		/* -		 -		DON'T DO THIS -- this should happen through octree destruction +		mDrawable->setGroup(NULL); -		mDrawable->setSpatialGroup(NULL);  		if (mDrawable->getVObj())  		{  			LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); @@ -1518,10 +1514,10 @@ void LLSpatialBridge::cleanupReferences()  				LLDrawable* drawable = child->mDrawable;					  				if (drawable)  				{ -					drawable->setSpatialGroup(NULL); +					drawable->setGroup(NULL);				 +				}  				}  			} -		}*/  		LLDrawable* drawablep = mDrawable;  		mDrawable = NULL; @@ -1590,8 +1586,8 @@ void LLDrawable::updateFaceSize(S32 idx)  	}  } -LLBridgePartition::LLBridgePartition() -: LLSpatialPartition(0, FALSE, 0)  +LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, 0, regionp)   {   	mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;   	mPartitionType = LLViewerRegion::PARTITION_BRIDGE; @@ -1599,8 +1595,8 @@ LLBridgePartition::LLBridgePartition()  	mSlopRatio = 0.25f;  } -LLHUDBridge::LLHUDBridge(LLDrawable* drawablep) -: LLVolumeBridge(drawablep) +LLHUDBridge::LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp) +: LLVolumeBridge(drawablep, regionp)  {  	mDrawableType = LLPipeline::RENDER_TYPE_HUD;  	mPartitionType = LLViewerRegion::PARTITION_HUD; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 4420a34fae..98f0b51a97 100755 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -42,6 +42,7 @@  #include "llviewerobject.h"  #include "llrect.h"  #include "llappviewer.h" // for gFrameTimeSeconds +#include "llvieweroctree.h"  class LLCamera;  class LLDrawPool; @@ -59,10 +60,12 @@ const U32 SILHOUETTE_HIGHLIGHT = 0;  // All data for new renderer goes into this class.  LL_ALIGN_PREFIX(16) -class LLDrawable : public LLRefCount +class LLDrawable  +:	public LLViewerOctreeEntryData, +	public LLTrace::MemTrackable<LLDrawable>  {  public: -	LLDrawable(const LLDrawable& rhs) +	LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs)  	{  		*this = rhs;  	} @@ -75,17 +78,7 @@ public:  	static void initClass(); -	void* operator new(size_t size) -	{ -		return ll_aligned_malloc_16(size); -	} - -	void operator delete(void* ptr) -	{ -		ll_aligned_free_16(ptr); -	} - -	LLDrawable()				{ init(); } +	LLDrawable(LLViewerObject *vobj, bool new_entry = false);  	void markDead();			// Mark this drawable as dead  	BOOL isDead() const			{ return isState(DEAD); } @@ -93,11 +86,9 @@ public:  	BOOL isLight() const; -	BOOL isVisible() const;	 -	BOOL isRecentlyVisible() const;	  	virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE); - +	LLSpatialGroup* getSpatialGroup()const          {return (LLSpatialGroup*)getGroup();}  	LLViewerRegion* getRegion()               const { return mVObjp->getRegion(); }  	const LLTextureEntry* getTextureEntry(U8 which) const { return mVObjp->getTE(which); }  	LLPointer<LLViewerObject>& getVObj()							  { return mVObjp; } @@ -110,16 +101,12 @@ public:  	const LLVector3&	  getPosition() const			{ return mXform.getPosition(); }  	const LLVector3&      getWorldPosition() const		{ return mXform.getPositionW(); }  	const LLVector3		  getPositionAgent() const; -	const LLVector4a&	  getPositionGroup() const		{ return mPositionGroup; }  	const LLVector3&	  getScale() const				{ return mCurrentScale; }  	void				  setScale(const LLVector3& scale) { mCurrentScale = scale; }  	const LLQuaternion&   getWorldRotation() const		{ return mXform.getWorldRotation(); }  	const LLQuaternion&   getRotation() const			{ return mXform.getRotation(); }  	F32			          getIntensity() const			{ return llmin(mXform.getScale().mV[0], 4.f); }  	S32					  getLOD() const				{ return mVObjp ? mVObjp->getLOD() : 1; } -	F32					  getBinRadius() const			{ return mBinRadius; } -	S32					  getBinIndex() const			{ return mBinIndex; } -	void				  setBinIndex(S32 index) const	{ mBinIndex = index; }  	void  getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }  	LLXformMatrix*		getXform() { return &mXform; } @@ -150,7 +137,7 @@ public:  	void                setNumFacesFast(const S32 numFaces, LLFacePool *poolp, LLViewerTexture *texturep);  	void				mergeFaces(LLDrawable* src); -	void init(); +	void init(bool new_entry);  	void destroy();  	void update(); @@ -181,8 +168,12 @@ public:  	BOOL getLit() const							{ return isState(UNLIT) ? FALSE : TRUE; }  	void setLit(BOOL lit)						{ lit ? clearState(UNLIT) : setState(UNLIT); } +	bool isVisible() const; +	bool isRecentlyVisible() const; +  	virtual void cleanupReferences(); +	void setGroup(LLviewerOctreeGroup* group);  	void setRadius(const F32 radius);  	F32 getRadius() const						{ return mRadius; }  	F32 getVisibilityRadius() const; @@ -192,11 +183,6 @@ public:  	const LLVector3& getBounds(LLVector3& min, LLVector3& max) const;  	virtual void updateSpatialExtents();  	virtual void updateBinRadius(); -	const LLVector4a* getSpatialExtents() const; -	void setSpatialExtents(const LLVector3& min, const LLVector3& max); -	void setSpatialExtents(const LLVector4a& min, const LLVector4a& max); - -	void setPositionGroup(const LLVector4a& pos);  	void setRenderType(S32 type) 				{ mRenderType = type; }  	BOOL isRenderType(S32 type) 				{ return mRenderType == type; } @@ -205,10 +191,14 @@ public:  	// Debugging methods  	S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators... -	void setSpatialGroup(LLSpatialGroup *groupp); -	LLSpatialGroup *getSpatialGroup() const;  	LLSpatialPartition* getSpatialPartition(); +	virtual S32 getMinFrameRange()const; +	void removeFromOctree(); + +	void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } +	LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } +  	// Statics  	static void incrementVisible();  	static void cleanupDeadDrawables(); @@ -292,10 +282,6 @@ public:  		ACTIVE_CHILD	= 0x40000000,  	} EDrawableFlags; -private: //aligned members -	LL_ALIGN_16(LLVector4a		mExtents[2]); -	LL_ALIGN_16(LLVector4a		mPositionGroup); -	  public:  	LLXformMatrix       mXform; @@ -304,13 +290,8 @@ public:  	F32				mDistanceWRTCamera; -	static S32 getCurrentFrame() { return sCurVisible; } -	static S32 getMinVisFrameRange(); - -	void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } -	LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } -	  	static F32 sCurPixelAngle; //current pixels per radian +	static LLTrace::MemStatHandle sMemStat;  private:  	typedef std::vector<LLFace*> face_list_t; @@ -319,21 +300,15 @@ private:  	S32				mRenderType;  	LLPointer<LLViewerObject> mVObjp;  	face_list_t     mFaces; -	LLSpatialGroup* mSpatialGroupp;  	LLPointer<LLDrawable> mSpatialBridge; -	mutable U32		mVisible;  	F32				mRadius; -	F32				mBinRadius; -	mutable S32		mBinIndex;  	S32				mGeneration;  	LLVector3		mCurrentScale; -	static U32 sCurVisible; // Counter for what value of mVisible means currently visible -  	static U32 sNumZombieDrawables; -	static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList; +	static LLDynamicArray<LLPointer<LLDrawable>, 32> sDeadList;  } LL_ALIGN_POSTFIX(16); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 313b310e1e..7020db917b 100755 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -351,7 +351,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)  	for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{  		LLSpatialGroup* group = *i; -		if (group->mSpatialPartition->mRenderByGroup && +		if (group->getSpatialPartition()->mRenderByGroup &&  			!group->isDead())  		{  			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];	 @@ -389,15 +389,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  	{  		LLSpatialGroup* group = *i;  		llassert(group); -		llassert(group->mSpatialPartition); +		llassert(group->getSpatialPartition()); -		if (group->mSpatialPartition->mRenderByGroup && +		if (group->getSpatialPartition()->mRenderByGroup &&  		    !group->isDead())  		{  			bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.  				// All particle systems seem to come off the wire with texture entries which claim that they glow.  This is probably a bug in the data.  Suppress. -				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && -				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; +				group->getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && +				group->getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;  			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 294cecc703..67dbe6de8b 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -421,7 +421,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  	if (pass == 0)  	{ -		avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); +		avatarp->renderSkinned();  	}  	else  	{ @@ -1246,7 +1246,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  	if( !single_avatar || (avatarp == single_avatar) )  	{ -		avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); +		avatarp->renderSkinned();  	}  } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 5ddc15df42..9a5743919d 100755 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -463,7 +463,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)  	gGL.getTexUnit(0)->bind(mHBTex[dr]); -	LLOverrideFaceColor override(this, face->getFaceColor().mV); +	LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));  	face->renderIndexed();  } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 281f852b0a..98c75a64c7 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2346,8 +2346,6 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)  			return 0.f ;  		} -		//F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ; -		  		S32 i = 0 ;  		for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i);  		i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index de4d03351c..dda4bc9b3c 100755 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -28,7 +28,6 @@  #define LL_LLFACE_H  #include "llstrider.h" -  #include "llrender.h"  #include "v2math.h"  #include "v3math.h" @@ -37,7 +36,6 @@  #include "v4coloru.h"  #include "llquaternion.h"  #include "xform.h" -#include "lldarrayptr.h"  #include "llvertexbuffer.h"  #include "llviewertexture.h"  #include "lldrawable.h" @@ -47,10 +45,8 @@ class LLFacePool;  class LLVolume;  class LLViewerTexture;  class LLTextureEntry; -class LLVertexProgram; -class LLViewerTexture; -class LLGeometryManager;  class LLTextureAtlasSlot; +class LLDrawInfo;  const F32 MIN_ALPHA_SIZE = 1024.f;  const F32 MIN_TEX_ANIM_SIZE = 512.f; @@ -262,11 +258,11 @@ public:  	LLVector2		mTexExtents[2];  	F32				mDistance; -	F32			mLastUpdateTime; -	F32			mLastSkinTime; -	F32			mLastMoveTime; -	LLMatrix4*	mTextureMatrix; -	LLDrawInfo* mDrawInfo; +	F32				mLastUpdateTime; +	F32				mLastSkinTime; +	F32				mLastMoveTime; +	LLMatrix4*		mTextureMatrix; +	LLDrawInfo*		mDrawInfo;  private:  	LLPointer<LLVertexBuffer> mVertexBuffer; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index fbf72b1a85..40526d3357 100755 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -46,7 +46,6 @@  #include "llviewertexturelist.h"  #include "llui.h"  #include "llviewercontrol.h" -#include "llstat.h"  #include "llfasttimer.h"  #include "lltreeiterators.h" @@ -55,24 +54,23 @@  ////////////////////////////////////////////////////////////////////////////// +using namespace LLTrace; +  static const S32 MAX_VISIBLE_HISTORY = 10;  static const S32 LINE_GRAPH_HEIGHT = 240; +static const S32 MIN_BAR_HEIGHT = 3; -//static const int FTV_DISPLAY_NUM  = (sizeof(ft_display_table)/sizeof(ft_display_table[0])); -static S32 FTV_NUM_TIMERS; -const S32 FTV_MAX_DEPTH = 8; - -std::vector<LLFastTimer::NamedTimer*> ft_display_idx; // line of table entry for display purposes (for collapse) +std::vector<TimeBlock*> ft_display_idx; // line of table entry for display purposes (for collapse) -typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_iterator_t; +typedef LLTreeDFSIter<TimeBlock, TimeBlock::child_const_iter> timer_tree_iterator_t;  BOOL LLFastTimerView::sAnalyzePerformance = FALSE; -static timer_tree_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)  +static timer_tree_iterator_t begin_timer_tree(TimeBlock& id)   {   	return timer_tree_iterator_t(&id,  -							boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),  -							boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1)); +							boost::bind(boost::mem_fn(&TimeBlock::beginChildren), _1),  +							boost::bind(boost::mem_fn(&TimeBlock::endChildren), _1));  }  static timer_tree_iterator_t end_timer_tree()  @@ -80,37 +78,74 @@ static timer_tree_iterator_t end_timer_tree()  	return timer_tree_iterator_t();   } +S32 get_depth(const TimeBlock* blockp) +{ +	S32 depth = 0; +	TimeBlock* timerp = blockp->getParent(); +	while(timerp) +	{ +		depth++; +		if (timerp->getParent() == timerp) break; +		timerp = timerp->getParent(); +	} +	return depth; +} +  LLFastTimerView::LLFastTimerView(const LLSD& key)  :	LLFloater(key), -	mHoverTimer(NULL) +	mHoverTimer(NULL), +	mDisplayMode(0), +	mDisplayCenter(ALIGN_CENTER), +	mDisplayCalls(false), +	mDisplayHz(false), +	mScrollIndex(0), +	mHoverID(NULL), +	mHoverBarIndex(-1), +	mPrintStats(-1), +	mRecording(&get_frame_recording()), +	mPauseHistory(false)  { -	mDisplayMode = 0; -	mAvgCountTotal = 0; -	mMaxCountTotal = 0; -	mDisplayCenter = ALIGN_CENTER; -	mDisplayCalls = 0; -	mDisplayHz = 0; -	mScrollIndex = 0; -	mHoverID = NULL; -	mHoverBarIndex = -1; -	FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount(); -	mPrintStats = -1;	 +	mTimerBars = new std::vector<TimerBar>[MAX_VISIBLE_HISTORY + 1]; +} + +LLFastTimerView::~LLFastTimerView() +{ +	if (mRecording != &get_frame_recording()) +	{ +		delete mRecording; +	} +	mRecording = NULL; +	delete [] mTimerBars;  }  void LLFastTimerView::onPause()  { -	LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory; +	setPauseState(!mPauseHistory); +} + +void LLFastTimerView::setPauseState(bool pause_state) +{ +	if (pause_state == mPauseHistory) return; +  	// reset scroll to bottom when unpausing -	if (!LLFastTimer::sPauseHistory) +	if (!pause_state)  	{ -		mScrollIndex = 0; -		LLFastTimer::sResetHistory = true; +		if (mRecording != &get_frame_recording()) +		{ +			delete mRecording; +		} +		mRecording = &get_frame_recording();  		getChild<LLButton>("pause_btn")->setLabel(getString("pause"));  	}  	else  	{ +		mRecording = new PeriodicRecording(get_frame_recording()); +		mScrollIndex = 0; +  		getChild<LLButton>("pause_btn")->setLabel(getString("run"));  	} + +	mPauseHistory = pause_state;  }  BOOL LLFastTimerView::postBuild() @@ -140,15 +175,15 @@ BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)  	{  		S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());  		bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY); -		mPrintStats = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - bar_idx; +		mPrintStats = mScrollIndex + bar_idx;  		return TRUE;  	}  	return LLFloater::handleRightMouseDown(x, y, mask);  } -LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y) +TimeBlock* LLFastTimerView::getLegendID(S32 y)  { -	S32 idx = (getRect().getHeight() - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 5; +	S32 idx = (mBarRect.mTop - y) / (LLFontGL::getFontMonospace()->getLineHeight()+2) - 1;  	if (idx >= 0 && idx < (S32)ft_display_idx.size())  	{ @@ -160,7 +195,7 @@ LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)  BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask)  { -	for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); +	for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME);  		it != end_timer_tree();  		++it)  	{ @@ -173,7 +208,7 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)  {  	if (x < mBarRect.mLeft)   	{ -		LLFastTimer::NamedTimer* idp = getLegendID(y); +		TimeBlock* idp = getLegendID(y);  		if (idp)  		{  			idp->setCollapsed(!idp->getCollapsed()); @@ -209,16 +244,7 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)  		gFocusMgr.setMouseCapture(this);  		return TRUE;  	} -	//else -	//{ -	//	// pause/unpause -	//	LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory; -	//	// reset scroll to bottom when unpausing -	//	if (!LLFastTimer::sPauseHistory) -	//	{ -	//		mScrollIndex = 0; -	//	} -	//} +  	return LLFloater::handleMouseDown(x, y, mask);  } @@ -236,17 +262,18 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  	if (hasMouseCapture())  	{  		F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f); -		mScrollIndex = llround( lerp * (F32)(LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY)); -		mScrollIndex = llclamp(	mScrollIndex, 0, LLFastTimer::getLastFrameIndex()); +		mScrollIndex = llround( lerp * (F32)(mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY)); +		mScrollIndex = llclamp(	mScrollIndex, 0, (S32)mRecording->getNumPeriods());  		return TRUE;  	}  	mHoverTimer = NULL;  	mHoverID = NULL; -	if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y)) +	if(mPauseHistory && mBarRect.pointInRect(x, y))  	{ -		mHoverBarIndex = llmin(LLFastTimer::getCurFrameIndex() - 1,  -								MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight())); +		mHoverBarIndex = llmin((mBarRect.mTop - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1, +								(S32)mRecording->getNumPeriods() - 1, +								MAX_VISIBLE_HISTORY);  		if (mHoverBarIndex == 0)  		{  			return TRUE; @@ -257,13 +284,12 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  		}  		S32 i = 0; -		for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); +		for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME);  			it != end_timer_tree();  			++it, ++i)  		{  			// is mouse over bar for this timer? -			if (x > mBarStart[mHoverBarIndex][i] && -				x < mBarEnd[mHoverBarIndex][i]) +			if (mTimerBars[mHoverBarIndex][i].mVisibleRect.pointInRect(x, y))  			{  				mHoverID = (*it);  				if (mHoverTimer != *it) @@ -275,10 +301,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  					mHoverTimer = (*it);  				} -				mToolTipRect.set(mBarStart[mHoverBarIndex][i],  -					mBarRect.mBottom + llround(((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex + 1)) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))), -					mBarEnd[mHoverBarIndex][i], -					mBarRect.mBottom + llround((F32)(MAX_VISIBLE_HISTORY - mHoverBarIndex) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f)))); +				mToolTipRect = mTimerBars[mHoverBarIndex][i].mVisibleRect;  			}  			if ((*it)->getCollapsed()) @@ -289,7 +312,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  	}  	else if (x < mBarRect.mLeft)   	{ -		LLFastTimer::NamedTimer* timer_id = getLegendID(y); +		TimeBlock* timer_id = getLegendID(y);  		if (timer_id)  		{  			mHoverID = timer_id; @@ -300,9 +323,24 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)  } +static std::string get_tooltip(TimeBlock& timer, S32 history_index, PeriodicRecording& frame_recording) +{ +	std::string tooltip; +	if (history_index == 0) +	{ +		// by default, show average number of call +		tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<LLUnits::Milliseconds, F64>(frame_recording.getPeriodMean(timer)).value(), (S32)frame_recording.getPeriodMean(timer.callCount())); +	} +	else +	{ +		tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)LLUnit<LLUnits::Milliseconds, F64>(frame_recording.getPrevRecording(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecording(history_index).getSum(timer.callCount())); +	} +	return tooltip; +} +  BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)  { -	if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y)) +	if(mPauseHistory && mBarRect.pointInRect(x, y))  	{  		// tooltips for timer bars  		if (mHoverTimer) @@ -310,8 +348,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)  			LLRect screen_rect;  			localRectToScreen(mToolTipRect, &screen_rect); +			std::string tooltip = get_tooltip(*mHoverTimer, mHoverBarIndex > 0 ? mScrollIndex + mHoverBarIndex : 0, *mRecording); +  			LLToolTipMgr::instance().show(LLToolTip::Params() -				.message(mHoverTimer->getToolTip(LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex)) +				.message(tooltip)  				.sticky_rect(screen_rect)  				.delay_time(0.f)); @@ -323,10 +363,10 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)  		// tooltips for timer legend  		if (x < mBarRect.mLeft)   		{ -			LLFastTimer::NamedTimer* idp = getLegendID(y); +			TimeBlock* idp = getLegendID(y);  			if (idp)  			{ -				LLToolTipMgr::instance().show(idp->getToolTip()); +				LLToolTipMgr::instance().show(get_tooltip(*idp, 0, *mRecording));  				return TRUE;  			} @@ -338,705 +378,48 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask)  BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)  { -	LLFastTimer::sPauseHistory = TRUE; +	setPauseState(true);  	mScrollIndex = llclamp(	mScrollIndex + clicks,  							0, -							llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY)); +							llmin((S32)mRecording->getNumPeriods(), (S32)mRecording->getNumPeriods() - MAX_VISIBLE_HISTORY));  	return TRUE;  } -static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true); +static TimeBlock FTM_RENDER_TIMER("Timers", true); +static const S32 MARGIN = 10; +static const S32 LEGEND_WIDTH = 220; -static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors; +static std::map<TimeBlock*, LLColor4> sTimerColors;  void LLFastTimerView::draw()  {  	LLFastTimer t(FTM_RENDER_TIMER); -	std::string tdesc; - -	F64 clock_freq = (F64)LLFastTimer::countsPerSecond(); -	F64 iclock_freq = 1000.0 / clock_freq; -	 -	S32 margin = 10; -	S32 height = getRect().getHeight(); -	S32 width = getRect().getWidth(); -	 -	LLRect new_rect; -	new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height); -	setRect(new_rect); - -	S32 left, top, right, bottom; -	S32 x, y, barw, barh, dx, dy; -	S32 texth; -	LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square"); +	generateUniqueColors();  	// Draw the window background  	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); -	 -	S32 xleft = margin; -	S32 ytop = margin; +	gl_rect_2d(getLocalRect(), LLColor4(0.f, 0.f, 0.f, 0.25f)); -	// Draw some help -	{ -		 -		x = xleft; -		y = height - ytop; -		texth = (S32)LLFontGL::getFontMonospace()->getLineHeight(); - -		char modedesc[][32] = { -			"2 x Average ", -			"Max         ", -			"Recent Max  ", -			"100 ms      " -		}; -		char centerdesc[][32] = { -			"Left      ", -			"Centered  ", -			"Ordered   " -		}; - -		tdesc = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]); -		LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); - -		x = xleft, y -= (texth + 2); -		tdesc = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]); -		LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -		y -= (texth + 2); - -		LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"), -										 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -		y -= (texth + 2); -	} - -	S32 histmax = llmin(LLFastTimer::getLastFrameIndex()+1, MAX_VISIBLE_HISTORY); -		 -	// Draw the legend -	xleft = margin; -	ytop = y; - -	y -= (texth + 2); - -	sTimerColors[&getFrameTimer()] = LLColor4::grey; - -	F32 hue = 0.f; - -	for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); -		it != timer_tree_iterator_t(); -		++it) -	{ -		LLFastTimer::NamedTimer* idp = (*it); - -		const F32 HUE_INCREMENT = 0.23f; -		hue = fmodf(hue + HUE_INCREMENT, 1.f); -		// saturation increases with depth -		F32 saturation = clamp_rescale((F32)idp->getDepth(), 0.f, 3.f, 0.f, 1.f); -		// lightness alternates with depth -		F32 lightness = idp->getDepth() % 2 ? 0.5f : 0.6f; - -		LLColor4 child_color; -		child_color.setHSL(hue, saturation, lightness); - -		sTimerColors[idp] = child_color; -	} - -	const S32 LEGEND_WIDTH = 220; -	{ -		LLLocalClipRect clip(LLRect(margin, y, LEGEND_WIDTH, margin)); -		S32 cur_line = 0; -		ft_display_idx.clear(); -		std::map<LLFastTimer::NamedTimer*, S32> display_line; -		for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); -			it != timer_tree_iterator_t(); -			++it) -		{ -			LLFastTimer::NamedTimer* idp = (*it); -			display_line[idp] = cur_line; -			ft_display_idx.push_back(idp); -			cur_line++; - -			x = xleft; - -			left = x; right = x + texth; -			top = y; bottom = y - texth; -			S32 scale_offset = 0; -			if (idp == mHoverID) -			{ -				scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f); -			} -			gl_rect_2d(left - scale_offset, top + scale_offset, right + scale_offset, bottom - scale_offset, sTimerColors[idp]); - -			F32 ms = 0; -			S32 calls = 0; -			if (mHoverBarIndex > 0 && mHoverID) -			{ -				S32 hidx = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex; -				U64 ticks = idp->getHistoricalCount(hidx); -				ms = (F32)((F64)ticks * iclock_freq); -				calls = (S32)idp->getHistoricalCalls(hidx); -			} -			else -			{ -				U64 ticks = idp->getCountAverage(); -				ms = (F32)((F64)ticks * iclock_freq); -				calls = (S32)idp->getCallAverage(); -			} - -			if (mDisplayCalls) -			{ -				tdesc = llformat("%s (%d)",idp->getName().c_str(),calls); -			} -			else -			{ -				tdesc = llformat("%s [%.1f]",idp->getName().c_str(),ms); -			} -			dx = (texth+4) + idp->getDepth()*8; - -			LLColor4 color = LLColor4::white; -			if (idp->getDepth() > 0) -			{ -				S32 line_start_y = (top + bottom) / 2; -				S32 line_end_y = line_start_y + ((texth + 2) * (cur_line - display_line[idp->getParent()])) - texth; -				gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color); -				S32 line_x = x + (texth + 4) + ((idp->getDepth() - 1) * 8); -				gl_line_2d(line_x, line_start_y, line_x, line_end_y, color); -				if (idp->getCollapsed() && !idp->getChildren().empty()) -				{ -					gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color); -				} -			} - -			x += dx; -			BOOL is_child_of_hover_item = (idp == mHoverID); -			LLFastTimer::NamedTimer* next_parent = idp->getParent(); -			while(!is_child_of_hover_item && next_parent) -			{ -				is_child_of_hover_item = (mHoverID == next_parent); -				if (next_parent->getParent() == next_parent) break; -				next_parent = next_parent->getParent(); -			} - -			LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0,  -											x, y,  -											color,  -											LLFontGL::LEFT, LLFontGL::TOP,  -											is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL); - -			y -= (texth + 2); - -			if (idp->getCollapsed())  -			{ -				it.skipDescendants(); -			} -		} -	} - -	xleft += LEGEND_WIDTH + 8; -	// ytop = ytop; +	S32 y = drawHelp(getRect().getHeight() - MARGIN); +	drawLegend(y - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 2));  	// update rectangle that includes timer bars -	mBarRect.mLeft = xleft; -	mBarRect.mRight = getRect().getWidth(); -	mBarRect.mTop = ytop - (LLFontGL::getFontMonospace()->getLineHeight() + 4); -	mBarRect.mBottom = margin + LINE_GRAPH_HEIGHT; - -	y = ytop; -	barh = (ytop - margin - LINE_GRAPH_HEIGHT) / (MAX_VISIBLE_HISTORY + 2); -	dy = barh>>2; // spacing between bars -	if (dy < 1) dy = 1; -	barh -= dy; -	barw = width - xleft - margin; - -	// Draw the history bars -	if (LLFastTimer::getLastFrameIndex() >= 0) -	{	 -		LLLocalClipRect clip(LLRect(xleft, ytop, getRect().getWidth() - margin, margin)); - -		U64 totalticks; -		if (!LLFastTimer::sPauseHistory) -		{ -			U64 ticks = getFrameTimer().getHistoricalCount(mScrollIndex); - -			if (LLFastTimer::getCurFrameIndex() >= 10) -			{ -				U64 framec = LLFastTimer::getCurFrameIndex(); -				U64 avg = (U64)mAvgCountTotal; -				mAvgCountTotal = (avg*framec + ticks) / (framec + 1); -				if (ticks > mMaxCountTotal) -				{ -					mMaxCountTotal = ticks; -				} -			} - -			if (ticks < mAvgCountTotal/100 || ticks > mAvgCountTotal*100) -			{ -				LLFastTimer::sResetHistory = true; -			} - -			if (LLFastTimer::getCurFrameIndex() < 10 || LLFastTimer::sResetHistory) -			{ -				mAvgCountTotal = ticks; -				mMaxCountTotal = ticks; -				LLFastTimer::sResetHistory = false; -			} -		} - -		if (mDisplayMode == 0) -		{ -			totalticks = mAvgCountTotal*2; -		} -		else if (mDisplayMode == 1) -		{ -			totalticks = mMaxCountTotal; -		} -		else if (mDisplayMode == 2) -		{ -			// Calculate the max total ticks for the current history -			totalticks = 0; -			for (S32 j=0; j<histmax; j++) -			{ -				U64 ticks = getFrameTimer().getHistoricalCount(j); - -				if (ticks > totalticks) -					totalticks = ticks; -			} -		} -		else -		{ -			totalticks = (U64)(clock_freq * .1); // 100 ms -		} -		 -		// Draw MS ticks -		{ -			U32 ms = (U32)((F64)totalticks * iclock_freq) ; - -			tdesc = llformat("%.1f ms |", (F32)ms*.25f); -			x = xleft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tdesc); -			LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, -										 LLFontGL::LEFT, LLFontGL::TOP); -			 -			tdesc = llformat("%.1f ms |", (F32)ms*.50f); -			x = xleft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tdesc); -			LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, -										 LLFontGL::LEFT, LLFontGL::TOP); -			 -			tdesc = llformat("%.1f ms |", (F32)ms*.75f); -			x = xleft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tdesc); -			LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, -										 LLFontGL::LEFT, LLFontGL::TOP); -			 -			tdesc = llformat( "%d ms |", ms); -			x = xleft + barw - LLFontGL::getFontMonospace()->getWidth(tdesc); -			LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, -										 LLFontGL::LEFT, LLFontGL::TOP); -		} - -		// Draw borders -		{ -			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -			gGL.color4f(0.5f,0.5f,0.5f,0.5f); - -			S32 by = y + 2; -			 -			y -= ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); - -			//heading -			gl_rect_2d(xleft-5, by, getRect().getWidth()-5, y+5, FALSE); - -			//tree view -			gl_rect_2d(5, by, xleft-10, 5, FALSE); - -			by = y + 5; -			//average bar -			gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-5, FALSE); -			 -			by -= barh*2+dy; -			 -			//current frame bar -			gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-2, FALSE); -			 -			by -= barh+dy+1; -			 -			//history bars -			gl_rect_2d(xleft-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-barh-dy-2, FALSE);			 -			 -			by = LINE_GRAPH_HEIGHT-barh-dy-7; -			 -			//line graph -			mGraphRect = LLRect(xleft-5, by, getRect().getWidth()-5, 5); -			 -			gl_rect_2d(mGraphRect, FALSE); -		} -		 -		mBarStart.clear(); -		mBarEnd.clear(); - -		// Draw bars for each history entry -		// Special: -1 = show running average -		gGL.getTexUnit(0)->bind(box_imagep->getImage()); -		for (S32 j=-1; j<histmax && y > LINE_GRAPH_HEIGHT; j++) -		{ -			mBarStart.push_back(std::vector<S32>()); -			mBarEnd.push_back(std::vector<S32>()); -			int sublevel_dx[FTV_MAX_DEPTH]; -			int sublevel_left[FTV_MAX_DEPTH]; -			int sublevel_right[FTV_MAX_DEPTH]; -			S32 tidx; -			if (j >= 0) -			{ -				tidx = LLFastTimer::NamedTimer::HISTORY_NUM - j - 1 - mScrollIndex; -			} -			else -			{ -				tidx = -1; -			} -			 -			x = xleft; -			 -			// draw the bars for each stat -			std::vector<S32> xpos; -			std::vector<S32> deltax; -			xpos.push_back(xleft); -			 -			LLFastTimer::NamedTimer* prev_id = NULL; - -			S32 i = 0; -			for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); -				it != end_timer_tree(); -				++it, ++i) -			{ -				LLFastTimer::NamedTimer* idp = (*it); -				F32 frac = tidx == -1 -					? (F32)idp->getCountAverage() / (F32)totalticks  -					: (F32)idp->getHistoricalCount(tidx) / (F32)totalticks; -		 -				dx = llround(frac * (F32)barw); -				S32 prev_delta_x = deltax.empty() ? 0 : deltax.back(); -				deltax.push_back(dx); -				 -				int level = idp->getDepth() - 1; -				 -				while ((S32)xpos.size() > level + 1) -				{ -					xpos.pop_back(); -				} -				left = xpos.back(); -				 -				if (level == 0) -				{ -					sublevel_left[level] = xleft; -					sublevel_dx[level] = dx; -					sublevel_right[level] = sublevel_left[level] + sublevel_dx[level]; -				} -				else if (prev_id && prev_id->getDepth() < idp->getDepth()) -				{ -					U64 sublevelticks = 0; - -					for (LLFastTimer::NamedTimer::child_const_iter it = prev_id->beginChildren(); -						it != prev_id->endChildren(); -						++it) -					{ -						sublevelticks += (tidx == -1) -							? (*it)->getCountAverage()  -							: (*it)->getHistoricalCount(tidx); -					} - -					F32 subfrac = (F32)sublevelticks / (F32)totalticks; -					sublevel_dx[level] = (int)(subfrac * (F32)barw + .5f); - -					if (mDisplayCenter == ALIGN_CENTER) -					{ -						left += (prev_delta_x - sublevel_dx[level])/2; -					} -					else if (mDisplayCenter == ALIGN_RIGHT) -					{ -						left += (prev_delta_x - sublevel_dx[level]); -					} - -					sublevel_left[level] = left; -					sublevel_right[level] = sublevel_left[level] + sublevel_dx[level]; -				}				 - -				right = left + dx; -				xpos.back() = right; -				xpos.push_back(left); -				 -				mBarStart.back().push_back(left); -				mBarEnd.back().push_back(right); - -				top = y; -				bottom = y - barh; - -				if (right > left) -				{ -					//U32 rounded_edges = 0; -					LLColor4 color = sTimerColors[idp];//*ft_display_table[i].color; -					S32 scale_offset = 0; - -					BOOL is_child_of_hover_item = (idp == mHoverID); -					LLFastTimer::NamedTimer* next_parent = idp->getParent(); -					while(!is_child_of_hover_item && next_parent) -					{ -						is_child_of_hover_item = (mHoverID == next_parent); -						if (next_parent->getParent() == next_parent) break; -						next_parent = next_parent->getParent(); -					} - -					if (idp == mHoverID) -					{ -						scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); -						//color = lerp(color, LLColor4::black, -0.4f); -					} -					else if (mHoverID != NULL && !is_child_of_hover_item) -					{ -						color = lerp(color, LLColor4::grey, 0.8f); -					} - -					gGL.color4fv(color.mV); -					F32 start_fragment = llclamp((F32)(left - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f); -					F32 end_fragment = llclamp((F32)(right - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f); -					gl_segmented_rect_2d_fragment_tex(sublevel_left[level], top - level + scale_offset, sublevel_right[level], bottom + level - scale_offset, box_imagep->getTextureWidth(), box_imagep->getTextureHeight(), 16, start_fragment, end_fragment); - -				} - -				if ((*it)->getCollapsed()) -				{ -					it.skipDescendants(); -				} -		 -				prev_id = idp; -			} -			y -= (barh + dy); -			if (j < 0) -				y -= barh; -		} -		 -		//draw line graph history -		{ -			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -			LLLocalClipRect clip(mGraphRect); -			 -			//normalize based on last frame's maximum -			static U64 last_max = 0; -			static F32 alpha_interp = 0.f; -			U64 max_ticks = llmax(last_max, (U64) 1);			 -			F32 ms = (F32)((F64)max_ticks * iclock_freq); -			 -			//display y-axis range -			std::string tdesc; -			 if (mDisplayCalls) -				tdesc = llformat("%d calls", (int)max_ticks); -			else if (mDisplayHz) -				tdesc = llformat("%d Hz", (int)max_ticks); -			else -				tdesc = llformat("%4.2f ms", ms); -							 -			x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(tdesc)-5; -			y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight(); -  -			LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, -										 LLFontGL::LEFT, LLFontGL::TOP); - -			//highlight visible range -			{ -				S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex; -				S32 last_frame = first_frame - MAX_VISIBLE_HISTORY; -				 -				F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1); -				 -				F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame; -				F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame; -				 -				gGL.color4f(0.5f,0.5f,0.5f,0.3f); -				gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom); -				 -				if (mHoverBarIndex >= 0) -				{ -					S32 bar_frame = first_frame - mHoverBarIndex; -					F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame; - -					gGL.color4f(0.5f,0.5f,0.5f,1); -				 -					gGL.begin(LLRender::LINES); -					gGL.vertex2i((S32)bar, mGraphRect.mBottom); -					gGL.vertex2i((S32)bar, mGraphRect.mTop); -					gGL.end(); -				} -			} -			 -			U64 cur_max = 0; -			for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); -				it != end_timer_tree(); -				++it) -			{ -				LLFastTimer::NamedTimer* idp = (*it); -				 -				//fatten highlighted timer -				if (mHoverID == idp) -				{ -					gGL.flush(); -					glLineWidth(3); -				} -			 -				const F32 * col = sTimerColors[idp].mV;// ft_display_table[idx].color->mV; -				 -				F32 alpha = 1.f; -				 -				if (mHoverID != NULL && -					idp != mHoverID) -				{	//fade out non-highlighted timers -					if (idp->getParent() != mHoverID) -					{ -						alpha = alpha_interp; -					} -				} - -				gGL.color4f(col[0], col[1], col[2], alpha);				 -				gGL.begin(LLRender::TRIANGLE_STRIP); -				for (U32 j = llmax(0, LLFastTimer::NamedTimer::HISTORY_NUM - LLFastTimer::getLastFrameIndex()); -					j < LLFastTimer::NamedTimer::HISTORY_NUM; -					j++) -				{ -					U64 ticks = idp->getHistoricalCount(j); - -					if (mDisplayHz) -					{ -						F64 tc = (F64) (ticks+1) * iclock_freq; -						tc = 1000.f/tc; -						ticks = llmin((U64) tc, (U64) 1024); -					} -					else if (mDisplayCalls) -					{ -						ticks = (S32)idp->getHistoricalCalls(j); -					} -										 -					if (alpha == 1.f) -					{  -						//normalize to highlighted timer -						cur_max = llmax(cur_max, ticks); -					} -					F32 x = mGraphRect.mLeft + ((F32) (mGraphRect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j; -					F32 y = mGraphRect.mBottom + (F32) mGraphRect.getHeight()/max_ticks*ticks; -					gGL.vertex2f(x,y); -					gGL.vertex2f(x,mGraphRect.mBottom); -				} -				gGL.end(); -				 -				if (mHoverID == idp) -				{ -					gGL.flush(); -					glLineWidth(1); -				} - -				if (idp->getCollapsed()) -				{	 -					//skip hidden timers -					it.skipDescendants(); -				} -			} -			 -			//interpolate towards new maximum -			last_max = (U64) lerp((F32)last_max, (F32) cur_max, LLCriticalDamp::getInterpolant(0.1f)); -			if (last_max - cur_max <= 1 ||  cur_max - last_max  <= 1) -			{ -				last_max = cur_max; -			} -			F32 alpha_target = last_max > cur_max ? -								llmin((F32) last_max/ (F32) cur_max - 1.f,1.f) : -								llmin((F32) cur_max/ (F32) last_max - 1.f,1.f); -			alpha_interp = lerp(alpha_interp, alpha_target, LLCriticalDamp::getInterpolant(0.1f)); - -			if (mHoverID != NULL) -			{ -				x = (mGraphRect.mRight + mGraphRect.mLeft)/2; -				y = mGraphRect.mBottom + 8; - -				LLFontGL::getFontMonospace()->renderUTF8( -					mHoverID->getName(),  -					0,  -					x, y,  -					LLColor4::white, -					LLFontGL::LEFT, LLFontGL::BOTTOM); -			}					 -		} -	} - -	// Output stats for clicked bar to log -	if (mPrintStats >= 0) -	{ -		std::string legend_stat; -		bool first = true; -		for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); -			it != end_timer_tree(); -			++it) -		{ -			LLFastTimer::NamedTimer* idp = (*it); - -			if (!first) -			{ -				legend_stat += ", "; -			} -			first = false; -			legend_stat += idp->getName(); - -			if (idp->getCollapsed()) -			{ -				it.skipDescendants(); -			} -		} -		llinfos << legend_stat << llendl; - -		std::string timer_stat; -		first = true; -		for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); -			it != end_timer_tree(); -			++it) -		{ -			LLFastTimer::NamedTimer* idp = (*it); - -			if (!first) -			{ -				timer_stat += ", "; -			} -			first = false; - -			U64 ticks; -			if (mPrintStats > 0) -			{ -				ticks = idp->getHistoricalCount(mPrintStats); -			} -			else -			{ -				ticks = idp->getCountAverage(); -			} -			F32 ms = (F32)((F64)ticks * iclock_freq); +	const S32 LEGEND_WIDTH = 220; -			timer_stat += llformat("%.1f",ms); +	mBarRect.mLeft = MARGIN + LEGEND_WIDTH + 8; +	mBarRect.mTop = y; +	mBarRect.mRight = getRect().getWidth() - MARGIN; +	mBarRect.mBottom = MARGIN + LINE_GRAPH_HEIGHT; -			if (idp->getCollapsed()) -			{ -				it.skipDescendants(); -			} -		} -		llinfos << timer_stat << llendl; -		mPrintStats = -1; -	} +	drawBars(); +	drawLineGraph(); +	printLineStats(); +	LLView::draw(); +	mAllTimeMax = llmax(mAllTimeMax, mRecording->getLastRecording().getSum(FTM_FRAME));  	mHoverID = NULL;  	mHoverBarIndex = -1; - -	LLView::draw(); -} - -F64 LLFastTimerView::getTime(const std::string& name) -{ -	const LLFastTimer::NamedTimer* timerp = LLFastTimer::getTimerByName(name); -	if (timerp) -	{ -		return (F64)timerp->getCountAverage() / (F64)LLFastTimer::countsPerSecond(); -	} -	return 0.0;  }  void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch) @@ -1533,13 +916,13 @@ void LLFastTimerView::outputAllMetrics()  //static  void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output)  { -	if(LLFastTimer::sLog) +	if(TimeBlock::sLog)  	{  		doAnalysisDefault(baseline, target, output) ;  		return ;  	} -	if(LLFastTimer::sMetricLog) +	if(TimeBlock::sMetricLog)  	{  		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ;  		return ; @@ -1550,9 +933,660 @@ void	LLFastTimerView::onClickCloseBtn()  	setVisible(false);  } -LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer() +void LLFastTimerView::printLineStats() +{ +	// Output stats for clicked bar to log +	if (mPrintStats >= 0) +	{ +		std::string legend_stat; +		bool first = true; +		for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); +			it != end_timer_tree(); +			++it) +		{ +			TimeBlock* idp = (*it); + +			if (!first) +			{ +				legend_stat += ", "; +			} +			first = false; +			legend_stat += idp->getName(); + +			if (idp->getCollapsed()) +			{ +				it.skipDescendants(); +			} +		} +		llinfos << legend_stat << llendl; + +		std::string timer_stat; +		first = true; +		for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); +			it != end_timer_tree(); +			++it) +		{ +			TimeBlock* idp = (*it); + +			if (!first) +			{ +				timer_stat += ", "; +			} +			first = false; + +			LLUnit<LLUnits::Seconds, F32> ticks; +			if (mPrintStats > 0) +			{ +				ticks = mRecording->getPrevRecording(mPrintStats).getSum(*idp); +			} +			else +			{ +				ticks = mRecording->getPeriodMean(*idp); +			} +			LLUnit<LLUnits::Milliseconds, F32> ms = ticks; + +			timer_stat += llformat("%.1f",ms.value()); + +			if (idp->getCollapsed()) +			{ +				it.skipDescendants(); +			} +		} +		llinfos << timer_stat << llendl; +		mPrintStats = -1; +	} +} + +static LLFastTimer::DeclareTimer FTM_DRAW_LINE_GRAPH("Draw line graph"); + +void LLFastTimerView::drawLineGraph() +{ +	LLFastTimer _(FTM_DRAW_LINE_GRAPH); +	//draw line graph history +	S32 x = mBarRect.mLeft; +	S32 y = LINE_GRAPH_HEIGHT; +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	LLLocalClipRect clip(mGraphRect); + +	//normalize based on last frame's maximum +	static LLUnit<LLUnits::Seconds, F32> max_time = 0.000001; +	static U32 max_calls = 0; +	static F32 alpha_interp = 0.f; + +	//display y-axis range +	std::string axis_label; +	if (mDisplayCalls) +		axis_label = llformat("%d calls", (int)max_calls); +	else if (mDisplayHz) +		axis_label = llformat("%d Hz", (int)(1.f / max_time.value())); +	else +		axis_label = llformat("%4.2f ms", LLUnit<LLUnits::Milliseconds, F32>(max_time).value()); + +	x = mGraphRect.mRight - LLFontGL::getFontMonospace()->getWidth(axis_label)-5; +	y = mGraphRect.mTop - LLFontGL::getFontMonospace()->getLineHeight(); + +	LLFontGL::getFontMonospace()->renderUTF8(axis_label, 0, x, y, LLColor4::white, +		LLFontGL::LEFT, LLFontGL::TOP); + +	//highlight visible range +	{ +		S32 first_frame = mRecording->getNumPeriods() - mScrollIndex; +		S32 last_frame = first_frame - MAX_VISIBLE_HISTORY; + +		F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(mRecording->getNumPeriods()-1); + +		F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame; +		F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame; + +		gGL.color4f(0.5f,0.5f,0.5f,0.3f); +		gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom); + +		if (mHoverBarIndex > 0) +		{ +			S32 bar_frame = first_frame - mHoverBarIndex - 1; +			F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame; + +			gGL.color4f(0.5f,0.5f,0.5f,1); + +			gGL.begin(LLRender::LINES); +			gGL.vertex2i((S32)bar, mGraphRect.mBottom); +			gGL.vertex2i((S32)bar, mGraphRect.mTop); +			gGL.end(); +		} +	} + +	LLUnit<LLUnits::Seconds, F32> cur_max = 0; +	U32 cur_max_calls = 0; +	for(timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); +		it != end_timer_tree(); +		++it) +	{ +		TimeBlock* idp = (*it); + +		//fatten highlighted timer +		if (mHoverID == idp) +		{ +			gGL.flush(); +			glLineWidth(3); +		} + +		const F32 * col = sTimerColors[idp].mV;// ft_display_table[idx].color->mV; + +		F32 alpha = 1.f; + +		if (mHoverID != NULL && +			mHoverID != idp) +		{	//fade out non-highlighted timers +			if (idp->getParent() != mHoverID) +			{ +				alpha = alpha_interp; +			} +		} + +		gGL.color4f(col[0], col[1], col[2], alpha);				 +		gGL.begin(LLRender::TRIANGLE_STRIP); +		for (U32 j = mRecording->getNumPeriods(); +			j > 0; +			j--) +		{ +			LLUnit<LLUnits::Seconds, F32> time = llmax(mRecording->getPrevRecording(j).getSum(*idp), LLUnit<LLUnits::Seconds, F64>(0.000001)); +			U32 calls = mRecording->getPrevRecording(j).getSum(idp->callCount()); + +			if (alpha == 1.f) +			{  +				//normalize to highlighted timer +				cur_max = llmax(cur_max, time); +				cur_max_calls = llmax(cur_max_calls, calls); +			} +			F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording->getNumPeriods()-1); +			F32 y = mDisplayHz  +				? mGraphRect.mBottom + (1.f / time.value()) * ((F32) mGraphRect.getHeight() / (1.f / max_time.value())) +				: mGraphRect.mBottom + time / max_time * (F32)mGraphRect.getHeight(); +			gGL.vertex2f(x,y); +			gGL.vertex2f(x,mGraphRect.mBottom); +		} +		gGL.end(); + +		if (mHoverID == idp) +		{ +			gGL.flush(); +			glLineWidth(1); +		} + +		if (idp->getCollapsed()) +		{	 +			//skip hidden timers +			it.skipDescendants(); +		} +	} +	 +	//interpolate towards new maximum +	max_time = lerp(max_time.value(), cur_max.value(), LLSmoothInterpolation::getInterpolant(0.1f)); +	if (max_time - cur_max <= 1 ||  cur_max - max_time  <= 1) +	{ +		max_time = llmax(LLUnit<LLUnits::Microseconds, F32>(1), LLUnit<LLUnits::Microseconds, F32>(cur_max)); +	} + +	max_calls = llround(lerp((F32)max_calls, (F32) cur_max_calls, LLSmoothInterpolation::getInterpolant(0.1f))); +	if (llabs((S32)(max_calls - cur_max_calls)) <= 1) +	{ +		max_calls = cur_max_calls; +	} + +	// TODO: make sure alpha is correct in DisplayHz mode +	F32 alpha_target = (max_time > cur_max) +		? llmin(max_time / cur_max - 1.f,1.f)  +		: llmin(cur_max/ max_time - 1.f,1.f); +	alpha_interp = lerp(alpha_interp, alpha_target, LLSmoothInterpolation::getInterpolant(0.1f)); + +	if (mHoverID != NULL) +	{ +		x = (mGraphRect.mRight + mGraphRect.mLeft)/2; +		y = mGraphRect.mBottom + 8; + +		LLFontGL::getFontMonospace()->renderUTF8( +			mHoverID->getName(),  +			0,  +			x, y,  +			LLColor4::white, +			LLFontGL::LEFT, LLFontGL::BOTTOM); +	}					 +} + +void LLFastTimerView::drawLegend( S32 y ) +{ +	// draw legend +	S32 dx; +	S32 x = MARGIN; +	const S32 TEXT_HEIGHT = (S32)LLFontGL::getFontMonospace()->getLineHeight(); + +	{ +		LLLocalClipRect clip(LLRect(MARGIN, y, LEGEND_WIDTH, MARGIN)); +		S32 cur_line = 0; +		ft_display_idx.clear(); +		std::map<TimeBlock*, S32> display_line; +		for (timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); +			it != timer_tree_iterator_t(); +			++it) +		{ +			TimeBlock* idp = (*it); +			display_line[idp] = cur_line; +			ft_display_idx.push_back(idp); +			cur_line++; + +			x = MARGIN; + +			LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT); +			S32 scale_offset = 0; +			if (idp == mHoverID) +			{ +				scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f); +			} +			bar_rect.stretch(scale_offset); +			gl_rect_2d(bar_rect, sTimerColors[idp]); + +			LLUnit<LLUnits::Milliseconds, F32> ms = 0; +			S32 calls = 0; +			if (mHoverBarIndex > 0 && mHoverID) +			{ +				S32 hidx = mScrollIndex + mHoverBarIndex; +				ms = mRecording->getPrevRecording(hidx).getSum(*idp); +				calls = mRecording->getPrevRecording(hidx).getSum(idp->callCount()); +			} +			else +			{ +				ms = LLUnit<LLUnits::Seconds, F64>(mRecording->getPeriodMean(*idp)); +				calls = (S32)mRecording->getPeriodMean(idp->callCount()); +			} + +			std::string timer_label; +			if (mDisplayCalls) +			{ +				timer_label = llformat("%s (%d)",idp->getName().c_str(),calls); +			} +			else +			{ +				timer_label = llformat("%s [%.1f]",idp->getName().c_str(),ms.value()); +			} +			dx = (TEXT_HEIGHT+4) + get_depth(idp)*8; + +			LLColor4 color = LLColor4::white; +			if (get_depth(idp) > 0) +			{ +				S32 line_start_y = bar_rect.getCenterY(); +				S32 line_end_y = line_start_y + ((TEXT_HEIGHT + 2) * (cur_line - display_line[idp->getParent()])) - TEXT_HEIGHT; +				gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color); +				S32 line_x = x + (TEXT_HEIGHT + 4) + ((get_depth(idp) - 1) * 8); +				gl_line_2d(line_x, line_start_y, line_x, line_end_y, color); +				if (idp->getCollapsed() && !idp->getChildren().empty()) +				{ +					gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color); +				} +			} + +			x += dx; +			BOOL is_child_of_hover_item = (idp == mHoverID); +			TimeBlock* next_parent = idp->getParent(); +			while(!is_child_of_hover_item && next_parent) +			{ +				is_child_of_hover_item = (mHoverID == next_parent); +				if (next_parent->getParent() == next_parent) break; +				next_parent = next_parent->getParent(); +			} + +			LLFontGL::getFontMonospace()->renderUTF8(timer_label, 0,  +				x, y,  +				color,  +				LLFontGL::LEFT, LLFontGL::TOP,  +				is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL); + +			y -= (TEXT_HEIGHT + 2); + +			if (idp->getCollapsed())  +			{ +				it.skipDescendants(); +			} +		} +	} +} + +void LLFastTimerView::generateUniqueColors() +{ +	// generate unique colors +	{ +		sTimerColors[&FTM_FRAME] = LLColor4::grey; + +		F32 hue = 0.f; + +		for (timer_tree_iterator_t it = begin_timer_tree(FTM_FRAME); +			it != timer_tree_iterator_t(); +			++it) +		{ +			TimeBlock* idp = (*it); + +			const F32 HUE_INCREMENT = 0.23f; +			hue = fmodf(hue + HUE_INCREMENT, 1.f); +			// saturation increases with depth +			F32 saturation = clamp_rescale((F32)get_depth(idp), 0.f, 3.f, 0.f, 1.f); +			// lightness alternates with depth +			F32 lightness = get_depth(idp) % 2 ? 0.5f : 0.6f; + +			LLColor4 child_color; +			child_color.setHSL(hue, saturation, lightness); + +			sTimerColors[idp] = child_color; +		} +	} +} + +S32 LLFastTimerView::drawHelp( S32 y )  { -	return FTM_FRAME.getNamedTimer(); +	// Draw some help +	const S32 texth = (S32)LLFontGL::getFontMonospace()->getLineHeight(); + +	char modedesc[][32] = { +		"2 x Average ", +		"Max         ", +		"Recent Max  ", +		"100 ms      " +	}; +	char centerdesc[][32] = { +		"Left      ", +		"Centered  ", +		"Ordered   " +	}; + +	std::string text; +	text = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]); +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); + +	y -= (texth + 2); +	text = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]); +	LLFontGL::getFontMonospace()->renderUTF8(text, 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); +	y -= (texth + 2); + +	LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"), +		0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); +	y -= (texth + 2); +	return y;  } +void LLFastTimerView::drawTicks() +{ +	// Draw MS ticks +	{ +		LLUnit<LLUnits::Milliseconds, U32> ms = mTotalTimeDisplay; +		std::string tick_label; +		S32 x; +		S32 barw = mBarRect.getWidth(); + +		tick_label = llformat("%.1f ms |", (F32)ms.value()*.25f); +		x = mBarRect.mLeft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tick_label); +		LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, +			LLFontGL::LEFT, LLFontGL::TOP); + +		tick_label = llformat("%.1f ms |", (F32)ms.value()*.50f); +		x = mBarRect.mLeft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tick_label); +		LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, +			LLFontGL::LEFT, LLFontGL::TOP); + +		tick_label = llformat("%.1f ms |", (F32)ms.value()*.75f); +		x = mBarRect.mLeft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tick_label); +		LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, +			LLFontGL::LEFT, LLFontGL::TOP); + +		tick_label = llformat( "%d ms |", (U32)ms.value()); +		x = mBarRect.mLeft + barw - LLFontGL::getFontMonospace()->getWidth(tick_label); +		LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, +			LLFontGL::LEFT, LLFontGL::TOP); +	} +} +void LLFastTimerView::drawBorders( S32 y, const S32 x_start, S32 bar_height, S32 dy ) +{ +	// Draw borders +	{ +		S32 by = y + 6 + (S32)LLFontGL::getFontMonospace()->getLineHeight();	 + +		//heading +		gl_rect_2d(x_start-5, by, getRect().getWidth()-5, y+5, LLColor4::grey, FALSE); + +		//tree view +		gl_rect_2d(5, by, x_start-10, 5, LLColor4::grey, FALSE); + +		by = y + 5; +		//average bar +		gl_rect_2d(x_start-5, by, getRect().getWidth()-5, by-bar_height-dy-5, LLColor4::grey, FALSE); + +		by -= bar_height*2+dy; + +		//current frame bar +		gl_rect_2d(x_start-5, by, getRect().getWidth()-5, by-bar_height-dy-2, LLColor4::grey, FALSE); + +		by -= bar_height+dy+1; + +		//history bars +		gl_rect_2d(x_start-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-bar_height-dy-2, LLColor4::grey, FALSE);			 + +		by = LINE_GRAPH_HEIGHT-bar_height-dy-7; + +		//line graph +		mGraphRect = LLRect(x_start-5, by, getRect().getWidth()-5, 5); + +		gl_rect_2d(mGraphRect, FALSE); +	} +} + +void LLFastTimerView::updateTotalTime() +{ +	switch(mDisplayMode) +	{ +	case 0: +		mTotalTimeDisplay = mRecording->getPeriodMean(FTM_FRAME)*2; +		break; +	case 1: +		mTotalTimeDisplay = mAllTimeMax; +		break; +	case 2: +		// Calculate the max total ticks for the current history +		mTotalTimeDisplay = mRecording->getPeriodMax(FTM_FRAME); +		break; +	default: +		mTotalTimeDisplay = LLUnit<LLUnits::Milliseconds, F32>(100); +		break; +	} + +	mTotalTimeDisplay = LLUnit<LLUnits::Milliseconds, F32>(llceil(mTotalTimeDisplay.as<LLUnits::Milliseconds>().value() / 20.f) * 20.f); +} + +void LLFastTimerView::drawBars() +{ +	updateTotalTime(); +	if (mTotalTimeDisplay <= 0.0) return; + +	LLLocalClipRect clip(mBarRect); + +	S32 bar_height = mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2); +	S32 vpad = llmax(1, bar_height / 4); // spacing between bars +	bar_height -= vpad; + +	drawTicks(); +	S32 y = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); +	drawBorders(y, mBarRect.mLeft, bar_height, vpad); + +	// Draw bars for each history entry +	// Special: -1 = show running average +	LLPointer<LLUIImage> bar_image = LLUI::getUIImage("Rounded_Square"); +	gGL.getTexUnit(0)->bind(bar_image->getImage()); +	const S32 histmax = llmin((S32)mRecording->getNumPeriods(), MAX_VISIBLE_HISTORY) + 1; + +	for (S32 bar_index = 0; bar_index < histmax && y > LINE_GRAPH_HEIGHT; bar_index++) +	{ +		S32 history_index = (bar_index > 0) +			? bar_index + mScrollIndex +			: -1; +		mTimerBars[bar_index].clear(); +		mTimerBars[bar_index].reserve(LLInstanceTracker<LLTrace::TimeBlock>::instanceCount()); + +		updateTimerBarWidths(&FTM_FRAME, mTimerBars[bar_index], history_index, true); +		LLRect frame_bar_rect(mBarRect.mLeft, y, mBarRect.mLeft + mTimerBars[bar_index][0].mWidth, y-bar_height); +		mTimerBars[bar_index][0].mVisibleRect = frame_bar_rect; +		updateTimerBarFractions(&FTM_FRAME, 0, mTimerBars[bar_index]); +		drawBar(&FTM_FRAME, frame_bar_rect, mTimerBars[bar_index], 0, bar_image); +				 +		y -= (bar_height + vpad); +		if (bar_index == 0) +			y -= bar_height; +	} +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +} + +static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_WIDTHS("Update timer bar widths"); + +S32 LLFastTimerView::updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::vector<TimerBar>& bars, S32 history_index, bool visible) +{ +	LLFastTimer _(FTM_UPDATE_TIMER_BAR_WIDTHS); +	F32 self_time_frame_fraction = history_index == -1 +		? (mRecording->getPeriodMean(time_block->selfTime()) / mTotalTimeDisplay)  +		: (mRecording->getPrevRecording(history_index).getSum(time_block->selfTime()) / mTotalTimeDisplay); + +	S32 self_time_width = llround(self_time_frame_fraction * (F32)mBarRect.getWidth()); +	S32 full_width = self_time_width; + +	bool children_visible = visible; + +	// reserve a spot for this bar to be rendered before its children +	// even though we don't know its size yet +	S32 bar_rect_index = bars.size(); +	if (visible) +	{ +		bars.push_back(TimerBar()); +	} + +	if (time_block->getCollapsed()) +	{ +		children_visible = false; +	} +	for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) +	{ +		full_width += updateTimerBarWidths(*it, bars, history_index, children_visible); +	} + +	if (visible) +	{ +		TimerBar& timer_bar = bars[bar_rect_index]; + +		timer_bar.mWidth = full_width; +		timer_bar.mSelfWidth = self_time_width; +		timer_bar.mColor = sTimerColors[time_block]; + +		BOOL is_child_of_hover_item = (time_block == mHoverID); +		TimeBlock* next_parent = time_block->getParent(); +		while(!is_child_of_hover_item && next_parent) +		{ +			is_child_of_hover_item = (mHoverID == next_parent); +			if (next_parent->getParent() == next_parent) break; +			next_parent = next_parent->getParent(); +		} + +		if (mHoverID != NULL  +			&& time_block != mHoverID  +			&& !is_child_of_hover_item) +		{ +			timer_bar.mColor = lerp(timer_bar.mColor, LLColor4::grey, 0.8f); +		} +	} +	return full_width; +} + +static LLFastTimer::DeclareTimer FTM_UPDATE_TIMER_BAR_FRACTIONS("Update timer bar fractions"); + +S32 LLFastTimerView::updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 timer_bar_index, std::vector<TimerBar>& bars) +{ +	LLFastTimer _(FTM_UPDATE_TIMER_BAR_FRACTIONS); +	TimerBar& timer_bar = bars[timer_bar_index]; +	S32 child_time_width = timer_bar.mWidth - timer_bar.mSelfWidth; +	LLRect children_rect = timer_bar.mVisibleRect; + +	if (mDisplayCenter == ALIGN_CENTER) +	{ +		children_rect.mLeft += timer_bar.mSelfWidth / 2; +	} +	else if (mDisplayCenter == ALIGN_RIGHT) +	{ +		children_rect.mLeft += timer_bar.mSelfWidth; +	} +	children_rect.mRight = children_rect.mLeft + timer_bar.mWidth - timer_bar.mSelfWidth; + +	if (children_rect.getHeight() > MIN_BAR_HEIGHT) +	{ +		children_rect.mTop -= 1; +		children_rect.mBottom += 1; +	} +	timer_bar.mChildrenRect = children_rect; + +	//now loop through children and figure out portion of bar image covered by each bar, now that we know the +	//sum of all children +	if (!time_block->getCollapsed()) +	{ +		F32 bar_fraction_start = 0.f; +		for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren();  +			it != end_it;  +			++it) +		{ +			timer_bar_index++; + +			TimerBar& child_timer_bar = bars[timer_bar_index]; +			TimeBlock* child_time_block = *it; + +			child_timer_bar.mStartFraction = bar_fraction_start; +			child_timer_bar.mEndFraction = child_time_width > 0 +				? bar_fraction_start + (F32)child_timer_bar.mWidth / child_time_width +				: 1.f; +			child_timer_bar.mVisibleRect.set(children_rect.mLeft + llround(child_timer_bar.mStartFraction * children_rect.getWidth()),  +				children_rect.mTop,  +				children_rect.mLeft + llround(child_timer_bar.mEndFraction * children_rect.getWidth()),  +				children_rect.mBottom); + +			timer_bar_index = updateTimerBarFractions(child_time_block, timer_bar_index, bars); + +			bar_fraction_start = child_timer_bar.mEndFraction; +		} +	} +	return timer_bar_index; +} + +S32 LLFastTimerView::drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector<TimerBar>& bars, S32 bar_index, LLPointer<LLUIImage>& bar_image) +{ +	TimerBar& timer_bar = bars[bar_index]; + +	// animate scale of bar when hovering over that particular timer +	if (bar_rect.getWidth() > 0) +	{ +		LLRect render_rect(bar_rect); +		S32 scale_offset = 0; +		if (time_block == mHoverID) +		{ +			scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); +			render_rect.mTop += scale_offset; +			render_rect.mBottom -= scale_offset; +		} + +		gGL.color4fv(timer_bar.mColor.mV); +		gl_segmented_rect_2d_fragment_tex(render_rect, +			bar_image->getTextureWidth(), bar_image->getTextureHeight(),  +			16,  +			timer_bar.mStartFraction, timer_bar.mEndFraction); +	} + +	if (!time_block->getCollapsed()) +	{ +		for (TimeBlock::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) +		{ +			++bar_index; +			bar_index = drawBar(*it, timer_bar.mChildrenRect, bars, bar_index, bar_image); +		} +	} + +	return bar_index; +} diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 5766cfa0b0..341adacd65 100755 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -29,11 +29,14 @@  #include "llfloater.h"  #include "llfasttimer.h" +#include "llunit.h" +#include "lltracerecording.h"  class LLFastTimerView : public LLFloater  {  public:  	LLFastTimerView(const LLSD&); +	~LLFastTimerView();  	BOOL postBuild();  	static BOOL sAnalyzePerformance; @@ -46,7 +49,6 @@ private:  	static LLSD analyzePerformanceLogDefault(std::istream& is) ;  	static void exportCharts(const std::string& base, const std::string& target);  	void onPause(); -	LLFastTimer::NamedTimer& getFrameTimer();  public: @@ -59,15 +61,47 @@ public:  	virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);  	virtual void draw(); -	LLFastTimer::NamedTimer* getLegendID(S32 y); -	F64 getTime(const std::string& name); +	LLTrace::TimeBlock* getLegendID(S32 y);  protected:  	virtual	void	onClickCloseBtn(); +  private:	 -	typedef std::vector<std::vector<S32> > bar_positions_t; -	bar_positions_t mBarStart; -	bar_positions_t mBarEnd; +	void drawTicks(); +	void drawLineGraph(); +	void drawLegend(S32 y); +	S32 drawHelp(S32 y); +	void drawBorders( S32 y, const S32 x_start, S32 barh, S32 dy); +	void drawBars(); + +	void printLineStats(); +	void generateUniqueColors(); +	void updateTotalTime(); + +	struct TimerBar +	{ +		TimerBar() +		:	mWidth(0), +			mSelfWidth(0), +			mVisible(true), +			mStartFraction(0.f), +			mEndFraction(1.f) +		{} +		S32			mWidth; +		S32			mSelfWidth; +		LLRect		mVisibleRect, +					mChildrenRect; +		LLColor4	mColor; +		bool		mVisible; +		F32			mStartFraction, +					mEndFraction; +	}; +	S32 updateTimerBarWidths(LLTrace::TimeBlock* time_block, std::vector<TimerBar>& bars, S32 history_index, bool visible); +	S32 updateTimerBarFractions(LLTrace::TimeBlock* time_block, S32 timer_bar_index, std::vector<TimerBar>& bars); +	S32 drawBar(LLTrace::TimeBlock* time_block, LLRect bar_rect, std::vector<TimerBar>& bars, S32 bar_index, LLPointer<LLUIImage>& bar_image); +	void setPauseState(bool pause_state); + +	std::vector<TimerBar>* mTimerBars;  	S32 mDisplayMode;  	typedef enum child_alignment @@ -79,19 +113,21 @@ private:  	} ChildAlignment;  	ChildAlignment mDisplayCenter; -	S32 mDisplayCalls; -	S32 mDisplayHz; -	U64 mAvgCountTotal; -	U64 mMaxCountTotal; +	bool                          mDisplayCalls, +								  mDisplayHz; +	LLUnit<LLUnits::Seconds, F64> mAllTimeMax, +								  mTotalTimeDisplay;  	LLRect mBarRect;  	S32	mScrollIndex; -	LLFastTimer::NamedTimer* mHoverID; -	LLFastTimer::NamedTimer* mHoverTimer; +	LLTrace::TimeBlock*           mHoverID; +	LLTrace::TimeBlock*           mHoverTimer;  	LLRect					mToolTipRect;  	S32 mHoverBarIndex;  	LLFrameTimer mHighlightTimer;  	S32 mPrintStats;  	LLRect mGraphRect; +	LLTrace::PeriodicRecording*	  mRecording; +	bool						  mPauseHistory;  };  #endif diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 4f602f63f1..4d7b81304a 100755 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -50,6 +50,7 @@  // Need commdlg.h for OPENFILENAMEA  #ifdef LL_WINDOWS +#include "llwin32headers.h"  #include <commdlg.h>  #endif diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index caad0afec0..83193b2e14 100755 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -339,10 +339,10 @@ void LLVolumeImplFlexible::doIdleUpdate()  	if (drawablep)  	{  		//LLFastTimer ftm(FTM_FLEXIBLE_UPDATE); - +		  		//ensure drawable is active  		drawablep->makeActive(); - +			  		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))  		{  			bool visible = drawablep->isVisible(); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 83fb887d81..93502daac7 100755 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -296,7 +296,8 @@ LLSD LLFloaterAbout::getInfo()  	if (gPacketsIn > 0)  	{ -		info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent(); +		LLTrace::Recording cur_frame = LLTrace::get_frame_recording().snapshotCurRecording(); +		info["PACKETS_LOST"] = cur_frame.getSum(LLStatViewer::PACKETS_LOST);  		info["PACKETS_IN"] = F32(gPacketsIn);  		info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();  	} diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 113aa9a8f2..76773f914d 100755 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -405,11 +405,11 @@ void LLFloaterAvatarPicker::drawFrustum()          if (gFocusMgr.childHasMouseCapture(getDragHandle()))          { -            mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime)); +            mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));          }          else          { -            mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime)); +            mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));          }      }  } diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 048837acfe..317bdd8d46 100755 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -37,6 +37,7 @@  #include "lluictrlfactory.h"  #include "llviewerobjectlist.h"  #include "llvoavatarself.h" +#include "lllocaltextureobject.h"  using namespace LLAvatarAppearanceDefines; diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 42857b2aa2..84e2956b29 100755 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -202,7 +202,7 @@ public:  	virtual void draw();  	virtual BOOL canClose(); -	void onVisibilityChange ( const LLSD& new_visibility ); +	void onVisibilityChanged ( const LLSD& new_visibility );  }; @@ -1008,7 +1008,7 @@ BOOL LLFloaterBuyLandUI::canClose()  	return can_close;  } -void LLFloaterBuyLandUI::onVisibilityChange ( const LLSD& new_visibility ) +void LLFloaterBuyLandUI::onVisibilityChanged ( const LLSD& new_visibility )  {  	if (new_visibility.asBoolean())  	{ diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index a03425649f..6aebe85e7a 100755 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -529,11 +529,11 @@ void LLFloaterColorPicker::draw()  	if (gFocusMgr.childHasMouseCapture(getDragHandle()))  	{  		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"),  -                                        LLCriticalDamp::getInterpolant(mContextConeFadeTime)); +                                        LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));  	}  	else  	{ -		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime)); +		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(mContextConeFadeTime));  	}  	mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 49f36a2f32..2287277acf 100755 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -841,7 +841,7 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32  	gAgent.sendReliableMessage(); -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT); +	add(LLStatViewer::CHAT_COUNT, 1);  }  class LLChatCommandHandler : public LLCommandHandler diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 8ec85e1160..1b3318a730 100755..100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -41,6 +41,7 @@  #include "llchicletbar.h"  #include "lldonotdisturbnotificationstorage.h"  #include "llfloaterreg.h" +#include "llhttpclient.h"  #include "llfloateravatarpicker.h"  #include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container  #include "llinventoryfunctions.h" @@ -52,6 +53,7 @@  #include "lltrans.h"  #include "llchathistory.h"  #include "llnotifications.h" +#include "llviewerregion.h"  #include "llviewerwindow.h"  #include "lltransientfloatermgr.h"  #include "llinventorymodel.h" @@ -109,7 +111,7 @@ void LLFloaterIMSession::refresh()  void LLFloaterIMSession::onTearOffClicked()  {      LLFloaterIMSessionTab::onTearOffClicked(); - +	      if(mIsP2PChat)      {          if(isTornOff()) @@ -170,7 +172,7 @@ void LLFloaterIMSession::newIMCallback(const LLSD& data)  	}  } -void LLFloaterIMSession::onVisibilityChange(const LLSD& new_visibility) +void LLFloaterIMSession::onVisibilityChanged(const LLSD& new_visibility)  {  	bool visible = new_visibility.asBoolean(); @@ -331,7 +333,7 @@ void LLFloaterIMSession::initIMFloater()  BOOL LLFloaterIMSession::postBuild()  {  	BOOL result = LLFloaterIMSessionTab::postBuild(); - +	  	mInputEditor->setMaxTextLength(1023);  	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));  	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) ); @@ -358,7 +360,7 @@ BOOL LLFloaterIMSession::postBuild()  	return result;  } - +	  void LLFloaterIMSession::onAddButtonClicked()  {      LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn"); @@ -371,7 +373,7 @@ void LLFloaterIMSession::onAddButtonClicked()  	// Need to disable 'ok' button when selected users are already in conversation.  	picker->setOkBtnEnableCb(boost::bind(&LLFloaterIMSession::canAddSelectedToChat, this, _1)); -	 +  	if (root_floater)  	{  		root_floater->addDependentFloater(picker); @@ -426,7 +428,7 @@ bool LLFloaterIMSession::canAddSelectedToChat(const uuid_vec_t& uuids)  			}  		}  	} - +	  	return true;  } @@ -600,7 +602,7 @@ LLFloaterIMSession* LLFloaterIMSession::findInstance(const LLUUID& session_id)  	return conversation;  } - +			  LLFloaterIMSession* LLFloaterIMSession::getInstance(const LLUUID& session_id)  {  	LLFloaterIMSession* conversation = @@ -780,7 +782,7 @@ void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id)  		initIMSession(im_session_id);  		buildConversationViewParticipant();  	} - +	  	initIMFloater();  	LLFloaterIMSessionTab::updateGearBtn();  	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB) diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index a0e0171b34..84abb2435a 100755..100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -62,7 +62,7 @@ public:  	void initIMSession(const LLUUID& session_id);  	void initIMFloater(); - +	  	// LLView overrides  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void setMinimized(BOOL b); @@ -107,7 +107,7 @@ public:  	// called when docked floater's position has been set by chiclet  	void setPositioned(bool b) { mPositioned = b; }; -	void onVisibilityChange(const LLSD& new_visibility); +	void onVisibilityChanged(const LLSD& new_visibility);  	bool enableGearMenuItem(const LLSD& userdata);  	void GearDoToSelected(const LLSD& userdata);  	bool checkGearMenuItem(const LLSD& userdata); @@ -142,10 +142,10 @@ private:      /*virtual*/ void onTearOffClicked();  	/*virtual*/ void onClickCloseBtn(); - +	  	// Update the window title and input field help text  	/*virtual*/ void updateSessionName(const std::string& name); - +	  	bool dropPerson(LLUUID* person_id, bool drop);  	BOOL isInviteAllowed() const; @@ -161,7 +161,7 @@ private:  	bool canAddSelectedToChat(const uuid_vec_t& uuids);  	void onCallButtonClicked(); - +	  	void boundVoiceChannel();  	// Add the "User is typing..." indicator. diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index d0c22d25f2..b71ab4c53b 100755 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -33,7 +33,7 @@  #include "llerror.h"  #include "llrect.h"  #include "llstring.h" -#include "llstat.h" +#include "lltrace.h"  // project includes  #include "lluictrlfactory.h" @@ -42,6 +42,22 @@  #include "llviewerjoystick.h"  #include "llcheckboxctrl.h" +static LLTrace::SampleStatHandle<>	sJoystickAxis1("Joystick axis 1"), +									sJoystickAxis2("Joystick axis 2"), +									sJoystickAxis3("Joystick axis 3"), +									sJoystickAxis4("Joystick axis 4"), +									sJoystickAxis5("Joystick axis 5"), +									sJoystickAxis6("Joystick axis 6"); +static LLTrace::SampleStatHandle<>* sJoystickAxes[6] =  +{ +	&sJoystickAxis1, +	&sJoystickAxis2, +	&sJoystickAxis3, +	&sJoystickAxis4, +	&sJoystickAxis5, +	&sJoystickAxis6 +}; +  LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)  	: LLFloater(data)  { @@ -61,7 +77,7 @@ void LLFloaterJoystick::draw()  	for (U32 i = 0; i < 6; i++)  	{  		F32 value = joystick->getJoystickAxis(i); -		mAxisStats[i]->addValue(value * gFrameIntervalSeconds); +		sample(*sJoystickAxes[i], value * gFrameIntervalSeconds.value());  		if (mAxisStatsBar[i])  		{  			F32 minbar, maxbar; @@ -69,7 +85,7 @@ void LLFloaterJoystick::draw()  			if (llabs(value) > maxbar)  			{  				F32 range = llabs(value); -				mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f); +				mAxisStatsBar[i]->setRange(-range, range, range * 0.25f);  			}  		}  	} @@ -85,13 +101,12 @@ BOOL LLFloaterJoystick::postBuild()  	for (U32 i = 0; i < 6; i++)  	{  		std::string stat_name(llformat("Joystick axis %d", i)); -		mAxisStats[i] = new LLStat(stat_name, 4);  		std::string axisname = llformat("axis%d", i);  		mAxisStatsBar[i] = getChild<LLStatBar>(axisname);  		if (mAxisStatsBar[i])  		{ -			mAxisStatsBar[i]->setStat(mAxisStats[i]); -			mAxisStatsBar[i]->setRange(-range, range, range * 0.25f, range * 0.5f); +			mAxisStatsBar[i]->setStat(stat_name); +			mAxisStatsBar[i]->setRange(-range, range, range * 0.25f);  		}  	} diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index dfdb108ff8..9c3752540d 100755 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -84,7 +84,6 @@ private:  	LLCheckBoxCtrl	*mCheckFlycamEnabled;  	// stats view  -	LLStat* mAxisStats[6];  	LLStatBar* mAxisStatsBar[6];  }; diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp deleted file mode 100755 index 68b1770bb2..0000000000 --- a/indra/newview/llfloaterlagmeter.cpp +++ /dev/null @@ -1,375 +0,0 @@ -/**  - * @file llfloaterlagmeter.cpp - * @brief The "Lag-o-Meter" floater used to tell users what is causing lag. - * - * $LicenseInfo:firstyear=2007&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 "llfloaterlagmeter.h" - -#include "lluictrlfactory.h" -#include "llviewerstats.h" -#include "llviewertexture.h" -#include "llviewercontrol.h" -#include "llappviewer.h" - -#include "lltexturefetch.h" - -#include "llbutton.h" -#include "llfocusmgr.h" -#include "lltextbox.h" - -const std::string LAG_CRITICAL_IMAGE_NAME = "lag_status_critical.tga"; -const std::string LAG_WARNING_IMAGE_NAME  = "lag_status_warning.tga"; -const std::string LAG_GOOD_IMAGE_NAME     = "lag_status_good.tga"; - -LLFloaterLagMeter::LLFloaterLagMeter(const LLSD& key) -	:	LLFloater(key) -{ -	mCommitCallbackRegistrar.add("LagMeter.ClickShrink",  boost::bind(&LLFloaterLagMeter::onClickShrink, this));	 -} - -BOOL LLFloaterLagMeter::postBuild() -{ -	// Don't let this window take keyboard focus -- it's confusing to -	// lose arrow-key driving when testing lag. -	setIsChrome(TRUE); -	 -	// were we shrunk last time? -	if (isShrunk()) -	{ -		onClickShrink(); -	} -	 -	mClientButton = getChild<LLButton>("client_lagmeter"); -	mClientText = getChild<LLTextBox>("client_text"); -	mClientCause = getChild<LLTextBox>("client_lag_cause"); - -	mNetworkButton = getChild<LLButton>("network_lagmeter"); -	mNetworkText = getChild<LLTextBox>("network_text"); -	mNetworkCause = getChild<LLTextBox>("network_lag_cause"); - -	mServerButton = getChild<LLButton>("server_lagmeter"); -	mServerText = getChild<LLTextBox>("server_text"); -	mServerCause = getChild<LLTextBox>("server_lag_cause"); - -	std::string config_string = getString("client_frame_rate_critical_fps", mStringArgs); -	mClientFrameTimeCritical = 1.0f / (float)atof( config_string.c_str() ); -	config_string = getString("client_frame_rate_warning_fps", mStringArgs); -	mClientFrameTimeWarning = 1.0f / (float)atof( config_string.c_str() ); - -	config_string = getString("network_packet_loss_critical_pct", mStringArgs); -	mNetworkPacketLossCritical = (float)atof( config_string.c_str() ); -	config_string = getString("network_packet_loss_warning_pct", mStringArgs); -	mNetworkPacketLossWarning = (float)atof( config_string.c_str() ); - -	config_string = getString("network_ping_critical_ms", mStringArgs); -	mNetworkPingCritical = (float)atof( config_string.c_str() ); -	config_string = getString("network_ping_warning_ms", mStringArgs); -	mNetworkPingWarning = (float)atof( config_string.c_str() ); -	config_string = getString("server_frame_rate_critical_fps", mStringArgs); - -	mServerFrameTimeCritical = 1000.0f / (float)atof( config_string.c_str() ); -	config_string = getString("server_frame_rate_warning_fps", mStringArgs); -	mServerFrameTimeWarning = 1000.0f / (float)atof( config_string.c_str() ); -	config_string = getString("server_single_process_max_time_ms", mStringArgs); -	mServerSingleProcessMaxTime = (float)atof( config_string.c_str() ); - -//	mShrunk = false; -	config_string = getString("max_width_px", mStringArgs); -	mMaxWidth = atoi( config_string.c_str() ); -	config_string = getString("min_width_px", mStringArgs); -	mMinWidth = atoi( config_string.c_str() ); - -	mStringArgs["[CLIENT_FRAME_RATE_CRITICAL]"] = getString("client_frame_rate_critical_fps"); -	mStringArgs["[CLIENT_FRAME_RATE_WARNING]"] = getString("client_frame_rate_warning_fps"); - -	mStringArgs["[NETWORK_PACKET_LOSS_CRITICAL]"] = getString("network_packet_loss_critical_pct"); -	mStringArgs["[NETWORK_PACKET_LOSS_WARNING]"] = getString("network_packet_loss_warning_pct"); - -	mStringArgs["[NETWORK_PING_CRITICAL]"] = getString("network_ping_critical_ms"); -	mStringArgs["[NETWORK_PING_WARNING]"] = getString("network_ping_warning_ms"); - -	mStringArgs["[SERVER_FRAME_RATE_CRITICAL]"] = getString("server_frame_rate_critical_fps"); -	mStringArgs["[SERVER_FRAME_RATE_WARNING]"] = getString("server_frame_rate_warning_fps"); - -//	childSetAction("minimize", onClickShrink, this); -	updateControls(isShrunk()); // if expanded append colon to the labels (EXT-4079) - -	return TRUE; -} -LLFloaterLagMeter::~LLFloaterLagMeter() -{ -	// save shrunk status for next time -//	gSavedSettings.setBOOL("LagMeterShrunk", mShrunk); -	// expand so we save the large window rectangle -	if (isShrunk()) -	{ -		onClickShrink(); -	} -} - -void LLFloaterLagMeter::draw() -{ -	determineClient(); -	determineNetwork(); -	determineServer(); - -	LLFloater::draw(); -} - -void LLFloaterLagMeter::determineClient() -{ -	F32 client_frame_time = LLViewerStats::getInstance()->mFPSStat.getMeanDuration(); -	bool find_cause = false; - -	if (!gFocusMgr.getAppHasFocus()) -	{ -		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME)); -		mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) ); -		mClientCause->setText( LLStringUtil::null ); -	} -	else if(client_frame_time >= mClientFrameTimeCritical) -	{ -		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); -		mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) ); -		find_cause = true; -	} -	else if(client_frame_time >= mClientFrameTimeWarning) -	{ -		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME)); -		mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) ); -		find_cause = true; -	} -	else -	{ -		mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME)); -		mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) ); -		mClientCause->setText( LLStringUtil::null ); -	}	 - -	if(find_cause) -	{ -		if(gSavedSettings.getF32("RenderFarClip") > 128) -		{ -			mClientCause->setText( getString("client_draw_distance_cause_msg", mStringArgs) ); -		} -		else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2) -		{ -			mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); -		} -		else if((BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes)) > LLViewerTexture::sMaxBoundTextureMemInMegaBytes) -		{ -			mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); -		} -		else  -		{ -			mClientCause->setText( getString("client_complex_objects_cause_msg", mStringArgs) ); -		} -	} -} - -void LLFloaterLagMeter::determineNetwork() -{ -	F32 packet_loss = LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean(); -	F32 ping_time = LLViewerStats::getInstance()->mSimPingStat.getMean(); -	bool find_cause_loss = false; -	bool find_cause_ping = false; - -	// *FIXME: We can't blame a large ping time on anything in -	// particular if the frame rate is low, because a low frame -	// rate is a sure recipe for bad ping times right now until -	// the network handlers are de-synched from the rendering. -	F32 client_frame_time_ms = 1000.0f * LLViewerStats::getInstance()->mFPSStat.getMeanDuration(); -	 -	if(packet_loss >= mNetworkPacketLossCritical) -	{ -		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); -		mNetworkText->setText( getString("network_packet_loss_critical_msg", mStringArgs) ); -		find_cause_loss = true; -	} -	else if(ping_time >= mNetworkPingCritical) -	{ -		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); -		if (client_frame_time_ms < mNetworkPingCritical) -		{ -			mNetworkText->setText( getString("network_ping_critical_msg", mStringArgs) ); -			find_cause_ping = true; -		} -	} -	else if(packet_loss >= mNetworkPacketLossWarning) -	{ -		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME)); -		mNetworkText->setText( getString("network_packet_loss_warning_msg", mStringArgs) ); -		find_cause_loss = true; -	} -	else if(ping_time >= mNetworkPingWarning) -	{ -		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME)); -		if (client_frame_time_ms < mNetworkPingWarning) -		{ -			mNetworkText->setText( getString("network_ping_warning_msg", mStringArgs) ); -			find_cause_ping = true; -		} -	} -	else -	{ -		mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME)); -		mNetworkText->setText( getString("network_performance_normal_msg", mStringArgs) ); -	} - -	if(find_cause_loss) - 	{ -		mNetworkCause->setText( getString("network_packet_loss_cause_msg", mStringArgs) ); - 	} -	else if(find_cause_ping) -	{ -		mNetworkCause->setText( getString("network_ping_cause_msg", mStringArgs) ); -	} -	else -	{ -		mNetworkCause->setText( LLStringUtil::null ); -	} -} - -void LLFloaterLagMeter::determineServer() -{ -	F32 sim_frame_time = LLViewerStats::getInstance()->mSimFrameMsec.getCurrent(); -	bool find_cause = false; - -	if(sim_frame_time >= mServerFrameTimeCritical) -	{ -		mServerButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME)); -		mServerText->setText( getString("server_frame_time_critical_msg", mStringArgs) ); -		find_cause = true; -	} -	else if(sim_frame_time >= mServerFrameTimeWarning) -	{ -		mServerButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME)); -		mServerText->setText( getString("server_frame_time_warning_msg", mStringArgs) ); -		find_cause = true; -	} -	else -	{ -		mServerButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME)); -		mServerText->setText( getString("server_frame_time_normal_msg", mStringArgs) ); -		mServerCause->setText( LLStringUtil::null ); -	}	 - -	if(find_cause) -	{ -		if(LLViewerStats::getInstance()->mSimSimPhysicsMsec.getCurrent() > mServerSingleProcessMaxTime) -		{ -			mServerCause->setText( getString("server_physics_cause_msg", mStringArgs) ); -		} -		else if(LLViewerStats::getInstance()->mSimScriptMsec.getCurrent() > mServerSingleProcessMaxTime) -		{ -			mServerCause->setText( getString("server_scripts_cause_msg", mStringArgs) ); -		} -		else if(LLViewerStats::getInstance()->mSimNetMsec.getCurrent() > mServerSingleProcessMaxTime) -		{ -			mServerCause->setText( getString("server_net_cause_msg", mStringArgs) ); -		} -		else if(LLViewerStats::getInstance()->mSimAgentMsec.getCurrent() > mServerSingleProcessMaxTime) -		{ -			mServerCause->setText( getString("server_agent_cause_msg", mStringArgs) ); -		} -		else if(LLViewerStats::getInstance()->mSimImagesMsec.getCurrent() > mServerSingleProcessMaxTime) -		{ -			mServerCause->setText( getString("server_images_cause_msg", mStringArgs) ); -		} -		else -		{ -			mServerCause->setText( getString("server_generic_cause_msg", mStringArgs) ); -		} -	} -} - -void LLFloaterLagMeter::updateControls(bool shrink) -{ -//	LLFloaterLagMeter * self = (LLFloaterLagMeter*)data; - -	LLButton * button = getChild<LLButton>("minimize"); -	S32 delta_width = mMaxWidth -mMinWidth; -	LLRect r = getRect(); - -	if(!shrink) -	{ -		setTitle(getString("max_title_msg", mStringArgs) ); -		// make left edge appear to expand -		r.translate(-delta_width, 0); -		setRect(r); -		reshape(mMaxWidth, getRect().getHeight()); -		 -		getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) + ":"); -		getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) + ":"); -		getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) + ":"); - -		// usually "<<" -		button->setLabel( getString("smaller_label", mStringArgs) ); -	} -	else -	{ -		setTitle( getString("min_title_msg", mStringArgs) ); -		// make left edge appear to collapse -		r.translate(delta_width, 0); -		setRect(r); -		reshape(mMinWidth, getRect().getHeight()); -		 -		getChild<LLUICtrl>("client")->setValue(getString("client_text_msg", mStringArgs) ); -		getChild<LLUICtrl>("network")->setValue(getString("network_text_msg",mStringArgs) ); -		getChild<LLUICtrl>("server")->setValue(getString("server_text_msg", mStringArgs) ); - -		// usually ">>" -		button->setLabel( getString("bigger_label", mStringArgs) ); -	} -	// Don't put keyboard focus on the button -	button->setFocus(FALSE); - -//	self->mClientText->setVisible(self->mShrunk); -//	self->mClientCause->setVisible(self->mShrunk); -//	self->getChildView("client_help")->setVisible( self->mShrunk); - -//	self->mNetworkText->setVisible(self->mShrunk); -//	self->mNetworkCause->setVisible(self->mShrunk); -//	self->getChildView("network_help")->setVisible( self->mShrunk); - -//	self->mServerText->setVisible(self->mShrunk); -//	self->mServerCause->setVisible(self->mShrunk); -//	self->getChildView("server_help")->setVisible( self->mShrunk); - -//	self->mShrunk = !self->mShrunk; -} - -BOOL LLFloaterLagMeter::isShrunk() -{ -	return gSavedSettings.getBOOL("LagMeterShrunk"); -} - -void LLFloaterLagMeter::onClickShrink()  // toggle "LagMeterShrunk" -{ -	bool shrunk = isShrunk(); -	updateControls(!shrunk); -	gSavedSettings.setBOOL("LagMeterShrunk", !shrunk); -} diff --git a/indra/newview/llfloaterlagmeter.h b/indra/newview/llfloaterlagmeter.h deleted file mode 100755 index eef6955601..0000000000 --- a/indra/newview/llfloaterlagmeter.h +++ /dev/null @@ -1,80 +0,0 @@ -/**  - * @file llfloaterlagmeter.h - * @brief The "Lag-o-Meter" floater used to tell users what is causing lag. - * - * $LicenseInfo:firstyear=2007&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 LLFLOATERLAGMETER_H -#define LLFLOATERLAGMETER_H - -#include "llfloater.h" - -class LLTextBox; - -class LLFloaterLagMeter : public LLFloater -{ -	friend class LLFloaterReg; -	 -public: -	/*virtual*/ void draw(); -	/*virtual*/ BOOL postBuild();	 -private: -	 -	LLFloaterLagMeter(const LLSD& key); -	/*virtual*/ ~LLFloaterLagMeter(); -	void determineClient(); -	void determineNetwork(); -	void determineServer(); -	void updateControls(bool shrink); -	BOOL isShrunk(); - -	void onClickShrink(); - -	bool mShrunk; -	S32 mMaxWidth, mMinWidth; - -	F32 mClientFrameTimeCritical; -	F32 mClientFrameTimeWarning; -	LLButton * mClientButton; -	LLTextBox * mClientText; -	LLTextBox * mClientCause; - -	F32 mNetworkPacketLossCritical; -	F32 mNetworkPacketLossWarning; -	F32 mNetworkPingCritical; -	F32 mNetworkPingWarning; -	LLButton * mNetworkButton; -	LLTextBox * mNetworkText; -	LLTextBox * mNetworkCause; - -	F32 mServerFrameTimeCritical; -	F32 mServerFrameTimeWarning; -	F32 mServerSingleProcessMaxTime; -	LLButton * mServerButton; -	LLTextBox * mServerText; -	LLTextBox * mServerCause; - -	LLStringUtil::format_map_t mStringArgs; -}; - -#endif diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 8290494c22..2194c1112a 100755 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -225,7 +225,7 @@ void LLFloaterLand::onOpen(const LLSD& key)  	refresh();  } -void LLFloaterLand::onVisibilityChange(const LLSD& visible) +void LLFloaterLand::onVisibilityChanged(const LLSD& visible)  {  	if (!visible.asBoolean())  	{ @@ -255,7 +255,7 @@ LLFloaterLand::LLFloaterLand(const LLSD& seed)  BOOL LLFloaterLand::postBuild()  {	 -	setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChange, this, _2)); +	setVisibleCallback(boost::bind(&LLFloaterLand::onVisibilityChanged, this, _2));  	LLTabContainer* tab = getChild<LLTabContainer>("landtab"); diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 4f1c10274a..dccdfc9acb 100755 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -88,7 +88,7 @@ private:  	LLFloaterLand(const LLSD& seed);  	virtual ~LLFloaterLand(); -	void onVisibilityChange(const LLSD& visible); +	void onVisibilityChanged(const LLSD& visible);  protected: diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 100f1d580b..85fe901fde 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -113,8 +113,6 @@  #include "llviewernetwork.h"  #include "llviewershadermgr.h"  #include "glod/glod.h" -#include <boost/algorithm/string.hpp> -  const S32 SLM_SUPPORTED_VERSION = 3; @@ -3884,14 +3882,14 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim  	for (LLModelLoader::scene::iterator iter = mBaseScene.begin(), endIter = mBaseScene.end(); iter != endIter; ++iter)  	{  		for (LLModelLoader::model_instance_list::iterator instance = iter->second.begin(), end_instance = iter->second.end(); instance != end_instance; ++instance) -		{ +	{  			LLModel* mdl = instance->mModel;  			if (mdl) -			{ +		{  				instanced_triangle_count += mdl->getNumTriangles();  			}  		} -	} +		}  	//get the triangle count for the non-instanced set of models  	for (U32 i = 0; i < mBaseModel.size(); ++i) @@ -4232,28 +4230,28 @@ void LLModelPreview::updateStatusMessages()  				if (model)  				{  					 //for each model in the lod -					S32 cur_tris = 0; -					S32 cur_verts = 0; +			S32 cur_tris = 0; +			S32 cur_verts = 0;  					S32 cur_submeshes = model->getNumVolumeFaces(); -					for (S32 j = 0; j < cur_submeshes; ++j) -					{ //for each submesh (face), add triangles and vertices to current total +			for (S32 j = 0; j < cur_submeshes; ++j) +			{ //for each submesh (face), add triangles and vertices to current total  						const LLVolumeFace& face = model->getVolumeFace(j); -						cur_tris += face.mNumIndices/3; -						cur_verts += face.mNumVertices; -					} +				cur_tris += face.mNumIndices/3; +				cur_verts += face.mNumVertices; +			} -					//add this model to the lod total -					total_tris[lod] += cur_tris; -					total_verts[lod] += cur_verts; -					total_submeshes[lod] += cur_submeshes; +			//add this model to the lod total +			total_tris[lod] += cur_tris; +			total_verts[lod] += cur_verts; +			total_submeshes[lod] += cur_submeshes; -					//store this model's counts to asset data -					tris[lod].push_back(cur_tris); -					verts[lod].push_back(cur_verts); -					submeshes[lod].push_back(cur_submeshes); -				} -			} +			//store this model's counts to asset data +			tris[lod].push_back(cur_tris); +			verts[lod].push_back(cur_verts); +			submeshes[lod].push_back(cur_submeshes); +		} +	}  		}  	} @@ -4442,28 +4440,28 @@ void LLModelPreview::updateStatusMessages()  			LLModel* model = instance->mModel;  			if (model)  			{ -				S32 cur_submeshes = model->getNumVolumeFaces(); +		S32 cur_submeshes = model->getNumVolumeFaces(); -				LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; +		LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; -				if (!decomp.empty()) -				{ -					phys_hulls += decomp.size(); -					for (U32 i = 0; i < decomp.size(); ++i) -					{ -						phys_points += decomp[i].size(); -					} -				} -				else -				{ //choose physics shape OR decomposition, can't use both -					for (S32 j = 0; j < cur_submeshes; ++j) -					{ //for each submesh (face), add triangles and vertices to current total -						const LLVolumeFace& face = model->getVolumeFace(j); -						phys_tris += face.mNumIndices/3; -					} -				} +		if (!decomp.empty()) +		{ +			phys_hulls += decomp.size(); +			for (U32 i = 0; i < decomp.size(); ++i) +			{ +				phys_points += decomp[i].size();  			}  		} +		else +		{ //choose physics shape OR decomposition, can't use both +			for (S32 j = 0; j < cur_submeshes; ++j) +			{ //for each submesh (face), add triangles and vertices to current total +				const LLVolumeFace& face = model->getVolumeFace(j); +				phys_tris += face.mNumIndices/3; +			} +		} +	} +		}  	}  	if (phys_tris > 0) diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 50c013a49d..bc8a208030 100755 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2545,8 +2545,6 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,  		}  		else  		{ -			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); -  			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||  				LL_ERR_FILE_EMPTY == status)  			{ @@ -2921,7 +2919,7 @@ void LLPanelEnvironmentInfo::onOpen(const LLSD& key)  }  // virtual -void LLPanelEnvironmentInfo::handleVisibilityChange(BOOL new_visibility) +void LLPanelEnvironmentInfo::onVisibilityChange(BOOL new_visibility)  {  	// If hiding (user switched to another tab or closed the floater),  	// display user's preferred environment. diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index f0499f1903..dd961e21b2 100755 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -402,7 +402,7 @@ public:  	/*virtual*/ void onOpen(const LLSD& key);  	// LLView -	/*virtual*/ void handleVisibilityChange(BOOL new_visibility); +	/*virtual*/ void onVisibilityChange(BOOL new_visibility);  	// LLPanelRegionInfo  	/*virtual*/ bool refreshFromRegion(LLViewerRegion* region); diff --git a/indra/newview/llfloatersceneloadstats.cpp b/indra/newview/llfloatersceneloadstats.cpp new file mode 100644 index 0000000000..8aa93eae96 --- /dev/null +++ b/indra/newview/llfloatersceneloadstats.cpp @@ -0,0 +1,40 @@ +/**  + * @file llfloatersceneloadstats.cpp + * @author Richard Nelson + * @brief debug floater for measuring various scene load statistics + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2013, 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 "llfloatersceneloadstats.h" + + +LLFloaterSceneLoadStats::LLFloaterSceneLoadStats( const LLSD& key )  +:	LLFloater(key) +{} + +BOOL LLFloaterSceneLoadStats::postBuild() +{ +	return TRUE; +} diff --git a/indra/llprimitive/llvolumexml.h b/indra/newview/llfloatersceneloadstats.h index 9d4d989475..aa414bf544 100755..100644 --- a/indra/llprimitive/llvolumexml.h +++ b/indra/newview/llfloatersceneloadstats.h @@ -1,10 +1,10 @@  /**  - * @file llvolumexml.h - * @brief LLVolumeXml base class + * @file llfloatersceneloadstats.h + * @brief debug floater for measuring various scene load statistics   *   * $LicenseInfo:firstyear=2001&license=viewerlgpl$   * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2013, 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 @@ -24,22 +24,20 @@   * $/LicenseInfo$   */ -#ifndef LL_LLVOLUMEXML_H -#define LL_LLVOLUMEXML_H +#ifndef LL_FLOATERSCENELOADSTATS_H +#define LL_FLOATERSCENELOADSTATS_H -#include "llvolume.h" -#include "llxmlnode.h" +#include "llfloater.h" -// wrapper class for some volume/message functions -class LLVolumeXml +class LLFloaterSceneLoadStats : public LLFloater  { -public: -	static LLPointer<LLXMLNode> exportProfileParams(const LLProfileParams* params); +	friend class LLFloaterReg; +private: +	LLFloaterSceneLoadStats(const LLSD& key); -	static LLPointer<LLXMLNode> exportPathParams(const LLPathParams* params); +public: +	BOOL postBuild(); -	static LLPointer<LLXMLNode> exportVolumeParams(const LLVolumeParams* params);  }; -#endif // LL_LLVOLUMEXML_H - +#endif // LL_FLOATERSCENELOADSTATS_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index d8d62e5bbb..285f52fcd6 100755 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -478,7 +478,7 @@ void LLSnapshotLivePreview::draw()  		{  			if (mFlashAlpha < 1.f)  			{ -				mFlashAlpha = lerp(mFlashAlpha, 1.f, LLCriticalDamp::getInterpolant(0.02f)); +				mFlashAlpha = lerp(mFlashAlpha, 1.f, LLSmoothInterpolation::getInterpolant(0.02f));  			}  			else  			{ @@ -487,7 +487,7 @@ void LLSnapshotLivePreview::draw()  		}  		else  		{ -			mFlashAlpha = lerp(mFlashAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f)); +			mFlashAlpha = lerp(mFlashAlpha, 0.f, LLSmoothInterpolation::getInterpolant(0.15f));  		}  		// Draw shining animation if appropriate. @@ -992,7 +992,7 @@ void LLSnapshotLivePreview::saveTexture()  		llwarns << "Error encoding snapshot" << llendl;  	} -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT ); +	add(LLStatViewer::SNAPSHOT, 1);  	mDataSize = 0;  } diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp index 47612fe25c..3110d0391f 100755 --- a/indra/newview/llfollowcam.cpp +++ b/indra/newview/llfollowcam.cpp @@ -327,11 +327,11 @@ void LLFollowCam::update()  				F32 force = focusOffsetDistance - focusThresholdNormalizedByDistance;  			*/ -			F32 focusLagLerp = LLCriticalDamp::getInterpolant( mFocusLag ); +			F32 focusLagLerp = LLSmoothInterpolation::getInterpolant( mFocusLag );  			focus_pt_agent = lerp( focus_pt_agent, whereFocusWantsToBe, focusLagLerp );  			mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(focus_pt_agent);  		} -		mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f)); +		mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLSmoothInterpolation::getInterpolant(0.05f));  	}// if focus is not locked --------------------------------------------- @@ -414,7 +414,7 @@ void LLFollowCam::update()  		//-------------------------------------------------------------------------------------------------  		if ( distanceFromPositionToIdealPosition > mPositionThreshold )  		{ -			F32 positionPullLerp = LLCriticalDamp::getInterpolant( mPositionLag ); +			F32 positionPullLerp = LLSmoothInterpolation::getInterpolant( mPositionLag );  			simulated_pos_agent = lerp( simulated_pos_agent, whereCameraPositionWantsToBe, positionPullLerp );  		} @@ -434,7 +434,7 @@ void LLFollowCam::update()  		updateBehindnessConstraint(gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal), simulated_pos_agent);  		mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(simulated_pos_agent); -		mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f)); +		mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLSmoothInterpolation::getInterpolant(0.05f));  	} // if position is not locked ----------------------------------------------------------- @@ -489,7 +489,7 @@ BOOL LLFollowCam::updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_pos  		if ( cameraOffsetAngle > mBehindnessMaxAngle )  		{ -			F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLCriticalDamp::getInterpolant(mBehindnessLag); +			F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLSmoothInterpolation::getInterpolant(mBehindnessLag);  			cam_position = focus + horizontalSubjectBack * (slerp(fraction, camera_offset_rotation, LLQuaternion::DEFAULT));  			cam_position.mV[VZ] = cameraZ; // clamp z value back to what it was before we started messing with it  			constraint_active = TRUE; diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 9aa86297fc..876db96085 100755 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -1139,8 +1139,6 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,  	}  	else  	{ -		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); -  		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||  			LL_ERR_FILE_EMPTY == status)  		{ diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index cbd844cdac..ba4927e622 100755 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -41,6 +41,7 @@  #include "llui.h"  #include "message.h"  #include "roles_constants.h" +#include "llhttpclient.h"  #include "lltransactiontypes.h"  #include "llstatusbar.h"  #include "lleconomy.h" @@ -50,6 +51,7 @@  #include "llnotificationsutil.h"  #include "lluictrlfactory.h"  #include "lltrans.h" +#include "llviewerregion.h"  #include <boost/regex.hpp>  #if LL_MSVC diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 644daa0299..2bbc9c839d 100755 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -28,7 +28,6 @@  #define LL_LLHUDICON_H  #include "llpointer.h" -#include "lldarrayptr.h"  #include "llhudobject.h"  #include "v4color.h" @@ -42,8 +41,6 @@  #include "lldarray.h"  // Renders a 2D icon billboard floating at the location specified. -class LLDrawable; -class LLViewerObject;  class LLViewerTexture;  class LLHUDIcon : public LLHUDObject diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h index 09e79acbfc..effea8f034 100755 --- a/indra/newview/llhudmanager.h +++ b/indra/newview/llhudmanager.h @@ -30,13 +30,9 @@  // Responsible for managing all HUD elements.  #include "llhudobject.h" -#include "lldarrayptr.h" +#include "lldarray.h" -class LLViewerObject;  class LLHUDEffect; -//Ventrella 9/16/05 -class LLHUDAnimalControls; -// End Ventrella  class LLMessageSystem;  class LLHUDManager : public LLSingleton<LLHUDManager> @@ -59,7 +55,7 @@ public:  	static LLColor4 sChildColor;  protected: -	LLDynamicArrayPtr<LLPointer<LLHUDEffect>				> mHUDEffects; +	LLDynamicArray<LLPointer<LLHUDEffect>, 32> mHUDEffects;  };  #endif // LL_LLHUDMANAGER_H diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 3336097955..f43b478f60 100755 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -30,6 +30,7 @@  #include "llhudnametag.h"  #include "llrender.h" +#include "lltracerecording.h"  #include "llagent.h"  #include "llviewercontrol.h" @@ -310,7 +311,7 @@ void LLHUDNameTag::renderText(BOOL for_select)  		label_top_rect.mBottom = label_top_rect.mTop - label_height;  		LLColor4 label_top_color = text_color;  		label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor; - +		  		rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);  	} @@ -737,8 +738,8 @@ void LLHUDNameTag::updateAll()  		current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());  	} -	LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); -	F32 camera_vel = camera_vel_stat->getCurrent(); +	LLTrace::CountStatHandle<>* camera_vel_stat = LLViewerCamera::getVelocityStat(); +	F32 camera_vel = LLTrace::get_frame_recording().getLastRecording().getPerSec(*camera_vel_stat);  	if (camera_vel > MAX_STABLE_CAMERA_VELOCITY)  	{  		return; @@ -806,7 +807,7 @@ void LLHUDNameTag::updateAll()  	VisibleTextObjectIterator this_object_it;  	for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)  	{ -		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC)); +		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLSmoothInterpolation::getInterpolant(POSITION_DAMPING_TC));  	}  } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 2c20409381..c62871236b 100755 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -68,6 +68,7 @@  #include "llviewerparcelmgr.h"  #include "llconversationlog.h"  #include "message.h" +#include "llviewerregion.h"  const static std::string ADHOC_NAME_SUFFIX(" Conference"); @@ -1051,7 +1052,7 @@ const std::string LLIMModel::getName(const LLUUID& session_id) const  {  	LLIMSession* session = findIMSession(session_id); -	if (!session) +	if (!session)   	{  		llwarns << "session " << session_id << "does not exist " << llendl;  		return LLTrans::getString("no_session_message"); @@ -1561,7 +1562,7 @@ public:  	}  	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content) -	{ +	{		  		llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"  				<< statusNum << "]: " << content << llendl;  		//throw something back to the viewer here? @@ -2684,7 +2685,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess  		LLChat chat(message);  		chat.mSourceType = CHAT_SOURCE_SYSTEM; - +		  		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");  		if (nearby_chat)  		{ diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index da6039a3ae..2d036cbc2f 100755 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -33,13 +33,12 @@  #include "lllogchat.h"  #include "llvoicechannel.h" - +#include "lldarray.h"  class LLAvatarName;  class LLFriendObserver;  class LLCallDialogManager;	  class LLIMSpeakerMgr; -  /**   * Timeout Timer for outgoing Ad-Hoc/Group IM sessions which being initialized by the server   */ @@ -557,7 +556,7 @@ public:  			mAvatarNameCacheConnection.disconnect();  		}  	} -	 +  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void onOpen(const LLSD& key); diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 9c6db3676f..ce9f17663c 100755 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -67,7 +67,7 @@ public:  	// Inspector will be positioned relative to current mouse position  	LLInspectAvatar(const LLSD& avatar_id);  	virtual ~LLInspectAvatar(); - +	  	/*virtual*/ BOOL postBuild(void);  	// Because floater is single instance, need to re-parse data on each spawn @@ -83,7 +83,7 @@ private:  	// Make network requests for all the data to display in this view.  	// Used on construction and if avatar id changes.  	void requestUpdate(); - +	  	// Set the volume slider to this user's current client-side volume setting,  	// hiding/disabling if the user is not nearby.  	void updateVolumeSlider(); @@ -221,7 +221,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)  	requestUpdate();  	updateVolumeSlider(); -} +}	  void LLInspectAvatar::requestUpdate()  { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a5043a30ac..d05bdd0a6d 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -70,6 +70,7 @@  #include "llviewermenu.h"  #include "llviewermessage.h"  #include "llviewerobjectlist.h" +#include "llviewerregion.h"  #include "llviewerwindow.h"  #include "llvoavatarself.h"  #include "llwearablelist.h" @@ -3222,7 +3223,7 @@ void LLFolderBridge::pasteFromClipboard()  						LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id);  						llassert(vicat);  						if (vicat) -						{        +						{                              //changeCategoryParent() implicity calls dirtyFilter  							changeCategoryParent(model, vicat, parent_id, FALSE);  						} diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 02a2475cfd..b7c4ec6f8b 100755 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -32,6 +32,7 @@  #include "lldictionary.h"  #include "llinventorydefines.h"  #include "llui.h" +#include "lluiimage.h"  #include "llwearabletype.h"  struct IconEntry : public LLDictionaryEntry @@ -49,6 +50,8 @@ public:  	LLIconDictionary();  }; +typedef LLPointer<LLUIImage> LLUIImagePtr; +  LLIconDictionary::LLIconDictionary()  {  	addEntry(LLInventoryType::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture")); diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index 2197c53bb8..bc09e32087 100755 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -30,7 +30,6 @@  #include "llassettype.h"  #include "llinventorytype.h" -#include "lluiimage.h"  class LLInventoryIcon  { @@ -41,11 +40,11 @@ public:  										  BOOL item_is_multi = FALSE);  	static const std::string& getIconName(LLInventoryType::EIconName idx); -	static LLUIImagePtr getIcon(LLAssetType::EType asset_type, +	static LLPointer<class LLUIImage> getIcon(LLAssetType::EType asset_type,  								LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,  								U32 misc_flag = 0, // different meanings depending on item type  								BOOL item_is_multi = FALSE); -	static LLUIImagePtr getIcon(LLInventoryType::EIconName idx); +	static LLPointer<class LLUIImage> getIcon(LLInventoryType::EIconName idx);  protected:  	static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag); diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 8aac879a93..964adf5e50 100755 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -31,7 +31,7 @@  #include "llfoldertype.h"  #include "lldarray.h"  #include "llframetimer.h" -#include "llhttpclient.h" +#include "llcurl.h"  #include "lluuid.h"  #include "llpermissionsflags.h"  #include "llstring.h" @@ -79,7 +79,7 @@ public:  	typedef LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array_t;  	typedef std::set<LLUUID> changed_items_t; -	class fetchInventoryResponder : public LLHTTPClient::Responder +	class fetchInventoryResponder : public LLCurl::Responder  	{  	public:  		fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {}; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index cf1fd4c0d0..bd3c70b7f5 100755 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -396,9 +396,10 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()  	return getFilter().getShowFolderState();  } +static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); +  void LLInventoryPanel::modelChanged(U32 mask)  { -	static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");  	LLFastTimer t2(FTM_REFRESH);  	if (!mViewsInitialized) return; @@ -733,7 +734,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge  	params.listener = bridge;  	params.rect = LLRect (0, 0, 0, 0);  	params.tool_tip = params.name; - +	  	params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));  	params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor)); diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index dd402de394..2a131eff58 100755 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -141,7 +141,6 @@ void LLLandmarkList::processGetAssetReply(  	}  	else  	{ -		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );  		// SJB: No use case for a notification here. Use lldebugs instead  		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )  		{ diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 25df4889b0..33143b4671 100755 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -48,6 +48,7 @@  /* misc headers */  #include "llscrolllistctrl.h"  #include "llfilepicker.h" +#include "lllocaltextureobject.h"  #include "llviewertexturelist.h"  #include "llviewerobjectlist.h"  #include "llviewerobject.h" diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index 580b6dfa7e..b404345799 100755 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -30,11 +30,11 @@  #include "llavatarappearancedefines.h"  #include "lleventtimer.h" -#include "llimage.h"  #include "llpointer.h"  #include "llwearabletype.h"  class LLScrollListCtrl; +class LLImageRaw;  class LLViewerObject;  class LLLocalBitmap diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index d79f1040bb..9b05c75617 100755 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -240,7 +240,7 @@ void LLManipRotate::render()  		if (mManipPart == LL_ROT_Z)  		{ -			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  			gGL.pushMatrix();  			{  				// selected part @@ -251,7 +251,7 @@ void LLManipRotate::render()  		}  		else if (mManipPart == LL_ROT_Y)  		{ -			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  			gGL.pushMatrix();  			{  				gGL.rotatef( 90.f, 1.f, 0.f, 0.f ); @@ -262,7 +262,7 @@ void LLManipRotate::render()  		}  		else if (mManipPart == LL_ROT_X)  		{ -			mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  			gGL.pushMatrix();  			{  				gGL.rotatef( 90.f, 0.f, 1.f, 0.f ); @@ -273,13 +273,13 @@ void LLManipRotate::render()  		}  		else if (mManipPart == LL_ROT_ROLL)  		{ -			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  		}  		else if (mManipPart == LL_NO_PART)  		{  			if (mHighlightedPart == LL_NO_PART)  			{ -				mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +				mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  			}  			LLGLEnable cull_face(GL_CULL_FACE); @@ -294,7 +294,7 @@ void LLManipRotate::render()  				{  					if (mHighlightedPart == LL_ROT_Z)  					{ -						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, SELECTED_MANIPULATOR_SCALE, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  						gGL.scalef(mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ], mManipulatorScales.mV[VZ]);  						// hovering over part  						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 0.f, 1.f, 1.f ), LLColor4( 0.f, 0.f, 1.f, 0.5f ), CIRCLE_STEPS, i); @@ -312,7 +312,7 @@ void LLManipRotate::render()  					gGL.rotatef( 90.f, 1.f, 0.f, 0.f );  					if (mHighlightedPart == LL_ROT_Y)  					{ -						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +						mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, SELECTED_MANIPULATOR_SCALE, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  						gGL.scalef(mManipulatorScales.mV[VY], mManipulatorScales.mV[VY], mManipulatorScales.mV[VY]);  						// hovering over part  						gl_ring( mRadiusMeters, width_meters, LLColor4( 0.f, 1.f, 0.f, 1.f ), LLColor4( 0.f, 1.f, 0.f, 0.5f ), CIRCLE_STEPS, i); @@ -330,7 +330,7 @@ void LLManipRotate::render()  					gGL.rotatef( 90.f, 0.f, 1.f, 0.f );  					if (mHighlightedPart == LL_ROT_X)  					{ -						mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +						mManipulatorScales = lerp(mManipulatorScales, LLVector4(SELECTED_MANIPULATOR_SCALE, 1.f, 1.f, 1.f), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  						gGL.scalef(mManipulatorScales.mV[VX], mManipulatorScales.mV[VX], mManipulatorScales.mV[VX]);  						// hovering over part @@ -346,7 +346,7 @@ void LLManipRotate::render()  				if (mHighlightedPart == LL_ROT_ROLL)  				{ -					mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +					mManipulatorScales = lerp(mManipulatorScales, LLVector4(1.f, 1.f, 1.f, SELECTED_MANIPULATOR_SCALE), LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  				}  			} diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index ae0884ac5d..15788d6ffd 100755 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -535,11 +535,11 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)  	{  		if (mHighlightedPart == MANIPULATOR_IDS[i])  		{ -			mManipulatorScales[i] = lerp(mManipulatorScales[i], SELECTED_MANIPULATOR_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales[i] = lerp(mManipulatorScales[i], SELECTED_MANIPULATOR_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  		}  		else  		{ -			mManipulatorScales[i] = lerp(mManipulatorScales[i], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE)); +			mManipulatorScales[i] = lerp(mManipulatorScales[i], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE));  		}  	} diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index b62db70ec8..01337cfaed 100755 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1904,18 +1904,18 @@ void LLManipTranslate::renderTranslationHandles()  			{  				if (index == mManipPart - LL_X_ARROW || index == mHighlightedPart - LL_X_ARROW)  				{ -					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); -					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));  				}  				else if (index == mManipPart - LL_YZ_PLANE || index == mHighlightedPart - LL_YZ_PLANE)  				{ -					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); -					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], SELECTED_ARROW_SCALE, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));  				}  				else  				{ -					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); -					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLCriticalDamp::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mArrowScales.mV[index] = lerp(mArrowScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE )); +					mPlaneScales.mV[index] = lerp(mPlaneScales.mV[index], 1.f, LLSmoothInterpolation::getInterpolant(MANIPULATOR_SCALE_HALF_LIFE ));  				}  			} diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 2075aeed63..9298d6952f 100755 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -392,7 +392,7 @@ BOOL LLMediaCtrl::postBuild ()  	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(  		"menu_media_ctrl.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); -	setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2)); +	setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2));  	return TRUE;  } @@ -422,7 +422,7 @@ BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )  ////////////////////////////////////////////////////////////////////////////////  // -void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility ) +void LLMediaCtrl::onVisibilityChange ( BOOL new_visibility )  {  	llinfos << "visibility changed to " << (new_visibility?"true":"false") << llendl;  	if(mMediaSource) @@ -450,7 +450,7 @@ BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)  ////////////////////////////////////////////////////////////////////////////////  // -void LLMediaCtrl::onVisibilityChange ( const LLSD& new_visibility ) +void LLMediaCtrl::onVisibilityChanged ( const LLSD& new_visibility )  {  	// set state of frequent updates automatically if visibility changes  	if ( new_visibility.asBoolean() ) diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 7f2a5e1642..db501cdb8c 100755 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -149,7 +149,7 @@ public:  		// over-rides  		virtual BOOL handleKeyHere( KEY key, MASK mask); -		virtual void handleVisibilityChange ( BOOL new_visibility ); +		virtual void onVisibilityChange ( BOOL new_visibility );  		virtual BOOL handleUnicodeCharHere(llwchar uni_char);  		virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE);  		virtual void draw(); @@ -171,7 +171,7 @@ public:  		void convertInputCoords(S32& x, S32& y);  	private: -		void onVisibilityChange ( const LLSD& new_visibility ); +		void onVisibilityChanged ( const LLSD& new_visibility );  		void onPopup(const LLSD& notification, const LLSD& response);  		const S32 mTextureDepthBytes; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index b47fe9d4b1..55347039ac 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -26,8 +26,7 @@  #include "llviewerprecompiledheaders.h" -#include "apr_pools.h" -#include "apr_dso.h" +#include "llapr.h"  #include "llhttpstatuscodes.h"  #include "llmeshrepository.h" diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index dea90b9042..7cf1d177ac 100755 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -162,7 +162,7 @@ void LLNetMap::draw()  	static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);  	if (auto_center)  	{ -		mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(0.1f)); +		mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));  	}  	// Prepare a scissor region diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 862e4be203..50d0b4256b 100755 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -52,6 +52,7 @@  #include "llfloaterworldmap.h"  #include "llviewergenericmessage.h"	// send_generic_message  #include "llviewerregion.h" +#include "llviewertexture.h"  #include "lltrans.h"  #include "llscrollcontainer.h"  #include "llstatusbar.h" diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index e71dba5cae..a499fa1d87 100755 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -30,6 +30,7 @@  #include "llpanel.h"  #include "llviewerwearable.h"  #include "lluictrl.h" +#include "lllocaltextureobject.h"  #include "llscrollingpanellist.h"  #include "llvisualparam.h"  #include "lltoolmorph.h" diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 445c0d811f..ef5b803f70 100755 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1048,7 +1048,7 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)  void LLPanelFace::onCommitTexture( const LLSD& data )  { -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); +	add(LLStatViewer::EDIT_TEXTURE, 1);  	sendTexture();  } diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index a50d9074f7..74c810ea79 100755 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -202,7 +202,7 @@ void LLPanelNearByMedia::onTopLost()  /*virtual*/  -void LLPanelNearByMedia::handleVisibilityChange ( BOOL new_visibility ) +void LLPanelNearByMedia::onVisibilityChange ( BOOL new_visibility )  {  	if (new_visibility)	  	{ diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h index c3634de9b4..a9c1b190cf 100755 --- a/indra/newview/llpanelnearbymedia.h +++ b/indra/newview/llpanelnearbymedia.h @@ -48,7 +48,7 @@ public:  	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);  	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);  	/*virtual*/ void onTopLost(); -	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); +	/*virtual*/ void onVisibilityChange ( BOOL new_visibility );  	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);  	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index c09d4393c8..7648e12f96 100755 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -169,7 +169,7 @@ public:  		return menu;  	} -	 +  private:  	static void onCreate(const LLSD& param)  	{ @@ -481,7 +481,7 @@ BOOL LLPanelOutfitEdit::postBuild()  	childSetCommitCallback("shop_btn_1", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL);  	childSetCommitCallback("shop_btn_2", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL); -	setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChange, this, _2)); +	setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChanged, this, _2));  	mWearablesGearMenuBtn = getChild<LLMenuButton>("wearables_gear_menu_btn");  	mGearMenuBtn = getChild<LLMenuButton>("gear_menu_btn"); @@ -767,7 +767,7 @@ void LLPanelOutfitEdit::onPlusBtnClicked(void)  	}  } -void LLPanelOutfitEdit::onVisibilityChange(const LLSD &in_visible_chain) +void LLPanelOutfitEdit::onVisibilityChanged(const LLSD &in_visible_chain)  {  	showAddWearablesPanel(false);  	mWearableItemsList->resetSelection(); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 5d4b8d4644..30870daf40 100755 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -145,7 +145,7 @@ public:  	void updatePlusButton();  	void onPlusBtnClicked(void); -	void onVisibilityChange(const LLSD &in_visible_chain); +	void onVisibilityChanged(const LLSD &in_visible_chain);  	void applyFolderViewFilter(EFolderViewItemType type);  	void applyListViewFilter(EListViewItemType type); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 4740964dee..123e2891d6 100755 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -38,6 +38,7 @@ class LLFilterEditor;  class LLGroupList;  class LLMenuButton;  class LLTabContainer; +class LLNetMap;  class LLPanelPeople   	: public LLPanel diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 131e8e9359..79bcf15c1d 100755 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -913,7 +913,6 @@ bool callback_deed_to_group(const LLSD& notification, const LLSD& response)  		if(group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED)))  		{  			LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); -//			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT);  		}  	}  	return false; diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 5d9971c16c..da201ca36a 100755 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -302,9 +302,9 @@ void LLPanelPlaceProfile::processParcelInfo(const LLParcelData& parcel_data)  }  // virtual -void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility) +void LLPanelPlaceProfile::onVisibilityChange(BOOL new_visibility)  { -	LLPanel::handleVisibilityChange(new_visibility); +	LLPanel::onVisibilityChange(new_visibility);  	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();  	if (!parcel_mgr) diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index f4c6145881..01adfd4940 100755 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -38,7 +38,7 @@ class LLPanelPlaceProfile : public LLPanelPlaceInfo  public:  	LLPanelPlaceProfile();  	/*virtual*/ ~LLPanelPlaceProfile(); -	 +  	/*virtual*/ BOOL postBuild();  	/*virtual*/ void resetLocation(); @@ -47,7 +47,7 @@ public:  	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); -	/*virtual*/ void handleVisibilityChange(BOOL new_visibility); +	/*virtual*/ void onVisibilityChange(BOOL new_visibility);  	// Displays information about the currently selected parcel  	// without sending a request to the server. diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 6c2a01fc82..dc18cc6081 100755 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -998,9 +998,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  }  // virtual -void LLPanelPlaces::handleVisibilityChange(BOOL new_visibility) +void LLPanelPlaces::onVisibilityChange(BOOL new_visibility)  { -	LLPanel::handleVisibilityChange(new_visibility); +	LLPanel::onVisibilityChange(new_visibility);  	if (!new_visibility && mPlaceInfoType == AGENT_INFO_TYPE)  	{ diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 85bdc2c4e1..b6019ca32e 100755 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -102,7 +102,7 @@ private:  	void togglePickPanel(BOOL visible);  	void togglePlaceInfoPanel(BOOL visible); -	/*virtual*/ void handleVisibilityChange(BOOL new_visibility); +	/*virtual*/ void onVisibilityChange(BOOL new_visibility);  	void updateVerbs(); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index e2e7006773..435797bf80 100755 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -36,6 +36,7 @@  #include "lltabcontainer.h"  #include "llviewercontrol.h"  #include "llviewernetwork.h" +#include "llweb.h"  static const std::string PANEL_PICKS = "panel_picks"; diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 9dd665198f..3830847d74 100755 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -169,7 +169,7 @@ BOOL LLPanelTopInfoBar::postBuild()  	mParcelMgrConnection = LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(  			boost::bind(&LLPanelTopInfoBar::onAgentParcelChange, this)); -	setVisibleCallback(boost::bind(&LLPanelTopInfoBar::onVisibilityChange, this, _2)); +	setVisibleCallback(boost::bind(&LLPanelTopInfoBar::onVisibilityChanged, this, _2));  	return TRUE;  } @@ -186,7 +186,7 @@ void LLPanelTopInfoBar::onNavBarShowParcelPropertiesCtrlChanged()  // when panel is shown, all minimized floaters should be shifted downwards to prevent overlapping of  // PanelTopInfoBar. See EXT-7951. -void LLPanelTopInfoBar::onVisibilityChange(const LLSD& show) +void LLPanelTopInfoBar::onVisibilityChanged(const LLSD& show)  {  	// this height is used as a vertical offset for ALREADY MINIMIZED floaters  	// when PanelTopInfoBar visibility changes diff --git a/indra/newview/llpaneltopinfobar.h b/indra/newview/llpaneltopinfobar.h index d58d95be90..f37bd9c048 100755 --- a/indra/newview/llpaneltopinfobar.h +++ b/indra/newview/llpaneltopinfobar.h @@ -57,7 +57,7 @@ public:  	/**  	 * Called when the top info bar gets shown or hidden  	 */ -	void onVisibilityChange(const LLSD& show); +	void onVisibilityChanged(const LLSD& show);  	boost::signals2::connection setResizeCallback( const resize_signal_t::slot_type& cb ); diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp index 6be2ea6481..1782afddd9 100755 --- a/indra/newview/llpanelvoicedevicesettings.cpp +++ b/indra/newview/llpanelvoicedevicesettings.cpp @@ -85,7 +85,7 @@ BOOL LLPanelVoiceDeviceSettings::postBuild()  }  // virtual -void LLPanelVoiceDeviceSettings::handleVisibilityChange ( BOOL new_visibility ) +void LLPanelVoiceDeviceSettings::onVisibilityChange ( BOOL new_visibility )  {  	if (new_visibility)  	{ diff --git a/indra/newview/llpanelvoicedevicesettings.h b/indra/newview/llpanelvoicedevicesettings.h index ba3bcad0dc..83464f476a 100755 --- a/indra/newview/llpanelvoicedevicesettings.h +++ b/indra/newview/llpanelvoicedevicesettings.h @@ -44,7 +44,7 @@ public:  	void initialize();  	void cleanup(); -	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); +	/*virtual*/ void onVisibilityChange ( BOOL new_visibility );  	void setUseTuningMode(bool use) { mUseTuningMode = use; }; diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index 5fec6d967d..59ed53815b 100755 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -35,6 +35,7 @@  #include "lltrans.h"  #include "lltransientfloatermgr.h"  #include "llvoiceclient.h" +#include "llweb.h"  static LLRegisterPanelClassWrapper<LLPanelVoiceEffect> t_panel_voice_effect("panel_voice_effect"); diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp index aea7b33d7f..cb00f742cc 100755 --- a/indra/newview/llpanelvolumepulldown.cpp +++ b/indra/newview/llpanelvolumepulldown.cpp @@ -87,7 +87,7 @@ void LLPanelVolumePulldown::onMouseLeave(S32 x, S32 y, MASK mask)  }  /*virtual*/  -void LLPanelVolumePulldown::handleVisibilityChange ( BOOL new_visibility ) +void LLPanelVolumePulldown::onVisibilityChange ( BOOL new_visibility )  {  	if (new_visibility)	  	{ diff --git a/indra/newview/llpanelvolumepulldown.h b/indra/newview/llpanelvolumepulldown.h index 0d86e6bd28..b843fab756 100755 --- a/indra/newview/llpanelvolumepulldown.h +++ b/indra/newview/llpanelvolumepulldown.h @@ -42,7 +42,7 @@ class LLPanelVolumePulldown : public LLPanel  	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);  	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);  	/*virtual*/ void onTopLost(); -	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); +	/*virtual*/ void onVisibilityChange ( BOOL new_visibility );  	/*virtual*/ BOOL postBuild();   private: diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index f47928b131..bda603262d 100755 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -253,7 +253,7 @@ void LLPreviewGesture::onUpdateSucceeded()  	refresh();  } -void LLPreviewGesture::onVisibilityChange ( const LLSD& new_visibility ) +void LLPreviewGesture::onVisibilityChanged ( const LLSD& new_visibility )  {  	if (new_visibility.asBoolean())  	{ @@ -333,7 +333,7 @@ LLPreviewGesture::~LLPreviewGesture()  BOOL LLPreviewGesture::postBuild()  { -	setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChange, this, _2)); +	setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChanged, this, _2));  	LLLineEditor* edit;  	LLComboBox* combo; @@ -883,8 +883,6 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs,  		}  		else  		{ -			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); -  			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||  				LL_ERR_FILE_EMPTY == status)  			{ diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h index fd4fcf9d8f..7ce5706a0d 100755 --- a/indra/newview/llpreviewgesture.h +++ b/indra/newview/llpreviewgesture.h @@ -102,7 +102,7 @@ protected:  	// "Sound", "Chat", or "Wait"  	LLScrollListItem* addStep(const enum EStepType step_type); -	void onVisibilityChange ( const LLSD& new_visibility ); +	void onVisibilityChanged ( const LLSD& new_visibility );  	static std::string getLabel(std::vector<std::string> labels);  	static void updateLabel(LLScrollListItem* item); diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 3a9360fd23..97c9de4b72 100755 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -339,8 +339,6 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,  		}  		else  		{ -			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); -  			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||  				LL_ERR_FILE_EMPTY == status)  			{ diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 968a912ea2..516ecedbc8 100755 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -946,7 +946,7 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata)  void LLScriptEdCore::doSave( BOOL close_after_save )  { -	LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); +	add(LLStatViewer::LSL_SAVES, 1);  	if( mSaveCallback )  	{ @@ -1150,8 +1150,7 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data )  void LLScriptEdCore::onBtnSaveToFile( void* userdata )  { - -	LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); +	add(LLStatViewer::LSL_SAVES, 1);  	LLScriptEdCore* self = (LLScriptEdCore*) userdata; @@ -1674,8 +1673,6 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset  		}  		else  		{ -			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); -  			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||  				LL_ERR_FILE_EMPTY == status)  			{ @@ -1906,8 +1903,6 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,  		}  		else  		{ -			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); -  			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||  				LL_ERR_FILE_EMPTY == status)  			{ diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp new file mode 100644 index 0000000000..dccf8a2a17 --- /dev/null +++ b/indra/newview/llscenemonitor.cpp @@ -0,0 +1,698 @@ +/**  + * @file llscenemonitor.cpp + * @brief monitor the scene loading process. + * + * $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$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llrendertarget.h" +#include "llscenemonitor.h" +#include "llviewerwindow.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h" +#include "llviewershadermgr.h" +#include "llui.h" +#include "llstartup.h" +#include "llappviewer.h" +#include "llwindow.h" +#include "llpointer.h" +#include "llspatialpartition.h" +#include "llagent.h" +#include "pipeline.h" +#include "llviewerpartsim.h" + +LLSceneMonitorView* gSceneMonitorView = NULL; + +// +//The procedures of monitoring when the scene finishes loading visually,  +//i.e., no pixel differences among frames, are: +//1, freeze all dynamic objects and avatars; +//2, (?) disable all sky and water; +//3, capture frames periodically, by calling "capture()"; +//4, compute pixel differences between two latest captured frames, by calling "compare()", results are stored at mDiff; +//5, compute the number of pixels in mDiff above some tolerance threshold in GPU, by calling "calcDiffAggregate()"; +//6, use gl occlusion query to fetch the result from GPU, by calling "fetchQueryResult()"; +//END. +// + +LLSceneMonitor::LLSceneMonitor() :  +	mEnabled(false),  +	mDiff(NULL), +	mDiffResult(0.f), +	mDiffTolerance(0.1f), +	mDiffState(WAITING_FOR_NEXT_DIFF), +	mDebugViewerVisible(false), +	mQueryObject(0), +	mDiffPixelRatio(0.5f) +{ +	mFrames[0] = NULL; +	mFrames[1] = NULL; +} + +LLSceneMonitor::~LLSceneMonitor() +{ +	mDiffState = VIEWER_QUITTING; +	reset(); + +	mDitheringTexture = NULL; +} + +void LLSceneMonitor::reset() +{ +	delete mFrames[0]; +	delete mFrames[1]; +	delete mDiff; + +	mFrames[0] = NULL; +	mFrames[1] = NULL; +	mDiff = NULL; + +	mMonitorRecording.reset(); +	mSceneLoadRecording.reset(); + +	unfreezeScene(); + +	if(mQueryObject > 0) +	{ +		LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(mQueryObject); +		mQueryObject = 0; +	} +} + +void LLSceneMonitor::generateDitheringTexture(S32 width, S32 height) +{ +#if 1 +	//4 * 4 matrix +	mDitherMatrixWidth = 4;	 +	S32 dither_matrix[4][4] =  +	{ +		{1, 9, 3, 11},  +		{13, 5, 15, 7},  +		{4, 12, 2, 10},  +		{16, 8, 14, 6} +	}; +	 +	mDitherScale = 255.f / 17; +#else +	//8 * 8 matrix +	mDitherMatrixWidth = 16;	 +	S32 dither_matrix[16][16] =  +	{ +		{1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64},  +		{33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32},  +		{9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56},  +		{41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24}, +		{3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62}, +		{35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30}, +		{11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54}, +		{43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22}, +		{1, 49, 13, 61, 4, 52, 16, 64, 1, 49, 13, 61, 4, 52, 16, 64},  +		{33, 17, 45, 29, 36, 20, 48, 32, 33, 17, 45, 29, 36, 20, 48, 32},  +		{9, 57, 5, 53, 12, 60, 8, 56, 9, 57, 5, 53, 12, 60, 8, 56},  +		{41, 25, 37, 21, 44, 28, 40, 24, 41, 25, 37, 21, 44, 28, 40, 24}, +		{3, 51, 15, 63, 2, 50, 14, 62, 3, 51, 15, 63, 2, 50, 14, 62}, +		{35, 19, 47, 31, 34, 18, 46, 30, 35, 19, 47, 31, 34, 18, 46, 30}, +		{11, 59, 7, 55, 10, 58, 6, 54, 11, 59, 7, 55, 10, 58, 6, 54}, +		{43, 27, 39, 23, 42, 26, 38, 22, 43, 27, 39, 23, 42, 26, 38, 22} +	}; + +	mDitherScale = 255.f / 65; +#endif + +	LLPointer<LLImageRaw> image_raw = new LLImageRaw(mDitherMatrixWidth, mDitherMatrixWidth, 3); +	U8* data = image_raw->getData(); +	for (S32 i = 0; i < mDitherMatrixWidth; i++) +	{ +		for (S32 j = 0; j < mDitherMatrixWidth; j++) +		{ +			U8 val = dither_matrix[i][j]; +			*data++ = val; +			*data++ = val; +			*data++ = val; +		} +	} + +	mDitheringTexture = LLViewerTextureManager::getLocalTexture(image_raw.get(), FALSE) ; +	mDitheringTexture->setAddressMode(LLTexUnit::TAM_WRAP); +	mDitheringTexture->setFilteringOption(LLTexUnit::TFO_POINT); +	 +	mDitherScaleS = (F32)width / mDitherMatrixWidth; +	mDitherScaleT = (F32)height / mDitherMatrixWidth; +} + +void LLSceneMonitor::setDebugViewerVisible(bool visible)  +{ +	mDebugViewerVisible = visible; +} + +LLRenderTarget& LLSceneMonitor::getCaptureTarget() +{ +	LLRenderTarget* cur_target = NULL; + +	S32 width = gViewerWindow->getWorldViewWidthRaw(); +	S32 height = gViewerWindow->getWorldViewHeightRaw(); +	 +	if(!mFrames[0]) +	{ +		mFrames[0] = new LLRenderTarget(); +		mFrames[0]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true); +		gGL.getTexUnit(0)->bind(mFrames[0]); +		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +		cur_target = mFrames[0]; +	} +	else if(!mFrames[1]) +	{ +		mFrames[1] = new LLRenderTarget(); +		mFrames[1]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true); +		gGL.getTexUnit(0)->bind(mFrames[1]); +		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + +		cur_target = mFrames[1]; +	} +	else //swap +	{ +		cur_target = mFrames[0]; +		mFrames[0] = mFrames[1]; +		mFrames[1] = cur_target; +	} +	 +	if(cur_target->getWidth() != width || cur_target->getHeight() != height) //size changed +	{ +		cur_target->resize(width, height, GL_RGB); +	} + +	// we're promising the target exists +	return *cur_target; +} + +void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp) +{ +	mAvatarPauseHandles.push_back(avatarp->requestPause()); +} + +void LLSceneMonitor::freezeScene() +{ +	//freeze all avatars +	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); +		iter != LLCharacter::sInstances.end(); ++iter) +	{ +		freezeAvatar((LLCharacter*)(*iter)); +	} + +	// freeze everything else +	gSavedSettings.setBOOL("FreezeTime", TRUE); + +	//disable sky, water and clouds +	gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,  +		LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); + +	//disable particle system +	LLViewerPartSim::getInstance()->enable(false); +} + +void LLSceneMonitor::unfreezeScene() +{ +	//thaw all avatars +	mAvatarPauseHandles.clear(); + +	if(mDiffState == VIEWER_QUITTING) +	{ +		return; +	} + +	// thaw everything else +	gSavedSettings.setBOOL("FreezeTime", FALSE); + +	//enable sky, water and clouds +	gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,  +		LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); + +	//enable particle system +	LLViewerPartSim::getInstance()->enable(true); +} + +void LLSceneMonitor::capture() +{ +	static U32 last_capture_time = 0; +	static LLCachedControl<bool> monitor_enabled(gSavedSettings, "SceneLoadingMonitorEnabled"); +	static LLCachedControl<F32>  scene_load_sample_time(gSavedSettings, "SceneLoadingMonitorSampleTime"); +	static LLFrameTimer timer;	 + +	if (mEnabled  +		&&	(mMonitorRecording.getSum(*LLViewerCamera::getVelocityStat()) > 0.1f +			|| mMonitorRecording.getSum(*LLViewerCamera::getAngularVelocityStat()) > 0.05f)) +	{ +		reset(); +		freezeScene(); +	} + +	bool enabled = monitor_enabled || mDebugViewerVisible; +	if(mEnabled != enabled) +	{ +		if(mEnabled) +		{ +			unfreezeScene(); +		} +		else +		{ +			reset(); +			freezeScene(); +		} + +		mEnabled = enabled; +	} + +	if(timer.getElapsedTimeF32() > scene_load_sample_time() +		&& mEnabled +		&& LLGLSLShader::sNoFixedFunction +		&& last_capture_time != gFrameCount) +	{ +		mSceneLoadRecording.resume(); +		mMonitorRecording.resume(); + +		timer.reset(); + +		last_capture_time = gFrameCount; + +		LLRenderTarget& cur_target = getCaptureTarget(); + +		U32 old_FBO = LLRenderTarget::sCurFBO; + +		gGL.getTexUnit(0)->bind(&cur_target); +		glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); //point to the main frame buffer. +		 +		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, cur_target.getWidth(), cur_target.getHeight()); //copy the content +	 +		glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); +		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);		 +		glBindFramebuffer(GL_FRAMEBUFFER, old_FBO); + +		mDiffState = NEED_DIFF; +	} +} + +bool LLSceneMonitor::needsUpdate() const +{ +	return mDiffState == NEED_DIFF; +} + +static LLFastTimer::DeclareTimer FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE("Generate Scene Load Dither Texture"); +static LLFastTimer::DeclareTimer FTM_SCENE_LOAD_IMAGE_DIFF("Scene Load Image Diff"); + +void LLSceneMonitor::compare() +{ +	if(mDiffState != NEED_DIFF) +	{ +		return; +	} + +	if(!mFrames[0] || !mFrames[1]) +	{ +		return; +	} +	if(mFrames[0]->getWidth() != mFrames[1]->getWidth() || mFrames[0]->getHeight() != mFrames[1]->getHeight()) +	{	//size does not match +		return;  +	} + +	LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF); +	mDiffState = EXECUTE_DIFF; + +	S32 width = gViewerWindow->getWindowWidthRaw(); +	S32 height = gViewerWindow->getWindowHeightRaw(); +	if(!mDiff) +	{ +		LLFastTimer _(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE); +		mDiff = new LLRenderTarget(); +		mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true); + +		generateDitheringTexture(width, height); +	} +	else if(mDiff->getWidth() != width || mDiff->getHeight() != height) +	{ +		LLFastTimer _(FTM_GENERATE_SCENE_LOAD_DITHER_TEXTURE); +		mDiff->resize(width, height, GL_RGBA); +		generateDitheringTexture(width, height); +	} + +	mDiff->bindTarget(); +	mDiff->clear(); +	 +	gTwoTextureCompareProgram.bind(); +	 +	gTwoTextureCompareProgram.uniform1f("dither_scale", mDitherScale); +	gTwoTextureCompareProgram.uniform1f("dither_scale_s", mDitherScaleS); +	gTwoTextureCompareProgram.uniform1f("dither_scale_t", mDitherScaleT); + +	gGL.getTexUnit(0)->activate(); +	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(0)->bind(mFrames[0]); +	gGL.getTexUnit(0)->activate(); + +	gGL.getTexUnit(1)->activate(); +	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(1)->bind(mFrames[1]); +	gGL.getTexUnit(1)->activate();	 +	 +	gGL.getTexUnit(2)->activate(); +	gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(2)->bind(mDitheringTexture); +	gGL.getTexUnit(2)->activate();	 + +	gl_rect_2d_simple_tex(width, height); +	 +	mDiff->flush();	 + +	gTwoTextureCompareProgram.unbind(); + +	gGL.getTexUnit(0)->disable(); +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(1)->disable(); +	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); +	gGL.getTexUnit(2)->disable(); +	gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE); + +	if (!mDebugViewerVisible) +	{ +		calcDiffAggregate(); +	} +} + +//calculate Diff aggregate information in GPU, and enable gl occlusion query to capture it. +void LLSceneMonitor::calcDiffAggregate() +{ +	LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF); + +	if(mDiffState != EXECUTE_DIFF && !mDebugViewerVisible) +	{ +		return; +	}	 + +	if(!mQueryObject) +	{ +		mQueryObject = LLOcclusionCullingGroup::getNewOcclusionQueryObjectName(); +	} + +	LLGLDepthTest depth(true, false, GL_ALWAYS); +	if(!mDebugViewerVisible) +	{ +		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); +	} + +	LLGLSLShader* cur_shader = NULL; +	 +	cur_shader = LLGLSLShader::sCurBoundShaderPtr; +	gOneTextureFilterProgram.bind(); +	gOneTextureFilterProgram.uniform1f("tolerance", mDiffTolerance); + +	if(mDiffState == EXECUTE_DIFF) +	{ +		glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject); +	} + +	gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff); + +	if(mDiffState == EXECUTE_DIFF) +	{ +		glEndQueryARB(GL_SAMPLES_PASSED_ARB); +		mDiffState = WAIT_ON_RESULT; +	} +		 +	gOneTextureFilterProgram.unbind(); +	 +	if(cur_shader != NULL) +	{ +		cur_shader->bind(); +	} +	 +	if(!mDebugViewerVisible) +	{ +		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +	}	 +} + +static LLTrace::EventStatHandle<> sFramePixelDiff("FramePixelDifference"); +void LLSceneMonitor::fetchQueryResult() +{ +	LLFastTimer _(FTM_SCENE_LOAD_IMAGE_DIFF); + +	if(mDiffState == WAIT_ON_RESULT) +	{ +		mDiffState = WAITING_FOR_NEXT_DIFF; + +		GLuint available = 0; +		glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available); +		if(available) +		{ +			GLuint count = 0; +			glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_ARB, &count); +	 +			mDiffResult = count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio); //0.5 -> (front face + back face) + +			LL_DEBUGS("SceneMonitor") << "Frame difference: " << std::setprecision(4) << mDiffResult << LL_ENDL; +			record(sFramePixelDiff, mDiffResult); + +			static LLCachedControl<F32> diff_threshold(gSavedSettings,"SceneLoadingPixelDiffThreshold"); +			if(mDiffResult > diff_threshold()) +			{ +				mSceneLoadRecording.extend(); +				llassert(mSceneLoadRecording.getAcceptedRecording().getLastRecording().getSum(LLStatViewer::FPS)); +			} +			else +			{ +				mSceneLoadRecording.getPotentialRecording().nextPeriod(); +				llassert(mSceneLoadRecording.getPotentialRecording().getLastRecording().getSum(LLStatViewer::FPS)); +			} +		} +	} +} + +//dump results to a file _scene_xmonitor_results.csv +void LLSceneMonitor::dumpToFile(std::string file_name) +{	using namespace LLTrace; + +	if (!hasResults()) return; + +	LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL;  + +	std::ofstream os(file_name.c_str()); + +	os << std::setprecision(3); + +	PeriodicRecording& scene_load_recording = mSceneLoadRecording.getAcceptedRecording(); +	const U32 frame_count = scene_load_recording.getNumPeriods(); + +	LLUnit<LLUnits::Seconds, F64> frame_time; + +	os << "Stat"; +	for (S32 frame = 0; frame < frame_count; frame++) +	{ +		frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); +		os << ", " << frame_time.value(); +	} +	os << std::endl; + +	typedef TraceType<CountAccumulator> trace_count; +	for (trace_count::instance_iter it = trace_count::beginInstances(), end_it = trace_count::endInstances(); +		it != end_it; +		++it) +	{ +		std::ostringstream row; +		row << it->getName(); + +		const char* unit_label = it->getUnitLabel(); +		if(unit_label[0]) +		{ +			row << "(" << unit_label << ")"; +		} + +		S32 samples = 0; + +		for (S32 frame = 0; frame < frame_count; frame++) +		{ +			samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it); +			row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getSum(*it); +		} + +		row << std::endl; + +		if (samples > 0) +		{ +			os << row.str(); +		} +	} + +	typedef TraceType<EventAccumulator> trace_event; + +	for (trace_event::instance_iter it = trace_event::beginInstances(), end_it = trace_event::endInstances(); +		it != end_it; +		++it) +	{ +		std::ostringstream row; +		row << it->getName(); + +		const char* unit_label = it->getUnitLabel(); +		if(unit_label[0]) +		{ +			row << "(" << unit_label << ")"; +		} + +		S32 samples = 0; + +		for (S32 frame = 0; frame < frame_count; frame++) +		{ +			samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it); +			row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMean(*it); +		} + +		row << std::endl; + +		if (samples > 0) +		{ +			os << row.str(); +		} +	} + +	typedef TraceType<SampleAccumulator> trace_sample; + +	for (trace_sample::instance_iter it = trace_sample::beginInstances(), end_it = trace_sample::endInstances(); +		it != end_it; +		++it) +	{ +		std::ostringstream row; +		row << it->getName(); + +		const char* unit_label = it->getUnitLabel(); +		if(unit_label[0]) +		{ +			row << "(" << unit_label << ")"; +		} + +		S32 samples = 0; + +		for (S32 frame = 0; frame < frame_count; frame++) +		{ +			samples += scene_load_recording.getPrevRecording(frame_count - frame).getSampleCount(*it); +			row << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMean(*it); +		} + +		row << std::endl; + +		if (samples > 0) +		{ +			os << row.str(); +		} +	} + +	typedef TraceType<MemStatAccumulator> trace_mem; +	for (trace_mem::instance_iter it = trace_mem::beginInstances(), end_it = trace_mem::endInstances(); +		it != end_it; +		++it) +	{ +		os << it->getName() << "(KiB)"; + +		for (S32 frame = 0; frame < frame_count; frame++) +		{ +			os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(*it).as<LLUnits::Kibibytes>().value(); +		} + +		os << std::endl; +	} + +	os.flush(); +	os.close(); +} + +//------------------------------------------------------------------------------------------------------------- +//definition of class LLSceneMonitorView +//------------------------------------------------------------------------------------------------------------- +LLSceneMonitorView::LLSceneMonitorView(const LLRect& rect) +	:	LLFloater(LLSD()) +{ +	setRect(rect); +	setVisible(FALSE); +	 +	setCanMinimize(false); +	setCanClose(true); +} + +void LLSceneMonitorView::onClickCloseBtn() +{ +	setVisible(false);	 +} + +void LLSceneMonitorView::onVisibilityChange(BOOL visible) +{ +	visible = visible && LLGLSLShader::sNoFixedFunction; +	LLSceneMonitor::getInstance()->setDebugViewerVisible(visible); +} + +void LLSceneMonitorView::draw() +{ +	const LLRenderTarget* target = LLSceneMonitor::getInstance()->getDiffTarget(); +	if(!target) +	{ +		return; +	} + +	F32 ratio = LLSceneMonitor::getInstance()->getDiffPixelRatio(); +	S32 height = (S32)(target->getHeight() * ratio); +	S32 width = (S32)(target->getWidth() * ratio); +	 +	LLRect new_rect; +	new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height); +	setRect(new_rect); + +	//draw background +	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); +	 +	LLSceneMonitor::getInstance()->calcDiffAggregate(); + +	//show some texts +	LLColor4 color = LLColor4::white; +	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); + +	S32 lines = 0; +	std::string num_str = llformat("Frame difference: %.6f", LLSceneMonitor::getInstance()->getDiffResult()); +	LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); +	lines++; + +	num_str = llformat("Pixel tolerance: (R+G+B) < %.4f", LLSceneMonitor::getInstance()->getDiffTolerance()); +	LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); +	lines++; + +	num_str = llformat("Sampling time: %.3f seconds", gSavedSettings.getF32("SceneLoadingMonitorSampleTime")); +	LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); +	lines++; + +	num_str = llformat("Scene Loading time: %.3f seconds", (F32)LLSceneMonitor::getInstance()->getRecording()->getAcceptedRecording().getDuration().value()); +	LLFontGL::getFontMonospace()->renderUTF8(num_str, 0, 5, getRect().getHeight() - line_height * lines, color, LLFontGL::LEFT, LLFontGL::TOP); +	lines++; + +	LLView::draw(); +} + diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h new file mode 100644 index 0000000000..6af58b707a --- /dev/null +++ b/indra/newview/llscenemonitor.h @@ -0,0 +1,124 @@ +/**  + * @file llscenemonitor.h + * @brief monitor the process of scene loading + * + * $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$ + */ + +#ifndef LL_LLSCENE_MONITOR_H +#define LL_LLSCENE_MONITOR_H + +#include "llsingleton.h" +#include "llmath.h" +#include "llfloater.h" +#include "llcharacter.h" +#include "lltracerecording.h" + +class LLCharacter; +class LLRenderTarget; +class LLViewerTexture; + +class LLSceneMonitor :  public LLSingleton<LLSceneMonitor> +{ +	LOG_CLASS(LLSceneMonitor); +public: +	LLSceneMonitor(); +	~LLSceneMonitor(); + +	void freezeAvatar(LLCharacter* avatarp); +	void setDebugViewerVisible(bool visible); + +	void capture(); //capture the main frame buffer +	void compare(); //compare the stored two buffers.	 +	void fetchQueryResult(); +	void calcDiffAggregate(); +	void setDiffTolerance(F32 tol) {mDiffTolerance = tol;} + +	const LLRenderTarget* getDiffTarget() const {return mDiff;} +	F32  getDiffTolerance() const {return mDiffTolerance;} +	F32  getDiffResult() const { return mDiffResult;} +	F32  getDiffPixelRatio() const { return mDiffPixelRatio;} +	bool isEnabled()const {return mEnabled;} +	bool needsUpdate() const; +	 +	const LLTrace::ExtendablePeriodicRecording* getRecording() const {return &mSceneLoadRecording;} +	void dumpToFile(std::string file_name); +	bool hasResults() const { return mSceneLoadRecording.getAcceptedRecording().getDuration() != 0;} + +private: +	void freezeScene(); +	void unfreezeScene(); +	void reset(); +	LLRenderTarget& getCaptureTarget(); +	void generateDitheringTexture(S32 width, S32 height); + +private: +	bool mEnabled; +	bool mDebugViewerVisible; + +	enum EDiffState +	{ +		WAITING_FOR_NEXT_DIFF, +		NEED_DIFF, +		EXECUTE_DIFF, +		WAIT_ON_RESULT, +		VIEWER_QUITTING +	}	mDiffState; + +	LLRenderTarget* mFrames[2]; +	LLRenderTarget* mDiff; + +	GLuint  mQueryObject; //used for glQuery +	F32     mDiffResult;  //aggregate results of mDiff. +	F32     mDiffTolerance; //pixels are filtered out when R+G+B < mDiffTolerance + +	F32     mDiffPixelRatio; //ratio of pixels used for comparison against the original mDiff size along one dimension + +	LLPointer<LLViewerTexture> mDitheringTexture; +	S32                        mDitherMatrixWidth; +	F32                        mDitherScale; +	F32                        mDitherScaleS; +	F32                        mDitherScaleT; + +	std::vector<LLAnimPauseRequest> mAvatarPauseHandles; + +	LLTrace::ExtendablePeriodicRecording mSceneLoadRecording; +	LLTrace::Recording					 mMonitorRecording; +}; + +class LLSceneMonitorView : public LLFloater +{ +public: +	LLSceneMonitorView(const LLRect& rect); + +	virtual void draw(); + +	virtual void onVisibilityChange(BOOL visible); + +protected: +	virtual void onClickCloseBtn(); +}; + +extern LLSceneMonitorView* gSceneMonitorView; + +#endif + diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index db57848320..28765fbfb1 100755 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -30,6 +30,7 @@  #include <vector>  #include <openssl/x509.h>  #include <ostream> +#include "llthread.h"  #ifdef LL_WINDOWS  #pragma warning(disable:4250) diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 4681efd3e5..da6ca8964a 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1545,7 +1545,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)  				}  				// apply texture for the selected faces -				LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); +				add(LLStatViewer::EDIT_TEXTURE, 1);  				object->setTEImage(te, image);  				dialog_refresh_all(); @@ -2980,18 +2980,18 @@ private:  void LLSelectMgr::getFirst(LLSelectGetFirstTest* test)  {  	if (gSavedSettings.getBOOL("EditLinkedParts")) -	{ +{  		for (LLObjectSelection::valid_iterator iter = getSelection()->valid_begin();  			iter != getSelection()->valid_end(); ++iter ) -		{ +	{  			if (!test->checkMatchingNode(*iter)) -			{ +		{  				break;  			}  		} -	} -	else -	{ +		} +		else +		{  		for (LLObjectSelection::root_object_iterator iter = getSelection()->root_object_begin();  			iter != getSelection()->root_object_end(); ++iter )  		{ @@ -3001,31 +3001,31 @@ void LLSelectMgr::getFirst(LLSelectGetFirstTest* test)  			}  		}  	} -} +	}  //-----------------------------------------------------------------------------  // selectGetCreator()  // Creator information only applies to roots unless editing linked parts.  //-----------------------------------------------------------------------------  struct LLSelectGetFirstCreator : public LLSelectGetFirstTest -{ +	{  protected:  	virtual const LLUUID& getValueFromNode(LLSelectNode* node) -	{ +		{  		return node->mPermissions->getCreator(); -	} +		}  };  BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name) -{ +		{  	LLSelectGetFirstCreator test;  	getFirst(&test);  	if (test.mFirstValue.isNull()) -	{ -		name = LLTrans::getString("AvatarNameNobody"); +		{ +			name = LLTrans::getString("AvatarNameNobody");  		return FALSE; -	} +		}  	result_id = test.mFirstValue; @@ -3046,18 +3046,18 @@ BOOL LLSelectMgr::selectGetCreator(LLUUID& result_id, std::string& name)  // Owner information only applies to roots unless editing linked parts.  //-----------------------------------------------------------------------------  struct LLSelectGetFirstOwner : public LLSelectGetFirstTest -{ +	{  protected:  	virtual const LLUUID& getValueFromNode(LLSelectNode* node) -	{ +		{  		// Don't use 'getOwnership' since we return a reference, not a copy.  		// Will return LLUUID::null if unowned (which is not allowed and should never happen.)  		return node->mPermissions->isGroupOwned() ? node->mPermissions->getGroup() : node->mPermissions->getOwner(); -	} +		}  };  BOOL LLSelectMgr::selectGetOwner(LLUUID& result_id, std::string& name) -{ +		{  	LLSelectGetFirstOwner test;  	getFirst(&test); @@ -3096,34 +3096,34 @@ struct LLSelectGetFirstLastOwner : public LLSelectGetFirstTest  {  protected:  	virtual const LLUUID& getValueFromNode(LLSelectNode* node) -	{ +{  		return node->mPermissions->getLastOwner();  	}  };  BOOL LLSelectMgr::selectGetLastOwner(LLUUID& result_id, std::string& name) -{ +	{  	LLSelectGetFirstLastOwner test;  	getFirst(&test);  	if (test.mFirstValue.isNull()) -	{ -		return FALSE; -	} +		{ +			return FALSE; +		}  	result_id = test.mFirstValue;  	if (test.mIdentical) -	{ +		{  		name = LLSLURL("agent", test.mFirstValue, "inspect").getSLURLString(); -	} -	else -	{ +		} +		else +		{  		name.assign( "" ); -	} +			}  	return test.mIdentical; -} +		}  //-----------------------------------------------------------------------------  // selectGetGroup() @@ -3153,10 +3153,10 @@ BOOL LLSelectMgr::selectGetGroup(LLUUID& result_id)  // Returns TRUE if the first selected is group owned.  //-----------------------------------------------------------------------------  struct LLSelectGetFirstGroupOwner : public LLSelectGetFirstTest -{ +	{  protected:  	virtual const LLUUID& getValueFromNode(LLSelectNode* node) -	{ +		{  		if (node->mPermissions->isGroupOwned())  		{  			return node->mPermissions->getGroup(); @@ -3412,9 +3412,7 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response,  			gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);  			// Keep track of how many objects have been deleted. -			F64 obj_delete_count = LLViewerStats::getInstance()->getStat(LLViewerStats::ST_OBJECT_DELETE_COUNT); -			obj_delete_count += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount(); -			LLViewerStats::getInstance()->setStat(LLViewerStats::ST_OBJECT_DELETE_COUNT, obj_delete_count ); +			add(LLStatViewer::DELETE_OBJECT, LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount());  		}  		break;  	case 1: diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 74fa5a87bb..efef422bfb 100755 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -142,7 +142,7 @@ BOOL LLSidepanelAppearance::postBuild()  	mCurrOutfitPanel = getChild<LLPanel>("panel_currentlook"); -	setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChange,this,_2)); +	setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChanged,this,_2));  	return TRUE;  } @@ -181,7 +181,7 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)  	mOpened = true;  } -void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility) +void LLSidepanelAppearance::onVisibilityChanged(const LLSD &new_visibility)  {  	LLSD visibility;  	visibility["visible"] = new_visibility.asBoolean(); @@ -231,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)  		{  			gAgentCamera.changeCameraToDefault();  			gAgentCamera.resetView(); -		}	 +		}  	}  } diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 762f557a80..6359d6e86e 100755 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -47,7 +47,7 @@ public:  	virtual ~LLSidepanelAppearance();  	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void onOpen(const LLSD& key);	 +	/*virtual*/ void onOpen(const LLSD& key);  	void refreshCurrentOutfitName(const std::string& name = ""); @@ -68,7 +68,7 @@ public:  private:  	void onFilterEdit(const std::string& search_string); -	void onVisibilityChange ( const LLSD& new_visibility ); +	void onVisibilityChanged ( const LLSD& new_visibility );  	void onOpenOutfitButtonClicked();  	void onEditAppearanceButtonClicked(); diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index ad7c939728..090ee64801 100755 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -162,7 +162,7 @@ BOOL LLSidepanelTaskInfo::postBuild()  	return TRUE;  } -/*virtual*/ void LLSidepanelTaskInfo::handleVisibilityChange ( BOOL visible ) +/*virtual*/ void LLSidepanelTaskInfo::onVisibilityChange ( BOOL visible )  {  	if (visible)  	{ @@ -945,7 +945,6 @@ static bool callback_deed_to_group(const LLSD& notification, const LLSD& respons  		if (group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED)))  		{  			LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); -//			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT);  		}  	}  	return FALSE; diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h index 05edcda5ed..a1479ef0e7 100755 --- a/indra/newview/llsidepaneltaskinfo.h +++ b/indra/newview/llsidepaneltaskinfo.h @@ -50,7 +50,7 @@ public:  	virtual ~LLSidepanelTaskInfo();  	/*virtual*/	BOOL postBuild(); -	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); +	/*virtual*/ void onVisibilityChange ( BOOL new_visibility );  	void setObjectSelection(LLObjectSelectionHandle selection); diff --git a/indra/newview/llsimplestat.h b/indra/newview/llsimplestat.h index 9d7780c4f9..80ce99b774 100755 --- a/indra/newview/llsimplestat.h +++ b/indra/newview/llsimplestat.h @@ -99,43 +99,43 @@ public:  	 * values back to zero.  	 */  	void reset() -		{ -			mCount = 0; -			mMin = Value(0); -			mMax = Value(0); -			mTotal = Value(0); -		} +	{ +		mCount = 0; +		mMin = Value(0); +		mMax = Value(0); +		mTotal = Value(0); +	}  	void record(Value v) +	{ +		if (mCount) +		{ +			mMin = llmin(mMin, v); +			mMax = llmax(mMax, v); +		} +		else  		{ -			if (mCount) -			{ -				mMin = llmin(mMin, v); -				mMax = llmax(mMax, v); -			} -			else -			{ -				mMin = v; -				mMax = v; -			} -			mTotal += v; -			++mCount; +			mMin = v; +			mMax = v;  		} +		mTotal += v; +		++mCount; +	}  	void merge(const LLSimpleStatMMM<VALUE_T> & src) +	{ +		if (! mCount) +		{ +			*this = src; +		} +		else if (src.mCount)  		{ -			if (! mCount) -			{ -				*this = src; -			} -			else if (src.mCount) -			{ -				mMin = llmin(mMin, src.mMin); -				mMax = llmax(mMax, src.mMax); -				mCount += src.mCount; -				mTotal += src.mTotal; -			} +			mMin = llmin(mMin, src.mMin); +			mMax = llmax(mMax, src.mMax); +			mCount += src.mCount; +			mTotal += src.mTotal;  		} +	}  	inline U32 getCount() const		{ return mCount; }  	inline Value getMin() const		{ return mMin; } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index f85e855fd3..45130efeb9 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -51,32 +51,16 @@  #include "llvoavatar.h"  #include "llvolumemgr.h"  #include "lltextureatlas.h" -#include "llglslshader.h"  #include "llviewershadermgr.h"  static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling");  static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition"); -const F32 SG_OCCLUSION_FUDGE = 0.25f; -#define SG_DISCARD_TOLERANCE 0.01f - -#if LL_OCTREE_PARANOIA_CHECK -#define assert_octree_valid(x) x->validate() -#define assert_states_valid(x) ((LLSpatialGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() -#else -#define assert_octree_valid(x) -#define assert_states_valid(x) -#endif -  extern bool gShiftFrame;  static U32 sZombieGroups = 0;  U32 LLSpatialGroup::sNodeCount = 0; -#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 - -std::set<GLuint> LLSpatialGroup::sPendingQueries; -  U32 gOctreeMaxCapacity;  BOOL LLSpatialGroup::sNoDelete = FALSE; @@ -84,47 +68,6 @@ BOOL LLSpatialGroup::sNoDelete = FALSE;  static F32 sLastMaxTexPriority = 1.f;  static F32 sCurMaxTexPriority = 1.f; -class LLOcclusionQueryPool : public LLGLNamePool -{ -public: -	LLOcclusionQueryPool() -	{ -		mCurQuery = 1; -	} - -protected: - -	std::list<GLuint> mAvailableName; -	GLuint mCurQuery; -		 -	virtual GLuint allocateName() -	{ -		GLuint ret = 0; - -		if (!mAvailableName.empty()) -		{ -			ret = mAvailableName.front(); -			mAvailableName.pop_front(); -		} -		else -		{ -			ret = mCurQuery++; -		} - -		return ret; -	} - -	virtual void releaseName(GLuint name) -	{ -#if LL_TRACK_PENDING_OCCLUSION_QUERIES -		LLSpatialGroup::sPendingQueries.erase(name); -#endif -		llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); -		mAvailableName.push_back(name); -	} -}; - -static LLOcclusionQueryPool sQueryPool;  //static counter for frame to switch LOD on @@ -138,185 +81,6 @@ void sg_assert(BOOL expr)  #endif  } -S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) -{ -	return AABBSphereIntersectR2(min, max, origin, rad*rad); -} - -S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r) -{ -	F32 d = 0.f; -	F32 t; -	 -	if ((min-origin).magVecSquared() < r && -		(max-origin).magVecSquared() < r) -	{ -		return 2; -	} - -	for (U32 i = 0; i < 3; i++) -	{ -		if (origin.mV[i] < min.mV[i]) -		{ -			t = min.mV[i] - origin.mV[i]; -			d += t*t; -		} -		else if (origin.mV[i] > max.mV[i]) -		{ -			t = origin.mV[i] - max.mV[i]; -			d += t*t; -		} - -		if (d > r) -		{ -			return 0; -		} -	} - -	return 1; -} - - -S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) -{ -	return AABBSphereIntersectR2(min, max, origin, rad*rad); -} - -S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) -{ -	F32 d = 0.f; -	F32 t; -	 -	LLVector4a origina; -	origina.load3(origin.mV); - -	LLVector4a v; -	v.setSub(min, origina); -	 -	if (v.dot3(v) < r) -	{ -		v.setSub(max, origina); -		if (v.dot3(v) < r) -		{ -			return 2; -		} -	} - - -	for (U32 i = 0; i < 3; i++) -	{ -		if (origin.mV[i] < min[i]) -		{ -			t = min[i] - origin.mV[i]; -			d += t*t; -		} -		else if (origin.mV[i] > max[i]) -		{ -			t = origin.mV[i] - max[i]; -			d += t*t; -		} - -		if (d > r) -		{ -			return 0; -		} -	} - -	return 1; -} - - -typedef enum -{ -	b000 = 0x00, -	b001 = 0x01, -	b010 = 0x02, -	b011 = 0x03, -	b100 = 0x04, -	b101 = 0x05, -	b110 = 0x06, -	b111 = 0x07, -} eLoveTheBits; - -//contact Runitai Linden for a copy of the SL object used to write this table -//basically, you give the table a bitmask of the look-at vector to a node and it -//gives you a triangle fan index array -static U16 sOcclusionIndices[] = -{ -	 //000 -		b111, b110, b010, b011, b001, b101, b100, b110, -	 //001  -		b011, b010, b000, b001, b101, b111, b110, b010, -	 //010 -		b101, b100, b110, b111, b011, b001, b000, b100, -	 //011  -		b001, b000, b100, b101, b111, b011, b010, b000, -	 //100  -		b110, b000, b010, b011, b111, b101, b100, b000, -	 //101  -		b010, b100, b000, b001, b011, b111, b110, b100, -	 //110 -		b100, b010, b110, b111, b101, b001, b000, b010, -	 //111 -		b000, b110, b100, b101, b001, b011, b010, b110, -}; - -U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) -{ -	LLVector4a origin; -	origin.load3(camera->getOrigin().mV); - -	S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; -	 -	return cypher*8; -} - -U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) -{ -	LLVector4a origin; -	origin.load3(camera->getOrigin().mV); - -	S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; -	 -	return (U8*) (sOcclusionIndices+cypher*8); -} - -//create a vertex buffer for efficiently rendering cubes -LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) -{ -	LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); - -	ret->allocateBuffer(8, 64, true); - -	LLStrider<LLVector3> pos; -	LLStrider<U16> idx; - -	ret->getVertexStrider(pos); -	ret->getIndexStrider(idx); - -	pos[0] = LLVector3(-1,-1,-1); -	pos[1] = LLVector3(-1,-1, 1); -	pos[2] = LLVector3(-1, 1,-1); -	pos[3] = LLVector3(-1, 1, 1); -	pos[4] = LLVector3( 1,-1,-1); -	pos[5] = LLVector3( 1,-1, 1); -	pos[6] = LLVector3( 1, 1,-1); -	pos[7] = LLVector3( 1, 1, 1); - -	for (U32 i = 0; i < 64; i++) -	{ -		idx[i] = sOcclusionIndices[i]; -	} - -	ret->flush(); - -	return ret; -} - -static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); - -BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group); -  //returns:  //	0 if sphere and AABB are not intersecting   //	1 if they are @@ -358,24 +122,13 @@ LLSpatialGroup::~LLSpatialGroup()  		gPipeline.checkReferences(this);  	} -	if (isState(DEAD)) +	if (hasState(DEAD))  	{  		sZombieGroups--;  	}  	sNodeCount--; -	if (gGLManager.mHasOcclusionQuery) -	{ -		for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) -		{ -			if (mOcclusionQuery[i]) -			{ -				sQueryPool.release(mOcclusionQuery[i]); -			} -		} -	} -  	clearDrawMap();  	clearAtlasList() ;  } @@ -509,22 +262,13 @@ void LLSpatialGroup::clearDrawMap()  BOOL LLSpatialGroup::isHUDGroup()   { -	return mSpatialPartition && mSpatialPartition->isHUDPartition() ;  +	return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ;   }  BOOL LLSpatialGroup::isRecentlyVisible() const  { -	return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < LLDrawable::getMinVisFrameRange() ; -} - -BOOL LLSpatialGroup::isVisible() const -{ -	return mVisible[LLViewerCamera::sCurCameraID] >= LLDrawable::getCurrentFrame() ? TRUE : FALSE; -} - -void LLSpatialGroup::setVisible() -{ -	mVisible[LLViewerCamera::sCurCameraID] = LLDrawable::getCurrentFrame(); +	const S32 MIN_VIS_FRAME_RANGE = 2; +	return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ;  }  void LLSpatialGroup::validate() @@ -548,7 +292,7 @@ void LLSpatialGroup::validate()  		sg_assert(drawable->getSpatialGroup() == this);  		if (drawable->getSpatialBridge())  		{ -			sg_assert(drawable->getSpatialBridge() == mSpatialPartition->asBridge()); +			sg_assert(drawable->getSpatialBridge() == getSpatialPartition()->asBridge());  		}  		/*if (drawable->isSpatialBridge()) @@ -588,14 +332,6 @@ void LLSpatialGroup::validate()  #endif  } -void LLSpatialGroup::checkStates() -{ -#if LL_OCTREE_PARANOIA_CHECK -	//LLOctreeStateCheck checker; -	//checker.traverse(mOctreeNode); -#endif -} -  void LLSpatialGroup::validateDrawMap()  {  #if LL_OCTREE_PARANOIA_CHECK @@ -619,7 +355,7 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)  	OctreeNode* parent = mOctreeNode->getOctParent();  	if (mOctreeNode->isInside(drawablep->getPositionGroup()) &&  -		(mOctreeNode->contains(drawablep) || +		(mOctreeNode->contains(drawablep->getEntry()) ||  		 (drawablep->getBinRadius() > mOctreeNode->getSize()[0] &&  				parent && parent->getElementCount() >= gOctreeMaxCapacity)))  	{ @@ -633,15 +369,14 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)  } -BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_octree) +BOOL LLSpatialGroup::addObject(LLDrawable *drawablep)  { -	if (!from_octree) +	if(!drawablep)  	{ -		mOctreeNode->insert(drawablep); +		return FALSE;  	} -	else  	{ -		drawablep->setSpatialGroup(this); +		drawablep->setGroup(this);  		setState(OBJECT_DIRTY | GEOM_DIRTY);  		setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);  		gPipeline.markRebuild(this, TRUE); @@ -662,9 +397,9 @@ void LLSpatialGroup::rebuildGeom()  {  	if (!isDead())  	{ -		mSpatialPartition->rebuildGeom(this); +		getSpatialPartition()->rebuildGeom(this); -		if (isState(LLSpatialGroup::MESH_DIRTY)) +		if (hasState(LLSpatialGroup::MESH_DIRTY))  		{  			gPipeline.markMeshDirty(this);  		} @@ -675,7 +410,7 @@ void LLSpatialGroup::rebuildMesh()  {  	if (!isDead())  	{ -		mSpatialPartition->rebuildMesh(this); +		getSpatialPartition()->rebuildMesh(this);  	}  } @@ -686,7 +421,7 @@ static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry");  void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)  { -	if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) +	if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))  	{  		return;  	} @@ -751,137 +486,26 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group)  } -BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) +LLSpatialGroup* LLSpatialGroup::getParent()  {	 -	const OctreeNode* node = mOctreeNode; - -	if (node->isEmpty()) -	{	//don't do anything if there are no objects -		if (empty && mOctreeNode->getParent()) -		{	//only root is allowed to be empty -			OCT_ERRS << "Empty leaf found in octree." << llendl; -		} -		return FALSE; -	} - -	LLVector4a& newMin = mObjectExtents[0]; -	LLVector4a& newMax = mObjectExtents[1]; -	 -	if (isState(OBJECT_DIRTY)) -	{ //calculate new bounding box -		clearState(OBJECT_DIRTY); - -		//initialize bounding box to first element -		OctreeNode::const_element_iter i = node->getDataBegin(); -		LLDrawable* drawablep = *i; -		const LLVector4a* minMax = drawablep->getSpatialExtents(); - -		newMin = minMax[0]; -		newMax = minMax[1]; - -		for (++i; i != node->getDataEnd(); ++i) -		{ -			drawablep = *i; -			minMax = drawablep->getSpatialExtents(); -			 -			update_min_max(newMin, newMax, minMax[0]); -			update_min_max(newMin, newMax, minMax[1]); - -			//bin up the object -			/*for (U32 i = 0; i < 3; i++) -			{ -				if (minMax[0].mV[i] < newMin.mV[i]) -				{ -					newMin.mV[i] = minMax[0].mV[i]; -				} -				if (minMax[1].mV[i] > newMax.mV[i]) -				{ -					newMax.mV[i] = minMax[1].mV[i]; -				} -			}*/ -		} -		 -		mObjectBounds[0].setAdd(newMin, newMax); -		mObjectBounds[0].mul(0.5f); -		mObjectBounds[1].setSub(newMax, newMin); -		mObjectBounds[1].mul(0.5f); -	} -	 -	if (empty) -	{ -		minOut = newMin; -		maxOut = newMax; -	} -	else -	{ -		minOut.setMin(minOut, newMin); -		maxOut.setMax(maxOut, newMax); -	} -		 -	return TRUE; +	return (LLSpatialGroup*)LLviewerOctreeGroup::getParent();  } -void LLSpatialGroup::unbound() -{ -	if (isState(DIRTY)) -	{ -		return; -	} - -	setState(DIRTY); -	 -	//all the parent nodes need to rebound this child -	if (mOctreeNode) -	{ -		OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent(); -		while (parent != NULL) -		{ -			LLSpatialGroup* group = (LLSpatialGroup*) parent->getListener(0); -			if (group->isState(DIRTY)) -			{ -				return; -			} -			 -			group->setState(DIRTY); -			parent = (OctreeNode*) parent->getParent(); -		} -	} -} - -LLSpatialGroup* LLSpatialGroup::getParent() +BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)  { -	if (isDead()) +	if(!drawablep)  	{ -		return NULL; -	} - -	if(!mOctreeNode) -	{ -		return NULL; -	} -	OctreeNode* parent = mOctreeNode->getOctParent(); - -	if (parent) -	{ -		return (LLSpatialGroup*) parent->getListener(0); +		return FALSE;  	} -	return NULL; -} - -BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) -{  	unbound();  	if (mOctreeNode && !from_octree)  	{ -		if (!mOctreeNode->remove(drawablep)) -		{ -			OCT_ERRS << "Could not remove drawable from spatial group" << llendl; -		} +		drawablep->setGroup(NULL);  	}  	else  	{ -		drawablep->setSpatialGroup(NULL); +		drawablep->setGroup(NULL);  		setState(GEOM_DIRTY);  		gPipeline.markRebuild(this, TRUE); @@ -918,22 +542,22 @@ void LLSpatialGroup::shift(const LLVector4a &offset)  	mObjectExtents[0].add(offset);  	mObjectExtents[1].add(offset); -	if (!mSpatialPartition->mRenderByGroup &&  -		mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE && -		mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && -		mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE) +	if (!getSpatialPartition()->mRenderByGroup &&  +		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TREE && +		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_TERRAIN && +		getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_BRIDGE)  	{  		setState(GEOM_DIRTY);  		gPipeline.markRebuild(this, TRUE);  	}  } -class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler +class LLSpatialSetState : public OctreeTraveler  {  public:  	U32 mState;  	LLSpatialSetState(U32 state) : mState(state) { } -	virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); }	 +	virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); }	  };  class LLSpatialSetStateDiff : public LLSpatialSetState @@ -941,24 +565,17 @@ class LLSpatialSetStateDiff : public LLSpatialSetState  public:  	LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } -	virtual void traverse(const LLSpatialGroup::OctreeNode* n) +	virtual void traverse(const OctreeNode* n)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); -		if (!group->isState(mState)) +		if (!group->hasState(mState))  		{ -			LLSpatialGroup::OctreeTraveler::traverse(n); +			OctreeTraveler::traverse(n);  		}  	}  }; -void LLSpatialGroup::setState(U32 state)  -{  -	mState |= state;  -	 -	llassert(state <= LLSpatialGroup::STATE_MASK); -}	 -  void LLSpatialGroup::setState(U32 state, S32 mode)   {  	llassert(state <= LLSpatialGroup::STATE_MASK); @@ -982,12 +599,12 @@ void LLSpatialGroup::setState(U32 state, S32 mode)  	}  } -class LLSpatialClearState : public LLSpatialGroup::OctreeTraveler +class LLSpatialClearState : public OctreeTraveler  {  public:  	U32 mState;  	LLSpatialClearState(U32 state) : mState(state) { } -	virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } +	virtual void visit(const OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); }  };  class LLSpatialClearStateDiff : public LLSpatialClearState @@ -995,24 +612,17 @@ class LLSpatialClearStateDiff : public LLSpatialClearState  public:  	LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } -	virtual void traverse(const LLSpatialGroup::OctreeNode* n) +	virtual void traverse(const OctreeNode* n)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); -		if (group->isState(mState)) +		if (group->hasState(mState))  		{ -			LLSpatialGroup::OctreeTraveler::traverse(n); +			OctreeTraveler::traverse(n);  		}  	}  }; -void LLSpatialGroup::clearState(U32 state) -{ -	llassert(state <= LLSpatialGroup::STATE_MASK); - -	mState &= ~state;  -} -  void LLSpatialGroup::clearState(U32 state, S32 mode)  {  	llassert(state <= LLSpatialGroup::STATE_MASK); @@ -1036,144 +646,15 @@ void LLSpatialGroup::clearState(U32 state, S32 mode)  	}  } -BOOL LLSpatialGroup::isState(U32 state) const -{  -	llassert(state <= LLSpatialGroup::STATE_MASK); - -	return mState & state ? TRUE : FALSE;  -} - -//===================================== -//		Occlusion State Set/Clear -//===================================== -class LLSpatialSetOcclusionState : public LLSpatialGroup::OctreeTraveler -{ -public: -	U32 mState; -	LLSpatialSetOcclusionState(U32 state) : mState(state) { } -	virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); }	 -}; - -class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState -{ -public: -	LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } - -	virtual void traverse(const LLSpatialGroup::OctreeNode* n) -	{ -		LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); -		 -		if (!group->isOcclusionState(mState)) -		{ -			LLSpatialGroup::OctreeTraveler::traverse(n); -		} -	} -}; - - -void LLSpatialGroup::setOcclusionState(U32 state, S32 mode)  -{ -	if (mode > STATE_MODE_SINGLE) -	{ -		if (mode == STATE_MODE_DIFF) -		{ -			LLSpatialSetOcclusionStateDiff setter(state); -			setter.traverse(mOctreeNode); -		} -		else if (mode == STATE_MODE_BRANCH) -		{ -			LLSpatialSetOcclusionState setter(state); -			setter.traverse(mOctreeNode); -		} -		else -		{ -			for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) -			{ -				mOcclusionState[i] |= state; - -				if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) -				{ -					sQueryPool.release(mOcclusionQuery[i]); -					mOcclusionQuery[i] = 0; -				} -			} -		} -	} -	else -	{ -		mOcclusionState[LLViewerCamera::sCurCameraID] |= state; -		if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) -		{ -			sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -			mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; -		} -	} -} - -class LLSpatialClearOcclusionState : public LLSpatialGroup::OctreeTraveler -{ -public: -	U32 mState; -	 -	LLSpatialClearOcclusionState(U32 state) : mState(state) { } -	virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } -}; - -class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState -{ -public: -	LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } - -	virtual void traverse(const LLSpatialGroup::OctreeNode* n) -	{ -		LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); -		 -		if (group->isOcclusionState(mState)) -		{ -			LLSpatialGroup::OctreeTraveler::traverse(n); -		} -	} -}; - -void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode) -{ -	if (mode > STATE_MODE_SINGLE) -	{ -		if (mode == STATE_MODE_DIFF) -		{ -			LLSpatialClearOcclusionStateDiff clearer(state); -			clearer.traverse(mOctreeNode); -		} -		else if (mode == STATE_MODE_BRANCH) -		{ -			LLSpatialClearOcclusionState clearer(state); -			clearer.traverse(mOctreeNode); -		} -		else -		{ -			for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) -			{ -				mOcclusionState[i] &= ~state; -			} -		} -	} -	else -	{ -		mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; -	} -}  //======================================  //		Octree Listener Implementation  //====================================== -LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : +LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLOcclusionCullingGroup(node, part),  	mObjectBoxSize(1.f), -	mState(0),  	mGeometryBytes(0),  	mSurfaceArea(0.f),  	mBuilt(0.f), -	mOctreeNode(node), -	mSpatialPartition(part),  	mVertexBuffer(NULL),   	mBufferUsage(part->mBufferUsage),  	mDistance(0.f), @@ -1191,32 +672,11 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :  	mViewAngle.splat(0.f);  	mLastUpdateViewAngle.splat(-1.f); -	mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =  -		mObjectExtents[0] = mObjectExtents[1] = mViewAngle;  	sg_assert(mOctreeNode->getListenerCount() == 0); -	mOctreeNode->addListener(this);  	setState(SG_INITIAL_STATE_MASK);  	gPipeline.markRebuild(this, TRUE); -	mBounds[0] = node->getCenter(); -	mBounds[1] = node->getSize(); - -	part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; -	mLODHash = part->mLODSeed; - -	OctreeNode* oct_parent = node->getOctParent(); - -	LLSpatialGroup* parent = oct_parent ? (LLSpatialGroup*) oct_parent->getListener(0) : NULL; - -	for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) -	{ -		mOcclusionQuery[i] = 0; -		mOcclusionIssued[i] = 0; -		mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; -		mVisible[i] = 0; -	} -  	mRadius = 1;  	mPixelArea = 1024.f;  } @@ -1235,17 +695,17 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)  	}  #if !LL_RELEASE_FOR_DOWNLOAD -	if (isState(LLSpatialGroup::OBJECT_DIRTY)) +	if (hasState(LLSpatialGroup::OBJECT_DIRTY))  	{  		llerrs << "Spatial group dirty on distance update." << llendl;  	}  #endif  	if (!isEmpty())  	{ -		mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : +		mRadius = getSpatialPartition()->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :  						(F32) mOctreeNode->getSize().getLength3().getF32(); -		mDistance = mSpatialPartition->calcDistance(this, camera); -		mPixelArea = mSpatialPartition->calcPixelArea(this, camera); +		mDistance = getSpatialPartition()->calcDistance(this, camera); +		mPixelArea = getSpatialPartition()->calcPixelArea(this, camera);  	}  } @@ -1266,9 +726,9 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)  		dist = eye.getLength3().getF32();  		eye.normalize3fast(); -		if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) +		if (!group->hasState(LLSpatialGroup::ALPHA_DIRTY))  		{ -			if (!group->mSpatialPartition->isBridge()) +			if (!group->getSpatialPartition()->isBridge())  			{  				LLVector4a view_angle = eye; @@ -1336,23 +796,18 @@ F32 LLSpatialGroup::getUpdateUrgency() const  	}  } -BOOL LLSpatialGroup::needsUpdate() -{ -	return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; -} -  BOOL LLSpatialGroup::changeLOD()  { -	if (isState(ALPHA_DIRTY | OBJECT_DIRTY)) +	if (hasState(ALPHA_DIRTY | OBJECT_DIRTY))  	{ ///a rebuild is going to happen, update distance and LoD  		return TRUE;  	} -	if (mSpatialPartition->mSlopRatio > 0.f) +	if (getSpatialPartition()->mSlopRatio > 0.f)  	{  		F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); -		if (fabsf(ratio) >= mSpatialPartition->mSlopRatio) +		if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio)  		{  			return TRUE;  		} @@ -1371,17 +826,17 @@ BOOL LLSpatialGroup::changeLOD()  	return FALSE;  } -void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep) +void LLSpatialGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* entry)  { -	addObject(drawablep, FALSE, TRUE); +	addObject((LLDrawable*)entry->getDrawable());  	unbound();  	setState(OBJECT_DIRTY);  } -void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable) +void LLSpatialGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* entry)  { -	removeObject(drawable, TRUE); -	setState(OBJECT_DIRTY); +	removeObject((LLDrawable*)entry->getDrawable(), TRUE); +	LLviewerOctreeGroup::handleRemoval(node, entry);  }  void LLSpatialGroup::handleDestruction(const TreeNode* node) @@ -1390,15 +845,22 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)  	for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)  	{ -		LLDrawable* drawable = *i; -		if (drawable->getSpatialGroup() == this) +		LLViewerOctreeEntry* entry = *i; +		if (entry->getGroup() == this)  		{ -			drawable->setSpatialGroup(NULL); +			if(entry->hasDrawable()) +			{ +				((LLDrawable*)entry->getDrawable())->setGroup(NULL); +			} +			else +		{ +				llerrs << "No Drawable found in the entry." << llendl; +			}  		}  	}  	//clean up avatar attachment stats -	LLSpatialBridge* bridge = mSpatialPartition->asBridge(); +	LLSpatialBridge* bridge = getSpatialPartition()->asBridge();  	if (bridge)  	{  		if (bridge->mAvatar.notNull()) @@ -1415,21 +877,11 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)  	mOctreeNode = NULL;  } -void LLSpatialGroup::handleStateChange(const TreeNode* node) -{ -	//drop bounding box upon state change -	if (mOctreeNode != node) -	{ -		mOctreeNode = (OctreeNode*) node; -	} -	unbound(); -} -  void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)   {  	if (child->getListenerCount() == 0)  	{ -		new LLSpatialGroup(child, mSpatialPartition); +		new LLSpatialGroup(child, getSpatialPartition());  	}  	else  	{ @@ -1441,11 +893,6 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c  	assert_states_valid(this);  } -void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) -{ -	unbound(); -} -  void LLSpatialGroup::destroyGL(bool keep_occlusion)   {  	setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); @@ -1463,20 +910,17 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion)  	if (!keep_occlusion)  	{ -		for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) -		{ -			if (mOcclusionQuery[i]) -			{ -				sQueryPool.release(mOcclusionQuery[i]); -				mOcclusionQuery[i] = 0; -			} -		} +		releaseOcclusionQueryObjectNames();  	}  	for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i)  	{ -		LLDrawable* drawable = *i; +		LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); +		if(!drawable) +		{ +			continue; +		}  		for (S32 j = 0; j < drawable->getNumFaces(); j++)  		{  			LLFace* facep = drawable->getFace(j); @@ -1488,318 +932,27 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion)  	}  } -BOOL LLSpatialGroup::rebound() -{ -	if (!isState(DIRTY)) -	{	//return TRUE if we're not empty -		return TRUE; -	} -	 -	if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) -	{ -		LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); -		group->rebound(); -		 -		//copy single child's bounding box -		mBounds[0] = group->mBounds[0]; -		mBounds[1] = group->mBounds[1]; -		mExtents[0] = group->mExtents[0]; -		mExtents[1] = group->mExtents[1]; -		 -		group->setState(SKIP_FRUSTUM_CHECK); -	} -	else if (mOctreeNode->isLeaf()) -	{ //copy object bounding box if this is a leaf -		boundObjects(TRUE, mExtents[0], mExtents[1]); -		mBounds[0] = mObjectBounds[0]; -		mBounds[1] = mObjectBounds[1]; -	} -	else -	{ -		LLVector4a& newMin = mExtents[0]; -		LLVector4a& newMax = mExtents[1]; -		LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); -		group->clearState(SKIP_FRUSTUM_CHECK); -		group->rebound(); -		//initialize to first child -		newMin = group->mExtents[0]; -		newMax = group->mExtents[1]; - -		//first, rebound children -		for (U32 i = 1; i < mOctreeNode->getChildCount(); i++) -		{ -			group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0); -			group->clearState(SKIP_FRUSTUM_CHECK); -			group->rebound(); -			const LLVector4a& max = group->mExtents[1]; -			const LLVector4a& min = group->mExtents[0]; - -			newMax.setMax(newMax, max); -			newMin.setMin(newMin, min); -		} - -		boundObjects(FALSE, newMin, newMax); -		 -		mBounds[0].setAdd(newMin, newMax); -		mBounds[0].mul(0.5f); -		mBounds[1].setSub(newMax, newMin); -		mBounds[1].mul(0.5f); -	} -	 -	clearState(DIRTY); - -	return TRUE; -} - -static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); - -void LLSpatialGroup::checkOcclusion() -{ -	if (LLPipeline::sUseOcclusion > 1) -	{ -		LLFastTimer t(FTM_OCCLUSION_READBACK); -		LLSpatialGroup* parent = getParent(); -		if (parent && parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) -		{	//if the parent has been marked as occluded, the child is implicitly occluded -			clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); -		} -		else if (isOcclusionState(QUERY_PENDING)) -		{	//otherwise, if a query is pending, read it back - -			GLuint available = 0; -			if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) -			{ -				glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); - -				static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); - -				if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) -				{ //query was issued last frame, wait until it's available -					S32 max_loop = 1024; -					LLFastTimer t(FTM_OCCLUSION_WAIT); -					while (!available && max_loop-- > 0) -					{ -						F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); -						//do some usefu work while we wait -						LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread -						LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread -						LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread -						 -						glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); -					} -				} -			} -			else -			{ -				available = 1; -			} - -			if (available) -			{ //result is available, read it back, otherwise wait until next frame -				GLuint res = 1; -				if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) -				{ -					glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);	 -#if LL_TRACK_PENDING_OCCLUSION_QUERIES -					sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -#endif -				} -				else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) -				{ //delete the query to avoid holding onto hundreds of pending queries -					sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -					mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; -				} -				 -				if (isOcclusionState(DISCARD_QUERY)) -				{ -					res = 2; -				} - -				if (res > 0) -				{ -					assert_states_valid(this); -					clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); -					assert_states_valid(this); -				} -				else -				{ -					assert_states_valid(this); -					 -					setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); -					 -					assert_states_valid(this); -				} - -				clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); -			} -		} -		else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED)) -		{	//check occlusion has been issued for occluded node that has not had a query issued -			assert_states_valid(this); -			clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); -			assert_states_valid(this); -		} -	} -} - -static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); -static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water"); -static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); - - - -void LLSpatialGroup::doOcclusion(LLCamera* camera) -{ -	if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) -	{ -		// Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension -		if (earlyFail(camera, this)) -		{ -			LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); -			setOcclusionState(LLSpatialGroup::DISCARD_QUERY); -			assert_states_valid(this); -			clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); -			assert_states_valid(this); -		} -		else -		{ -			if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) -			{ -				{ //no query pending, or previous query to be discarded -					LLFastTimer t(FTM_RENDER_OCCLUSION); - -					if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) -					{ -						LLFastTimer t(FTM_OCCLUSION_ALLOCATE); -						mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); -					} - -					// Depth clamp all water to avoid it being culled as a result of being -					// behind the far clip plane, and in the case of edge water to avoid -					// it being culled while still visible. -					bool const use_depth_clamp = gGLManager.mHasDepthClamp && -												(mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||						 -												mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); - -					LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);				 -						 -#if !LL_DARWIN					 -					U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; -#else -					U32 mode = GL_SAMPLES_PASSED_ARB; -#endif -					 -#if LL_TRACK_PENDING_OCCLUSION_QUERIES -					sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); -#endif - -					{ -						LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); -						 -						//store which frame this query was issued on -						mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; - -						{ -							LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); -							glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);					 -						} -					 -						LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; -						llassert(shader); - -						shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); -						shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE,  -																 mBounds[1][1]+SG_OCCLUSION_FUDGE,  -																 mBounds[1][2]+SG_OCCLUSION_FUDGE); - -						if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) -						{ -							LLFastTimer t(FTM_OCCLUSION_DRAW_WATER); - -							LLGLSquashToFarClip squash(glh_get_current_projection(), 1); -							if (camera->getOrigin().isExactlyZero()) -							{ //origin is invalid, draw entire box -								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); -								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				 -							} -							else -							{ -								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); -							} -						} -						else -						{ -							LLFastTimer t(FTM_OCCLUSION_DRAW); -							if (camera->getOrigin().isExactlyZero()) -							{ //origin is invalid, draw entire box -								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); -								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				 -							} -							else -							{ -								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); -							} -						} - - -						{ -							LLFastTimer t(FTM_OCCLUSION_END_QUERY); -							glEndQueryARB(mode); -						} -					} -				} - -				{ -					LLFastTimer t(FTM_SET_OCCLUSION_STATE); -					setOcclusionState(LLSpatialGroup::QUERY_PENDING); -					clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); -				} -			} -		} -	} -} -  //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp)  : mRenderByGroup(render_by_group), mBridge(NULL)  { -	mOcclusionEnabled = TRUE; -	mDrawableType = 0; +	mRegionp = regionp;		  	mPartitionType = LLViewerRegion::PARTITION_NONE; -	mLODSeed = 0; -	mLODPeriod = 1;  	mVertexDataMask = data_mask;  	mBufferUsage = buffer_usage;  	mDepthMask = FALSE;  	mSlopRatio = 0.25f;  	mInfiniteFarClip = FALSE; -	LLVector4a center, size; -	center.splat(0.f); -	size.splat(1.f); - -	mOctree = new LLSpatialGroup::OctreeRoot(center,size, -											NULL);  	new LLSpatialGroup(mOctree, this);  }  LLSpatialPartition::~LLSpatialPartition()  { -	delete mOctree; -	mOctree = NULL;  } -  LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)  {  	drawablep->updateSpatialExtents(); @@ -1807,11 +960,15 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)  	//keep drawable from being garbage collected  	LLPointer<LLDrawable> ptr = drawablep; +	if(!drawablep->getGroup()) +	{  	assert_octree_valid(mOctree); -	mOctree->insert(drawablep); +		mOctree->insert(drawablep->getEntry());  	assert_octree_valid(mOctree); +	}	  	LLSpatialGroup* group = drawablep->getSpatialGroup(); +	llassert(group != NULL);  	if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING))  	{ @@ -1829,11 +986,9 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)  	}  	else  	{ -		drawablep->setSpatialGroup(NULL); +		drawablep->setGroup(NULL);  	} -	drawablep->setSpatialGroup(NULL); -  	assert_octree_valid(mOctree);  	return TRUE; @@ -1851,11 +1006,11 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL  	BOOL was_visible = curp ? curp->isVisible() : FALSE; -	if (curp && curp->mSpatialPartition != this) +	if (curp && curp->getSpatialPartition() != this)  	{  		//keep drawable from being garbage collected  		LLPointer<LLDrawable> ptr = drawablep; -		if (curp->mSpatialPartition->remove(drawablep, curp)) +		if (curp->getSpatialPartition()->remove(drawablep, curp))  		{  			put(drawablep, was_visible);  			return; @@ -1883,13 +1038,13 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL  	put(drawablep, was_visible);  } -class LLSpatialShift : public LLSpatialGroup::OctreeTraveler +class LLSpatialShift : public OctreeTraveler  {  public:  	const LLVector4a& mOffset;  	LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { } -	virtual void visit(const LLSpatialGroup::OctreeNode* branch)  +	virtual void visit(const OctreeNode* branch)   	{   		((LLSpatialGroup*) branch->getListener(0))->shift(mOffset);   	} @@ -1901,17 +1056,17 @@ void LLSpatialPartition::shift(const LLVector4a &offset)  	shifter.traverse(mOctree);  } -class LLOctreeCull : public LLSpatialGroup::OctreeTraveler +class LLOctreeCull : public LLViewerOctreeCull  {  public: -	LLOctreeCull(LLCamera* camera) -		: mCamera(camera), mRes(0) { } +	LLOctreeCull(LLCamera* camera) : LLViewerOctreeCull(camera) {} -	virtual bool earlyFail(LLSpatialGroup* group) +	virtual bool earlyFail(LLviewerOctreeGroup* base_group)  	{ +		LLSpatialGroup* group = (LLSpatialGroup*)base_group;  		group->checkOcclusion(); -		if (group->mOctreeNode->getParent() &&	//never occlusion cull the root node +		if (group->getOctreeNode()->getParent() &&	//never occlusion cull the root node  		  	LLPipeline::sUseOcclusion &&			//ignore occlusion if disabled  			group->isOcclusionState(LLSpatialGroup::OCCLUDED))  		{ @@ -1922,78 +1077,29 @@ public:  		return false;  	} -	virtual void traverse(const LLSpatialGroup::OctreeNode* n) +	virtual S32 frustumCheck(const LLviewerOctreeGroup* group)  	{ -		LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); - -		if (earlyFail(group)) -		{ -			return; -		} -		 -		if (mRes == 2 ||  -			(mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK))) -		{	//fully in, just add everything -			LLSpatialGroup::OctreeTraveler::traverse(n); -		} -		else -		{ -			mRes = frustumCheck(group); -				 -			if (mRes) -			{ //at least partially in, run on down -				LLSpatialGroup::OctreeTraveler::traverse(n); -			} - -			mRes = 0; -		} -	} -	 -	virtual S32 frustumCheck(const LLSpatialGroup* group) -	{ -		S32 res = mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); +		S32 res = AABBInFrustumNoFarClipGroupBounds(group);  		if (res != 0)  		{ -			res = llmin(res, AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); +			res = llmin(res, AABBSphereIntersectGroupExtents(group));  		}  		return res;  	} -	virtual S32 frustumCheckObjects(const LLSpatialGroup* group) +	virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)  	{ -		S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); +		S32 res = AABBInFrustumNoFarClipObjectBounds(group);  		if (res != 0)  		{ -			res = llmin(res, AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist)); +			res = llmin(res, AABBSphereIntersectObjectExtents(group));  		}  		return res;  	} -	virtual bool checkObjects(const LLSpatialGroup::OctreeNode* branch, const LLSpatialGroup* group) -	{ -		if (branch->getElementCount() == 0) //no elements -		{ -			return false; -		} -		else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box -		{ -			return true; -		} -		else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum -		{ -			return false; -		} -		 -		return true; -	} - -	virtual void preprocess(LLSpatialGroup* group) -	{ -		 -	} -	 -	virtual void processGroup(LLSpatialGroup* group) +	virtual void processGroup(LLviewerOctreeGroup* base_group)  	{ +		LLSpatialGroup* group = (LLSpatialGroup*)base_group;  		if (group->needsUpdate() ||  			group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1)  		{ @@ -2001,21 +1107,6 @@ public:  		}  		gPipeline.markNotCulled(group, *mCamera);  	} -	 -	virtual void visit(const LLSpatialGroup::OctreeNode* branch)  -	{	 -		LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - -		preprocess(group); -		 -		if (checkObjects(branch, group)) -		{ -			processGroup(group); -		} -	} - -	LLCamera *mCamera; -	S32 mRes;  };  class LLOctreeCullNoFarClip : public LLOctreeCull @@ -2024,14 +1115,14 @@ public:  	LLOctreeCullNoFarClip(LLCamera* camera)   		: LLOctreeCull(camera) { } -	virtual S32 frustumCheck(const LLSpatialGroup* group) +	virtual S32 frustumCheck(const LLviewerOctreeGroup* group)  	{ -		return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); +		return AABBInFrustumNoFarClipGroupBounds(group);  	} -	virtual S32 frustumCheckObjects(const LLSpatialGroup* group) +	virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)  	{ -		S32 res = mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); +		S32 res = AABBInFrustumNoFarClipObjectBounds(group);  		return res;  	}  }; @@ -2042,14 +1133,14 @@ public:  	LLOctreeCullShadow(LLCamera* camera)  		: LLOctreeCull(camera) { } -	virtual S32 frustumCheck(const LLSpatialGroup* group) +	virtual S32 frustumCheck(const LLviewerOctreeGroup* group)  	{ -		return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); +		return AABBInFrustumGroupBounds(group);  	} -	virtual S32 frustumCheckObjects(const LLSpatialGroup* group) +	virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group)  	{ -		return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); +		return AABBInFrustumObjectBounds(group);  	}  }; @@ -2059,9 +1150,11 @@ public:  	LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max)  		: LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } -	virtual bool earlyFail(LLSpatialGroup* group) +	virtual bool earlyFail(LLviewerOctreeGroup* base_group)  	{ -		if (group->mOctreeNode->getParent() &&	//never occlusion cull the root node +		LLSpatialGroup* group = (LLSpatialGroup*)base_group; + +		if (group->getOctreeNode()->getParent() &&	//never occlusion cull the root node  			LLPipeline::sUseOcclusion &&			//ignore occlusion if disabled  			group->isOcclusionState(LLSpatialGroup::OCCLUDED))  		{ @@ -2071,7 +1164,7 @@ public:  		return false;  	} -	virtual void traverse(const LLSpatialGroup::OctreeNode* n) +	virtual void traverse(const OctreeNode* n)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); @@ -2080,10 +1173,10 @@ public:  			return;  		} -		if ((mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || +		if ((mRes && group->hasState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) ||  			mRes == 2)  		{	//don't need to do frustum check -			LLSpatialGroup::OctreeTraveler::traverse(n); +			OctreeTraveler::traverse(n);  		}  		else  		{   @@ -2091,31 +1184,35 @@ public:  			if (mRes)  			{ //at least partially in, run on down -				LLSpatialGroup::OctreeTraveler::traverse(n); +				OctreeTraveler::traverse(n);  			}  			mRes = 0;  		}  	} -	virtual void processGroup(LLSpatialGroup* group) +	virtual void processGroup(LLviewerOctreeGroup* base_group)  	{ -		llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty()) +		LLSpatialGroup* group = (LLSpatialGroup*)base_group; +		 +		llassert(!group->hasState(LLSpatialGroup::DIRTY) && !group->isEmpty())  		if (mRes < 2)  		{ -			if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) +			if (AABBInFrustumObjectBounds(group) > 0)  			{  				mEmpty = FALSE; -				update_min_max(mMin, mMax, group->mObjectExtents[0]); -				update_min_max(mMin, mMax, group->mObjectExtents[1]); +				const LLVector4a* exts = group->getObjectExtents(); +				update_min_max(mMin, mMax, exts[0]); +				update_min_max(mMin, mMax, exts[1]);  			}  		}  		else  		{  			mEmpty = FALSE; -			update_min_max(mMin, mMax, group->mExtents[0]); -			update_min_max(mMin, mMax, group->mExtents[1]); +			const LLVector4a* exts = group->getExtents(); +			update_min_max(mMin, mMax, exts[0]); +			update_min_max(mMin, mMax, exts[1]);  		}  	} @@ -2130,10 +1227,12 @@ public:  	LLOctreeCullDetectVisible(LLCamera* camera)  		: LLOctreeCullShadow(camera), mResult(FALSE) { } -	virtual bool earlyFail(LLSpatialGroup* group) +	virtual bool earlyFail(LLviewerOctreeGroup* base_group)  	{ +		LLSpatialGroup* group = (LLSpatialGroup*)base_group; +  		if (mResult || //already found a node, don't check any more -			(group->mOctreeNode->getParent() &&	//never occlusion cull the root node +			(group->getOctreeNode()->getParent() &&	//never occlusion cull the root node  			 LLPipeline::sUseOcclusion &&			//ignore occlusion if disabled  			 group->isOcclusionState(LLSpatialGroup::OCCLUDED)))  		{ @@ -2143,9 +1242,9 @@ public:  		return false;  	} -	virtual void processGroup(LLSpatialGroup* group) +	virtual void processGroup(LLviewerOctreeGroup* base_group)  	{ -		if (group->isVisible()) +		if (base_group->isVisible())  		{  			mResult = TRUE;  		} @@ -2160,17 +1259,21 @@ public:  	LLOctreeSelect(LLCamera* camera, std::vector<LLDrawable*>* results)  		: LLOctreeCull(camera), mResults(results) { } -	virtual bool earlyFail(LLSpatialGroup* group) { return false; } -	virtual void preprocess(LLSpatialGroup* group) { } +	virtual bool earlyFail(LLviewerOctreeGroup* group) { return false; } +	virtual void preprocess(LLviewerOctreeGroup* group) { } -	virtual void processGroup(LLSpatialGroup* group) +	virtual void processGroup(LLviewerOctreeGroup* base_group)  	{ -		LLSpatialGroup::OctreeNode* branch = group->mOctreeNode; +		LLSpatialGroup* group = (LLSpatialGroup*)base_group; +		OctreeNode* branch = group->getOctreeNode(); -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) +		for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)  		{ -			LLDrawable* drawable = *i; -			 +			LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); +			if(!drawable) +		{ +				continue; +			}  			if (!drawable->isDead())  			{  				if (drawable->isSpatialBridge()) @@ -2283,18 +1386,22 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size)  	drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size));  } -class LLOctreeDirty : public LLOctreeTraveler<LLDrawable> +class LLOctreeDirty : public OctreeTraveler  {  public: -	virtual void visit(const LLOctreeNode<LLDrawable>* state) +	virtual void visit(const OctreeNode* state)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);  		group->destroyGL();  		for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  		{ -			LLDrawable* drawable = *i; -			if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup) +			LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); +			if(!drawable) +			{ +				continue; +			} +			if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup)  			{  				gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE);  			} @@ -2318,11 +1425,6 @@ void LLSpatialPartition::resetVertexBuffers()  	dirty.traverse(mOctree);  } -BOOL LLSpatialPartition::isOcclusionEnabled() -{ -	return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; -} -  BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax)  {  	LLVector4a visMina, visMaxa; @@ -2365,13 +1467,28 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result  	((LLSpatialGroup*)mOctree->getListener(0))->validate();  #endif +	LLOctreeSelect selecter(&camera, results); +	selecter.traverse(mOctree); +	 +	return 0; +} -	if (for_select) +S32 LLSpatialPartition::cull(LLCamera &camera) +{ +#if LL_OCTREE_PARANOIA_CHECK +	((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); +#endif  	{ -		LLOctreeSelect selecter(&camera, results); -		selecter.traverse(mOctree); +		LLFastTimer ftm(FTM_CULL_REBOUND);		 +		LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); +		group->rebound();  	} -	else if (LLPipeline::sShadowRender) + +#if LL_OCTREE_PARANOIA_CHECK +	((LLSpatialGroup*)mOctree->getListener(0))->validate(); +#endif + +	if (LLPipeline::sShadowRender)  	{  		LLFastTimer ftm(FTM_FRUSTUM_CULL);  		LLOctreeCullShadow culler(&camera); @@ -2393,50 +1510,6 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result  	return 0;  } -BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) -{ -	if (camera->getOrigin().isExactlyZero()) -	{ -		return FALSE; -	} - -	const F32 vel = SG_OCCLUSION_FUDGE*2.f; -	LLVector4a fudge; -	fudge.splat(vel); - -	const LLVector4a& c = group->mBounds[0]; -	LLVector4a r; -	r.setAdd(group->mBounds[1], fudge); - -	/*if (r.magVecSquared() > 1024.0*1024.0) -	{ -		return TRUE; -	}*/ - -	LLVector4a e; -	e.load3(camera->getOrigin().mV); -	 -	LLVector4a min; -	min.setSub(c,r); -	LLVector4a max; -	max.setAdd(c,r); -	 -	S32 lt = e.lessThan(min).getGatheredBits() & 0x7; -	if (lt) -	{ -		return FALSE; -	} - -	S32 gt = e.greaterThan(max).getGatheredBits() & 0x7; -	if (gt) -	{ -		return FALSE; -	} - -	return TRUE; -} - -  void pushVerts(LLDrawInfo* params, U32 mask)  {  	LLRenderPass::applyModelMatrix(*params); @@ -2508,7 +1581,7 @@ void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)  void pushBufferVerts(LLSpatialGroup* group, U32 mask)  { -	if (group->mSpatialPartition->mRenderByGroup) +	if (group->getSpatialPartition()->mRenderByGroup)  	{  		if (!group->mDrawMap.empty())  		{ @@ -2531,7 +1604,8 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask)  	}  	else  	{ -		drawBox(group->mBounds[0], group->mBounds[1]); +		const LLVector4a* bounds = group->getBounds(); +		drawBox(bounds[0], bounds[1]);  	}  } @@ -2576,7 +1650,7 @@ void renderOctree(LLSpatialGroup* group)  	LLVector4 col;  	if (group->mBuilt > 0.f)  	{ -		group->mBuilt -= 2.f * gFrameIntervalSeconds; +		group->mBuilt -= 2.f * gFrameIntervalSeconds.value();  		if (group->mBufferUsage == GL_STATIC_DRAW_ARB)  		{  			col.setVec(1.0f, 0, 0, group->mBuilt*0.5f); @@ -2595,14 +1669,20 @@ void renderOctree(LLSpatialGroup* group)  			gGL.diffuseColor4f(1,0,0,group->mBuilt);  			gGL.flush();  			glLineWidth(5.f); -			drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); + +			const LLVector4a* bounds = group->getObjectBounds(); +			drawBoxOutline(bounds[0], bounds[1]);  			gGL.flush();  			glLineWidth(1.f);  			gGL.flush();  			for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  			{ -				LLDrawable* drawable = *i; -				if (!group->mSpatialPartition->isBridge()) +				LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); +				if(!drawable) +				{ +					continue; +				} +				if (!group->getSpatialPartition()->isBridge())  				{  					gGL.pushMatrix();  					LLVector3 trans = drawable->getRegion()->getOriginAgent(); @@ -2634,7 +1714,7 @@ void renderOctree(LLSpatialGroup* group)  					}  				} -				if (!group->mSpatialPartition->isBridge()) +				if (!group->getSpatialPartition()->isBridge())  				{  					gGL.popMatrix();  				} @@ -2646,7 +1726,7 @@ void renderOctree(LLSpatialGroup* group)  	else  	{  		if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty()  -			&& group->mSpatialPartition->mRenderByGroup) +			&& group->getSpatialPartition()->mRenderByGroup)  		{  			col.setVec(0.8f, 0.4f, 0.1f, 0.1f);  		} @@ -2659,9 +1739,10 @@ void renderOctree(LLSpatialGroup* group)  	gGL.diffuseColor4fv(col.mV);  	LLVector4a fudge;  	fudge.splat(0.001f); -	LLVector4a size = group->mObjectBounds[1]; -	size.mul(1.01f); -	size.add(fudge); + +	//LLVector4a size = group->mObjectBounds[1]; +	//size.mul(1.01f); +	//size.add(fudge);  	//{  	//	LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -2677,10 +1758,12 @@ void renderOctree(LLSpatialGroup* group)  		//drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]);  		gGL.diffuseColor4f(0,1,1,1); -		drawBoxOutline(group->mBounds[0],group->mBounds[1]); + +		const LLVector4a* bounds = group->getBounds(); +		drawBoxOutline(bounds[0], bounds[1]);  		//draw bounding box for draw info -		/*if (group->mSpatialPartition->mRenderByGroup) +		/*if (group->getSpatialPartition()->mRenderByGroup)  		{  			gGL.diffuseColor4f(1.0f, 0.75f, 0.25f, 0.6f);  			for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) @@ -3444,13 +2527,17 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)  void renderPhysicsShapes(LLSpatialGroup* group)  { -	for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) +	for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{ -		LLDrawable* drawable = *i; +		LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); +		if(!drawable) +	{ +			continue; +		}  		LLVOVolume* volume = drawable->getVOVolume();  		if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE )  		{ -			if (!group->mSpatialPartition->isBridge()) +			if (!group->getSpatialPartition()->isBridge())  			{  				gGL.pushMatrix();  				LLVector3 trans = drawable->getRegion()->getOriginAgent(); @@ -4003,17 +3090,18 @@ void renderAgentTarget(LLVOAvatar* avatar)  	}  } -class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> +class LLOctreeRenderNonOccluded : public OctreeTraveler  {  public:  	LLCamera* mCamera;  	LLOctreeRenderNonOccluded(LLCamera* camera): mCamera(camera) {} -	virtual void traverse(const LLSpatialGroup::OctreeNode* node) +	virtual void traverse(const OctreeNode* node)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); -		if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) +		const LLVector4a* bounds = group->getBounds(); +		if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))  		{  			node->accept(this);  			stop_glerror(); @@ -4053,11 +3141,11 @@ public:  		}  	} -	virtual void visit(const LLSpatialGroup::OctreeNode* branch) +	virtual void visit(const OctreeNode* branch)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); - -		if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) +		const LLVector4a* bounds = group->getBounds(); +		if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])))  		{  			return;  		} @@ -4070,14 +3158,19 @@ public:  			if (!group->isEmpty())  			{  				gGL.diffuseColor3f(0,0,1); -				drawBoxOutline(group->mObjectBounds[0], -								group->mObjectBounds[1]); + +				const LLVector4a* obj_bounds = group->getObjectBounds(); +				drawBoxOutline(obj_bounds[0], obj_bounds[1]);  			}  		} -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) +		for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) +		{ +			LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); +			if(!drawable)  		{ -			LLDrawable* drawable = *i; +				continue; +			}  			if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))  			{ @@ -4200,17 +3293,18 @@ public:  }; -class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler<LLDrawable> +class LLOctreeRenderPhysicsShapes : public OctreeTraveler  {  public:  	LLCamera* mCamera;  	LLOctreeRenderPhysicsShapes(LLCamera* camera): mCamera(camera) {} -	virtual void traverse(const LLSpatialGroup::OctreeNode* node) +	virtual void traverse(const OctreeNode* node)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); -		if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1])) +		const LLVector4a* bounds = group->getBounds(); +		if (!mCamera || mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1]))  		{  			node->accept(this);  			stop_glerror(); @@ -4228,23 +3322,24 @@ public:  		}  	} -	virtual void visit(const LLSpatialGroup::OctreeNode* branch) +	virtual void visit(const OctreeNode* branch)  	{  	}  }; -class LLOctreePushBBoxVerts : public LLOctreeTraveler<LLDrawable> +class LLOctreePushBBoxVerts : public OctreeTraveler  {  public:  	LLCamera* mCamera;  	LLOctreePushBBoxVerts(LLCamera* camera): mCamera(camera) {} -	virtual void traverse(const LLSpatialGroup::OctreeNode* node) +	virtual void traverse(const OctreeNode* node)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); -		if (!mCamera || mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1])) +		const LLVector4a* bounds = group->getBounds(); +		if (!mCamera || mCamera->AABBInFrustum(bounds[0], bounds[1]))  		{  			node->accept(this); @@ -4255,19 +3350,23 @@ public:  		}  	} -	virtual void visit(const LLSpatialGroup::OctreeNode* branch) +	virtual void visit(const OctreeNode* branch)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) branch->getListener(0); -		if (group->isState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]))) +		const LLVector4a* bounds = group->getBounds(); +		if (group->hasState(LLSpatialGroup::GEOM_DIRTY) || (mCamera && !mCamera->AABBInFrustumNoFarClip(bounds[0], bounds[1])))  		{  			return;  		} -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) +		for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) +		{ +			LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); +			if(!drawable)  		{ -			LLDrawable* drawable = *i; -						 +				continue; +			}  			renderBoundingBox(drawable, FALSE);			  		}  	} @@ -4279,7 +3378,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera)  	pusher.traverse(mOctree);  } -class LLOctreeStateCheck : public LLOctreeTraveler<LLDrawable> +class LLOctreeStateCheck : public OctreeTraveler  {  public:  	U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS]; @@ -4292,7 +3391,7 @@ public:  		}  	} -	virtual void traverse(const LLSpatialGroup::OctreeNode* node) +	virtual void traverse(const OctreeNode* node)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); @@ -4319,7 +3418,7 @@ public:  	} -	virtual void visit(const LLOctreeNode<LLDrawable>* state) +	virtual void visit(const OctreeNode* state)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); @@ -4331,7 +3430,7 @@ public:  			}  		} -		if (group->isState(LLSpatialGroup::DIRTY)) +		if (group->hasState(LLSpatialGroup::DIRTY))  		{  			assert_parent_state(group, LLSpatialGroup::DIRTY);  		} @@ -4342,7 +3441,7 @@ public:  		LLSpatialGroup* parent = group->getParent();  		while (parent)  		{ -			if (!parent->isState(state)) +			if (!parent->hasState(state))  			{  				llerrs << "Spatial group failed parent state check." << llendl;  			} @@ -4457,7 +3556,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)  	return TRUE;  } -class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler +class LLOctreeIntersect : public OctreeTraveler  {  public:  	LLVector3 mStart; @@ -4484,21 +3583,21 @@ public:  	{  	} -	virtual void visit(const LLSpatialGroup::OctreeNode* branch)  +	virtual void visit(const OctreeNode* branch)   	{	 -		for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i) +		for (OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)  		{  			check(*i);  		}  	} -	virtual LLDrawable* check(const LLSpatialGroup::OctreeNode* node) +	virtual LLDrawable* check(const OctreeNode* node)  	{  		node->accept(this);  		for (U32 i = 0; i < node->getChildCount(); i++)  		{ -			const LLSpatialGroup::OctreeNode* child = node->getChild(i); +			const OctreeNode* child = node->getChild(i);  			LLVector3 res;  			LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); @@ -4506,15 +3605,16 @@ public:  			LLVector4a size;  			LLVector4a center; -			size = group->mBounds[1]; -			center = group->mBounds[0]; +			const LLVector4a* bounds = group->getBounds(); +			size = bounds[1]; +			center = bounds[0];  			LLVector3 local_start = mStart;  			LLVector3 local_end   = mEnd; -			if (group->mSpatialPartition->isBridge()) +			if (group->getSpatialPartition()->isBridge())  			{ -				LLMatrix4 local_matrix = group->mSpatialPartition->asBridge()->mDrawable->getRenderMatrix(); +				LLMatrix4 local_matrix = group->getSpatialPartition()->asBridge()->mDrawable->getRenderMatrix();  				local_matrix.invert();  				local_start = mStart * local_matrix; @@ -4534,8 +3634,10 @@ public:  		return mHit;  	} -	virtual bool check(LLDrawable* drawable) -	{	 +	virtual bool check(LLViewerOctreeEntry* entry) +	{ +		LLDrawable* drawable = (LLDrawable*)entry->getDrawable(); +	  		if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())  		{  			return false; @@ -4926,5 +4028,3 @@ void LLCullResult::assertDrawMapsEmpty()  	}  } - - diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b1706d9d35..406e796d4d 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -45,23 +45,16 @@  #define SG_STATE_INHERIT_MASK (OCCLUDED)  #define SG_INITIAL_STATE_MASK (DIRTY | GEOM_DIRTY) +class LLViewerOctreePartition;  class LLSpatialPartition;  class LLSpatialBridge;  class LLSpatialGroup;  class LLTextureAtlas;  class LLTextureAtlasSlot; +class LLViewerRegion; -S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); -S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); - -S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); -S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared);  void pushVerts(LLFace* face, U32 mask); -// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera -U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); -U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center); -  class LLDrawInfo : public LLRefCount   {  protected: @@ -192,13 +185,13 @@ public:  };  LL_ALIGN_PREFIX(16) -class LLSpatialGroup : public LLOctreeListener<LLDrawable> +class LLSpatialGroup : public LLOcclusionCullingGroup  {  	friend class LLSpatialPartition;  	friend class LLOctreeStateCheck;  public: -	LLSpatialGroup(const LLSpatialGroup& rhs) +	LLSpatialGroup(const LLSpatialGroup& rhs) : LLOcclusionCullingGroup(rhs)  	{  		*this = rhs;  	} @@ -219,7 +212,6 @@ public:  		return *this;  	} -	static std::set<GLuint> sPendingQueries; //pending occlusion queries  	static U32 sNodeCount;  	static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE @@ -231,15 +223,6 @@ public:  	typedef std::map<LLFace*, buffer_list_t> buffer_texture_map_t;  	typedef std::map<U32, buffer_texture_map_t> buffer_map_t; -	typedef LLOctreeListener<LLDrawable>	BaseType; -	typedef LLOctreeListener<LLDrawable>	OctreeListener; -	typedef LLTreeNode<LLDrawable>			TreeNode; -	typedef LLOctreeNode<LLDrawable>		OctreeNode; -	typedef LLOctreeRoot<LLDrawable>		OctreeRoot; -	typedef LLOctreeTraveler<LLDrawable>	OctreeTraveler; -	typedef LLOctreeNode<LLDrawable>::element_iter element_iter; -	typedef LLOctreeNode<LLDrawable>::element_list element_list; -  	struct CompareDistanceGreater  	{  		bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs) @@ -266,104 +249,57 @@ public:  	typedef enum  	{ -		OCCLUDED				= 0x00010000, -		QUERY_PENDING			= 0x00020000, -		ACTIVE_OCCLUSION		= 0x00040000, -		DISCARD_QUERY			= 0x00080000, -		EARLY_FAIL				= 0x00100000, -	} eOcclusionState; - -	typedef enum -	{ -		DEAD					= 0x00000001, -		DIRTY					= 0x00000002, -		OBJECT_DIRTY			= 0x00000004, -		GEOM_DIRTY				= 0x00000008, -		ALPHA_DIRTY				= 0x00000010, -		SKIP_FRUSTUM_CHECK		= 0x00000020, -		IN_IMAGE_QUEUE			= 0x00000040, -		IMAGE_DIRTY				= 0x00000080, -		MESH_DIRTY				= 0x00000100, -		NEW_DRAWINFO			= 0x00000200, -		IN_BUILD_Q1				= 0x00000400, -		IN_BUILD_Q2				= 0x00000800, +		GEOM_DIRTY				= LLviewerOctreeGroup::INVALID_STATE, +		ALPHA_DIRTY				= (GEOM_DIRTY << 1), +		IN_IMAGE_QUEUE			= (ALPHA_DIRTY << 1), +		IMAGE_DIRTY				= (IN_IMAGE_QUEUE << 1), +		MESH_DIRTY				= (IMAGE_DIRTY << 1), +		NEW_DRAWINFO			= (MESH_DIRTY << 1), +		IN_BUILD_Q1				= (NEW_DRAWINFO << 1), +		IN_BUILD_Q2				= (IN_BUILD_Q1 << 1),  		STATE_MASK				= 0x0000FFFF, -	} eSpatialState; - -	typedef enum -	{ -		STATE_MODE_SINGLE = 0,		//set one node -		STATE_MODE_BRANCH,			//set entire branch -		STATE_MODE_DIFF,			//set entire branch as long as current state is different -		STATE_MODE_ALL_CAMERAS,		//used for occlusion state, set state for all cameras -	} eSetStateMode; +	} eSpatialState;	  	LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part); -	BOOL isHUDGroup() ; -	BOOL isDead()							{ return isState(DEAD); } -	BOOL isState(U32 state) const;	 -	BOOL isOcclusionState(U32 state) const	{ return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } -	U32 getState()							{ return mState; } -	void setState(U32 state);	 -	void clearState(U32 state);	 +	BOOL isHUDGroup() ;	  	void clearDrawMap();  	void validate(); -	void checkStates();  	void validateDrawMap();  	void setState(U32 state, S32 mode);  	void clearState(U32 state, S32 mode); - -	void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); -	void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); +	void clearState(U32 state)     {mState &= ~state;}		  	LLSpatialGroup* getParent(); -	 -	BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE); +	BOOL addObject(LLDrawable *drawablep);  	BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);  	BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group -	BOOL isVisible() const;  	BOOL isRecentlyVisible() const; -	void setVisible(); -	void shift(const LLVector4a &offset); -	BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax); -	void unbound(); -	BOOL rebound(); -	void checkOcclusion(); //read back last occlusion query (if any) -	void doOcclusion(LLCamera* camera); //issue occlusion query +	void shift(const LLVector4a &offset);	  	void destroyGL(bool keep_occlusion = false);  	void updateDistance(LLCamera& camera); -	BOOL needsUpdate();  	F32 getUpdateUrgency() const;  	BOOL changeLOD();  	void rebuildGeom();  	void rebuildMesh(); +	void setState(U32 state)       {mState |= state;}  	void dirtyGeom() { setState(GEOM_DIRTY); }  	void dirtyMesh() { setState(MESH_DIRTY); } -	//octree wrappers to make code more readable -	element_list& getData() { return mOctreeNode->getData(); } -	element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } -	element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } -	bool hasElement(LLDrawable* drawablep) { return std::find(mOctreeNode->getDataBegin(), mOctreeNode->getDataEnd(), drawablep) != mOctreeNode->getDataEnd(); } - -	U32 getElementCount() const { return mOctreeNode->getElementCount(); } -	bool isEmpty() const { return mOctreeNode->isEmpty(); } -  	void drawObjectBox(LLColor4 col); +	LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;} +  	 //LISTENER FUNCTIONS -	virtual void handleInsertion(const TreeNode* node, LLDrawable* face); -	virtual void handleRemoval(const TreeNode* node, LLDrawable* face); +	virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* face); +	virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* face);  	virtual void handleDestruction(const TreeNode* node); -	virtual void handleStateChange(const TreeNode* node);  	virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); -	virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child);  //-------------------  //for atlas use @@ -386,21 +322,6 @@ public:  public: -	typedef enum -	{ -		BOUNDS = 0, -		EXTENTS = 2, -		OBJECT_BOUNDS = 4, -		OBJECT_EXTENTS = 6, -		VIEW_ANGLE = 8, -		LAST_VIEW_ANGLE = 9, -		V4_COUNT = 10 -	} eV4Index; - -	LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) -	LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children -	LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node -	LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node  	LL_ALIGN_16(LLVector4a mViewAngle);  	LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); @@ -419,13 +340,8 @@ private:  //-------------------  protected: -	virtual ~LLSpatialGroup(); - -	U32 mState; -	U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; -	U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; - -	S32 mLODHash; +	virtual ~LLSpatialGroup();	 +	  	static S32 sLODSeed;  public: @@ -435,17 +351,13 @@ public:  	U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node  	F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node -	F32 mBuilt; -	OctreeNode* mOctreeNode; -	LLSpatialPartition* mSpatialPartition; +	F32 mBuilt;	 -	LLPointer<LLVertexBuffer> mVertexBuffer; -	GLuint					mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; +	LLPointer<LLVertexBuffer> mVertexBuffer;	  	U32 mBufferUsage;  	draw_map_t mDrawMap; -	S32 mVisible[LLViewerCamera::NUM_CAMERAS];  	F32 mDistance;  	F32 mDepth;  	F32 mLastUpdateDistance; @@ -468,10 +380,10 @@ public:  	virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);  }; -class LLSpatialPartition: public LLGeometryManager +class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager  {  public: -	LLSpatialPartition(U32 data_mask,  BOOL render_by_group, U32 mBufferUsage); +	LLSpatialPartition(U32 data_mask,  BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp);  	virtual ~LLSpatialPartition();  	LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -498,7 +410,8 @@ public:  	virtual void rebuildMesh(LLSpatialGroup* group);  	BOOL visibleObjectsInFrustum(LLCamera& camera); -	S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results = NULL, BOOL for_select = FALSE); // Cull on arbitrary frustum +	/*virtual*/ S32 cull(LLCamera &camera); // Cull on arbitrary frustum +	S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select); // Cull on arbitrary frustum  	BOOL isVisible(const LLVector3& v);  	bool isHUDPartition() ; @@ -510,26 +423,21 @@ public:  	void renderDebug();  	void renderIntersectingBBoxes(LLCamera* camera);  	void restoreGL(); -	void resetVertexBuffers(); -	BOOL isOcclusionEnabled(); +	void resetVertexBuffers();	 +  	BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);  public: -	LLSpatialGroup::OctreeNode* mOctree;  	LLSpatialBridge* mBridge; // NULL for non-LLSpatialBridge instances, otherwise, mBridge == this  							// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe -							// to call asBridge() from the destructor -	BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed +							// to call asBridge() from the destructor	 +	  	BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane -	U32 mBufferUsage; -	const BOOL mRenderByGroup; -	U32 mLODSeed; -	U32 mLODPeriod;	//number of frames between LOD updates for a given spatial group (staggered by mLODSeed) +	U32 mBufferUsage;	 +	const BOOL mRenderByGroup;	  	U32 mVertexDataMask;  	F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);  	BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering -	U32 mDrawableType; -	U32 mPartitionType;  };  // class for creating bridges between spatial partitions @@ -541,7 +449,7 @@ protected:  public:  	typedef std::vector<LLPointer<LLSpatialBridge> > bridge_vector_t; -	LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); +	LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp);  	void destroyTree(); @@ -663,7 +571,7 @@ private:  class LLWaterPartition : public LLSpatialPartition  {  public: -	LLWaterPartition(); +	LLWaterPartition(LLViewerRegion* regionp);  	virtual void getGeometry(LLSpatialGroup* group) {  }  	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { }  }; @@ -672,14 +580,14 @@ public:  class LLVoidWaterPartition : public LLWaterPartition  {  public: -	LLVoidWaterPartition(); +	LLVoidWaterPartition(LLViewerRegion* regionp);  };  //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp)  class LLTerrainPartition : public LLSpatialPartition  {  public: -	LLTerrainPartition(); +	LLTerrainPartition(LLViewerRegion* regionp);  	virtual void getGeometry(LLSpatialGroup* group);  	virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);  }; @@ -688,7 +596,7 @@ public:  class LLTreePartition : public LLSpatialPartition  {  public: -	LLTreePartition(); +	LLTreePartition(LLViewerRegion* regionp);  	virtual void getGeometry(LLSpatialGroup* group) { }  	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } @@ -698,7 +606,7 @@ public:  class LLParticlePartition : public LLSpatialPartition  {  public: -	LLParticlePartition(); +	LLParticlePartition(LLViewerRegion* regionp);  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group);  	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count); @@ -710,14 +618,14 @@ protected:  class LLHUDParticlePartition : public LLParticlePartition  {  public: -	LLHUDParticlePartition(); +	LLHUDParticlePartition(LLViewerRegion* regionp);  };  //spatial partition for grass (implemented in LLVOGrass.cpp)  class LLGrassPartition : public LLSpatialPartition  {  public: -	LLGrassPartition(); +	LLGrassPartition(LLViewerRegion* regionp);  	virtual void getGeometry(LLSpatialGroup* group);  	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);  protected: @@ -747,7 +655,7 @@ class LLVolumeGeometryManager: public LLGeometryManager  class LLVolumePartition : public LLSpatialPartition, public LLVolumeGeometryManager  {  public: -	LLVolumePartition(); +	LLVolumePartition(LLViewerRegion* regionp);  	virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }  	virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }  	virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); } @@ -758,7 +666,7 @@ public:  class LLVolumeBridge : public LLSpatialBridge, public LLVolumeGeometryManager  {  public: -	LLVolumeBridge(LLDrawable* drawable); +	LLVolumeBridge(LLDrawable* drawable, LLViewerRegion* regionp);  	virtual void rebuildGeom(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildGeom(group); }  	virtual void getGeometry(LLSpatialGroup* group) { LLVolumeGeometryManager::getGeometry(group); }  	virtual void rebuildMesh(LLSpatialGroup* group) { LLVolumeGeometryManager::rebuildMesh(group); } @@ -768,7 +676,7 @@ public:  class LLHUDBridge : public LLVolumeBridge  {  public: -	LLHUDBridge(LLDrawable* drawablep); +	LLHUDBridge(LLDrawable* drawablep, LLViewerRegion* regionp);  	virtual void shiftPos(const LLVector4a& vec);  	virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);  }; @@ -777,7 +685,7 @@ public:  class LLBridgePartition : public LLSpatialPartition  {  public: -	LLBridgePartition(); +	LLBridgePartition(LLViewerRegion* regionp);  	virtual void getGeometry(LLSpatialGroup* group) { }  	virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) {  }  }; @@ -785,7 +693,7 @@ public:  class LLHUDPartition : public LLBridgePartition  {  public: -	LLHUDPartition(); +	LLHUDPartition(LLViewerRegion* regionp);  	virtual void shift(const LLVector4a &offset);  }; diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index a4582071e8..8177a50cc2 100755 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -34,7 +34,9 @@  #include "llgroupmgr.h"  #include "llsdutil.h"  #include "lluicolortable.h" +#include "llhttpclient.h"  #include "llviewerobjectlist.h" +#include "llviewerregion.h"  #include "llvoavatar.h"  #include "llworld.h" @@ -416,7 +418,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)  	{  		LLUUID speaker_id = speaker_it->first;  		LLSpeaker* speakerp = speaker_it->second; - +		  		if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id))  		{  			speakerp->mSpeechVolume = LLVoiceClient::getInstance()->getCurrentPower(speaker_id); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 82596a86b9..3c67216688 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -645,7 +645,7 @@ bool idle_startup()  				gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();  			}  #endif -             +  			if (gAudiop)  			{  #if LL_WINDOWS @@ -2052,7 +2052,7 @@ bool idle_startup()  		static LLFrameTimer wearables_timer;  		const F32 wearables_time = wearables_timer.getElapsedTimeF32(); -		const F32 MAX_WEARABLES_TIME = 10.f; +		static LLCachedControl<F32> max_wearables_time(gSavedSettings, "ClothingLoadingDelay");  		if (!gAgent.isGenderChosen() && isAgentAvatarValid())  		{ @@ -2072,10 +2072,10 @@ bool idle_startup()  		display_startup(); -		if (wearables_time > MAX_WEARABLES_TIME) +		if (wearables_time > max_wearables_time())  		{  			LLNotificationsUtil::add("ClothingLoading"); -			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG); +			record(LLStatViewer::LOADING_WEARABLES_LONG_DELAY, wearables_time);  			LLStartUp::setStartupState( STATE_CLEANUP );  			return TRUE;  		} @@ -2106,7 +2106,7 @@ bool idle_startup()  		display_startup();  		update_texture_fetch();  		display_startup(); -		set_startup_status(0.9f + 0.1f * wearables_time / MAX_WEARABLES_TIME, +		set_startup_status(0.9f + 0.1f * wearables_time / max_wearables_time(),  						 LLTrans::getString("LoginDownloadingClothing").c_str(),  						 gAgent.mMOTD.c_str());  		display_startup(); @@ -2186,9 +2186,6 @@ bool idle_startup()  		LLAppViewer::instance()->handleLoginComplete(); -		// reset timers now that we are running "logged in" logic -		LLFastTimer::reset(); -  		LLAgentPicksInfo::getInstance()->requestNumberOfPicks();  		display_startup(); @@ -2296,7 +2293,7 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)        //      break;          case 2:     // Teleport              // Restart the login process, starting at our home locaton -	  LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME)); +			LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));              LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );              break;          default: diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index ff69c6e9fd..f3406d9f8d 100755 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -37,7 +37,6 @@  #include "llviewercontrol.h"  #include "llfloaterbuycurrency.h"  #include "llbuycurrencyhtml.h" -#include "llfloaterlagmeter.h"  #include "llpanelnearbymedia.h"  #include "llpanelvolumepulldown.h"  #include "llfloaterregioninfo.h" @@ -199,10 +198,10 @@ BOOL LLStatusBar::postBuild()  	sgp.rect(r);  	sgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);  	sgp.mouse_opaque(false); +	sgp.stat.count_stat_float(&LLStatViewer::KBIT); +	sgp.units("Kbps"); +	sgp.precision(0);  	mSGBandwidth = LLUICtrlFactory::create<LLStatGraph>(sgp); -	mSGBandwidth->setStat(&LLViewerStats::getInstance()->mKBitStat); -	mSGBandwidth->setUnits("Kbps"); -	mSGBandwidth->setPrecision(0);  	addChild(mSGBandwidth);  	x -= SIM_STAT_WIDTH + 2; @@ -213,17 +212,20 @@ BOOL LLStatusBar::postBuild()  	pgp.rect(r);  	pgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);  	pgp.mouse_opaque(false); +	pgp.stat.sample_stat_float(&LLStatViewer::PACKETS_LOST_PERCENT); +	pgp.units("%"); +	pgp.min(0.f); +	pgp.max(5.f); +	pgp.precision(1); +	pgp.per_sec(false); +	LLStatGraph::Thresholds thresholds; +	thresholds.threshold.add(LLStatGraph::ThresholdParams().value(0.1).color(LLColor4::green)) +						.add(LLStatGraph::ThresholdParams().value(0.25f).color(LLColor4::yellow)) +						.add(LLStatGraph::ThresholdParams().value(0.6f).color(LLColor4::red)); + +	pgp.thresholds(thresholds);  	mSGPacketLoss = LLUICtrlFactory::create<LLStatGraph>(pgp); -	mSGPacketLoss->setStat(&LLViewerStats::getInstance()->mPacketsLostPercentStat); -	mSGPacketLoss->setUnits("%"); -	mSGPacketLoss->setMin(0.f); -	mSGPacketLoss->setMax(5.f); -	mSGPacketLoss->setThreshold(0, 0.5f); -	mSGPacketLoss->setThreshold(1, 1.f); -	mSGPacketLoss->setThreshold(2, 3.f); -	mSGPacketLoss->setPrecision(1); -	mSGPacketLoss->mPerSec = FALSE;  	addChild(mSGPacketLoss);  	mPanelVolumePulldown = new LLPanelVolumePulldown(); @@ -253,9 +255,9 @@ void LLStatusBar::refresh()  		F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f;  		mSGBandwidth->setMin(0.f);  		mSGBandwidth->setMax(bwtotal*1.25f); -		mSGBandwidth->setThreshold(0, bwtotal*0.75f); -		mSGBandwidth->setThreshold(1, bwtotal); -		mSGBandwidth->setThreshold(2, bwtotal); +		//mSGBandwidth->setThreshold(0, bwtotal*0.75f); +		//mSGBandwidth->setThreshold(1, bwtotal); +		//mSGBandwidth->setThreshold(2, bwtotal);  	}  	// update clock every 10 seconds diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 9d24bf8771..33a64ae7d5 100755 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -45,7 +45,6 @@  class LLTimer;  class LLUUID;  class LLAgent; -class LLStat;  static const U8 NO_EDGE    = 0x00;  static const U8 EAST_EDGE  = 0x01; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 305f6fca0f..f03cc22949 100755 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -919,7 +919,7 @@ void LLTextureCache::setDirNames(ELLPath location)  	mFastCacheFileName =  gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename);  } -void LLTextureCache::purgeCache(ELLPath location) +void LLTextureCache::purgeCache(ELLPath location, bool remove_dir)  {  	LLMutexLock lock(&mHeaderMutex); @@ -945,7 +945,7 @@ void LLTextureCache::purgeCache(ELLPath location)  	}  	//remove the current texture cache. -	purgeAllTextures(true); +	purgeAllTextures(remove_dir);  }  //is called in the main thread before initCache(...) is called. diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index e3fc957fd2..5a68c31a6d 100755 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -104,7 +104,7 @@ public:  	/*virtual*/ S32 update(F32 max_time_ms);	 -	void purgeCache(ELLPath location); +	void purgeCache(ELLPath location, bool remove_dir = true);  	void setReadOnly(BOOL read_only) ;  	S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index e2d0fdf357..a8038b7cf2 100755 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -187,7 +187,7 @@ protected:  	F32					mContextConeOpacity;  	LLSaveFolderState	mSavedFolderState;  	BOOL				mSelectedItemPinned; - +	  	LLRadioGroup*		mModeSelector;  	LLScrollListCtrl*	mLocalScrollCtrl; @@ -550,11 +550,11 @@ void LLFloaterTexturePicker::draw()  	if (gFocusMgr.childHasMouseCapture(getDragHandle()))  	{ -		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); +		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));  	}  	else  	{ -		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); +		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLSmoothInterpolation::getInterpolant(CONTEXT_FADE_TIME));  	}  	updateImageStats(); @@ -1311,7 +1311,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)  		// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.  		else if (mCommitOnSelection || op == TEXTURE_SELECT)  			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? -			 +  		if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work.  		{  			setTentative( FALSE ); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index be5fde9e2b..4b9a950b98 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -53,6 +53,7 @@  #include "llviewerstatsrecorder.h"  #include "llviewerassetstats.h"  #include "llworld.h" +#include "llsdparam.h"  #include "llsdutil.h"  #include "llstartup.h"  #include "llsdserialize.h" @@ -64,8 +65,8 @@  #include "bufferstream.h"  bool LLTextureFetchDebugger::sDebuggerEnabled = false ; -LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128); -LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128); +LLTrace::SampleStatHandle<> LLTextureFetch::sCacheHitRate("texture_cache_hits"); +LLTrace::SampleStatHandle<> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency");  ////////////////////////////////////////////////////////////////////////////// @@ -1246,7 +1247,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()  								 << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight())  								 << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; -			LLTextureFetch::sCacheHitRate.addValue(100.f); +			sample(LLTextureFetch::sCacheHitRate, 100.f);  		}  		else  		{ @@ -1264,7 +1265,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  			// fall through -			LLTextureFetch::sCacheHitRate.addValue(0.f); +			sample(LLTextureFetch::sCacheHitRate, 0.f);  		}  	} @@ -1884,7 +1885,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  	if (log_to_viewer_log || log_to_sim)  	{  		U64 timeNow = LLTimer::getTotalTime(); -		mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime); +		mFetcher->mTextureInfo.setRequestStartTime(mID, mMetricsStartTime.value());  		mFetcher->mTextureInfo.setRequestType(mID, LLTextureInfoDetails::REQUEST_TYPE_HTTP);  		mFetcher->mTextureInfo.setRequestSize(mID, mRequestedSize);  		mFetcher->mTextureInfo.setRequestOffset(mID, mRequestedOffset); @@ -2329,11 +2330,11 @@ bool LLTextureFetchWorker::writeToCacheComplete()  // Threads:  Ttf  void LLTextureFetchWorker::recordTextureStart(bool is_http)  { -	if (! mMetricsStartTime) +	if (! mMetricsStartTime.value())  	{  		mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();  	} -	LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, +	LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE,  												 is_http,  												 LLImageBase::TYPE_AVATAR_BAKE == mType);  } @@ -2342,15 +2343,15 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http)  // Threads:  Ttf  void LLTextureFetchWorker::recordTextureDone(bool is_http)  { -	if (mMetricsStartTime) +	if (mMetricsStartTime.value())  	{ -		LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, +		LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_TEXTURE,  													  is_http,  													  LLImageBase::TYPE_AVATAR_BAKE == mType,  													  LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime);  		mMetricsStartTime = 0;  	} -	LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, +	LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE,  												 is_http,  												 LLImageBase::TYPE_AVATAR_BAKE == mType);  } @@ -2411,6 +2412,10 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	mHttpMetricsHeaders = new LLCore::HttpHeaders;  	mHttpMetricsHeaders->mHeaders.push_back("Content-Type: application/llsd+xml");  	mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicyDefault(); + +	//reset the texture timer. +	gTextureTimer.reset(); +	gTextureTimer.pause();  }  LLTextureFetch::~LLTextureFetch() @@ -2756,7 +2761,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,  			F32 cache_read_time = worker->mCacheReadTime;  			if (cache_read_time != 0.f)  			{ -				sCacheReadLatency.addValue(cache_read_time * 1000.f); +				sample(sCacheReadLatency, cache_read_time * 1000.f);  			}  			res = true;  			LL_DEBUGS("Texture") << id << ": Request Finished. State: " << worker->mState << " Discard: " << discard_level << LL_ENDL; @@ -2882,7 +2887,7 @@ S32 LLTextureFetch::update(F32 max_time_ms)  		mNetworkQueueMutex.lock();										// +Mfnq  		mMaxBandwidth = band_width; -		gTextureList.sTextureBits += mHTTPTextureBits; +		add(LLStatViewer::TEXTURE_KBIT, mHTTPTextureBits);  		mHTTPTextureBits = 0;  		mNetworkQueueMutex.unlock();									// -Mfnq @@ -3789,7 +3794,7 @@ AssetReportHandler stats_handler;  bool  TFReqSetRegion::doWork(LLTextureFetch *)  { -	LLViewerAssetStatsFF::set_region_thread1(mRegionHandle); +	LLViewerAssetStatsFF::set_region(mRegionHandle);  	return true;  } @@ -3814,8 +3819,8 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	static const U32 report_priority(1);  	static LLCore::HttpHandler * const handler(fetcher->isQAMode() || true ? &stats_handler : NULL); -	if (! gViewerAssetStatsThread1) -		return true; +	//if (! gViewerAssetStatsThread1) +	//	return true;  	static volatile bool reporting_started(false);  	static volatile S32 report_sequence(0); @@ -3825,17 +3830,21 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// but leave it in 'this'.  Destructor will rid us of it.  	LLViewerAssetStats & main_stats = *mMainStats; -	// Merge existing stats into those from main, convert to LLSD -	main_stats.merge(*gViewerAssetStatsThread1); -	LLSD merged_llsd = main_stats.asLLSD(true); - -	// Add some additional meta fields to the content -	merged_llsd["session_id"] = mSessionID; -	merged_llsd["agent_id"] = mAgentID; -	merged_llsd["message"] = "ViewerAssetMetrics";					// Identifies the type of metrics -	merged_llsd["sequence"] = report_sequence;						// Sequence number -	merged_llsd["initial"] = ! reporting_started;					// Initial data from viewer -	merged_llsd["break"] = LLTextureFetch::svMetricsDataBreak;		// Break in data prior to this report +	LLViewerAssetStats::AssetStats stats; +	main_stats.getStats(stats, true); +	//LLSD merged_llsd = main_stats.asLLSD(); + +	bool initial_report = !reporting_started; +	stats.session_id = mSessionID; +	stats.agent_id = mAgentID; +	stats.message = "ViewerAssetMetrics"; +	stats.sequence = static_cast<bool>(report_sequence); +	stats.initial = initial_report; +	stats.break_ = static_cast<bool>(LLTextureFetch::svMetricsDataBreak); + +	LLSD sd; +	LLParamSDParser parser; +	parser.writeSD(sd, stats);  	// Update sequence number  	if (S32_MAX == ++report_sequence) @@ -3843,13 +3852,14 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	reporting_started = true;  	// Limit the size of the stats report if necessary. -	merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd); +	 +	sd["truncated"] = truncate_viewer_metrics(10, sd);  	if (! mCapsURL.empty())  	{  		LLCore::BufferArray * ba = new LLCore::BufferArray;  		LLCore::BufferArrayStream bas(ba); -		LLSDSerialize::toXML(merged_llsd, bas); +		LLSDSerialize::toXML(sd, bas);  		fetcher->getHttpRequest().requestPost(fetcher->getPolicyClass(),  											  report_priority, @@ -3869,11 +3879,9 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)  	// In QA mode, Metrics submode, log the result for ease of testing  	if (fetcher->isQAMode())  	{ -		LL_INFOS("Textures") << ll_pretty_print_sd(merged_llsd) << LL_ENDL; +		LL_INFOS("Textures") << ll_pretty_print_sd(sd) << LL_ENDL;  	} -	gViewerAssetStatsThread1->reset(); -  	return true;  } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 902a3d7a25..2530beb722 100755 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -37,15 +37,15 @@  #include "lltextureinfo.h"  #include "llapr.h"  #include "llimageworker.h" -#include "llstat.h"  #include "llcurl.h" -#include "llstat.h"  #include "httprequest.h"  #include "httpoptions.h"  #include "httpheaders.h"  #include "httphandler.h" +#include "lltrace.h"  #include "llviewertexture.h" +class LLViewerTexture;  class LLTextureFetchWorker;  class LLImageDecodeThread;  class LLHost; @@ -309,8 +309,8 @@ private:  	LLMutex mQueueMutex;        //to protect mRequestMap and mCommands only  	LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. -	static LLStat sCacheHitRate; -	static LLStat sCacheReadLatency; +	static LLTrace::SampleStatHandle<> sCacheHitRate; +	static LLTrace::SampleStatHandle<> sCacheReadLatency;  	LLTextureCache* mTextureCache;  	LLImageDecodeThread* mImageDecodeThread; @@ -330,7 +330,7 @@ private:  	LLTextureInfo mTextureInfo;  	// XXX possible delete -	U32 mHTTPTextureBits;												// Mfnq +	LLUnit<LLUnits::Bits, U32> mHTTPTextureBits;												// Mfnq  	// XXX possible delete  	//debug use diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index e80136b286..c9ec5d9bf6 100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -49,6 +49,8 @@  #include "llviewertexturelist.h"  #include "llvovolume.h"  #include "llviewerstats.h" +#include "llworld.h" +#include "llviewerobjectlist.h"  // For avatar texture view  #include "llvoavatarself.h" @@ -505,18 +507,21 @@ private:  void LLGLTexMemBar::draw()  { -	S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sBoundTextureMemoryInBytes); - 	S32 max_bound_mem = LLViewerTexture::sMaxBoundTextureMemInMegaBytes; -	S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerTexture::sTotalTextureMemoryInBytes); -	S32 max_total_mem = LLViewerTexture::sMaxTotalTextureMemInMegaBytes; +	LLUnit<LLUnits::Mibibytes, S32> bound_mem = LLViewerTexture::sBoundTextureMemory; + 	LLUnit<LLUnits::Mibibytes, S32> max_bound_mem = LLViewerTexture::sMaxBoundTextureMem; +	LLUnit<LLUnits::Mibibytes, S32> total_mem = LLViewerTexture::sTotalTextureMemory; +	LLUnit<LLUnits::Mibibytes, S32> max_total_mem = LLViewerTexture::sMaxTotalTextureMem;  	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias; -	F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ; -	F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ; +	F32 cache_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getUsage()).value() ; +	F32 cache_max_usage = (F32)LLTrace::Mibibytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ;  	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();  	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); -	F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024); -	F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); -	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests(); +	LLUnit<LLUnits::Bytes, F32> total_texture_downloaded = gTotalTextureData; +	LLUnit<LLUnits::Bytes, F32> total_object_downloaded = gTotalObjectData; +	U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; +	U32 total_active_cached_objects = LLWorld::getInstance()->getNumOfActiveCachedObjects(); +	U32 total_objects = gObjectList.getNumObjects(); +  	//----------------------------------------------------------------------------  	LLGLSUIDefault gls_ui;  	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); @@ -532,10 +537,10 @@ void LLGLTexMemBar::draw()  											 text_color, LLFontGL::LEFT, LLFontGL::TOP);  	text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB", -					total_mem, -					max_total_mem, -					bound_mem, -					max_bound_mem, +					total_mem.value(), +					max_total_mem.value(), +					bound_mem.value(), +					max_bound_mem.value(),  					LLRenderTarget::sBytesAllocated/(1024*1024),  					LLImageRaw::sGlobalRawMemory >> 20,  					discard_bias, @@ -549,9 +554,11 @@ void LLGLTexMemBar::draw()  	U32 cache_read(0U), cache_write(0U), res_wait(0U);  	LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait); -	text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u", -					total_texture_downloaded, -					total_object_downloaded, +	text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB #Objs/#Cached: %d/%d Tot Htp: %d Cread: %u Cwrite: %u Rwait: %u", +					total_texture_downloaded.value(), +					total_object_downloaded.value(), +					total_objects,  +					total_active_cached_objects,  					total_http_requests,  					cache_read,  					cache_write, @@ -679,7 +686,7 @@ void LLGLTexSizeBar::draw()  	if(LLImageGL::sCurTexSizeBar == mIndex)  	{ -		F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};	 +		LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);	  		std::string text;  		text = llformat("%d", mTopLoaded) ; @@ -691,8 +698,8 @@ void LLGLTexSizeBar::draw()  									 text_color, LLFontGL::LEFT, LLFontGL::TOP);  	} -	F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; -	F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; +	LLColor4 loaded_color(1.0f, 0.0f, 0.0f, 0.75f); +	LLColor4 bound_color(1.0f, 1.0f, 0.0f, 0.75f);  	gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ;  	gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ;  } diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 3f75f8da5e..85232f4a0b 100755 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -42,7 +42,6 @@  #include "lllineeditor.h"  #include "lluictrlfactory.h"  #include "llnotifications.h" -#include "llfunctorregistry.h"  #include "llrootview.h"  #include "lltransientfloatermgr.h"  #include "llviewercontrol.h" // for gSavedSettings diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index b2318f9158..ed0f22f16a 100755 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -521,7 +521,7 @@ void LLToolBarView::draw()  	{  		if (mToolbars[i])  		{ -			LLLayoutStack::ELayoutOrientation orientation = LLToolBarEnums::getOrientation(mToolbars[i]->getSideType()); +			LLView::EOrientation orientation = LLToolBarEnums::getOrientation(mToolbars[i]->getSideType());  			if (orientation == LLLayoutStack::HORIZONTAL)  			{ diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index e085834326..a4dce9efe8 100755 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1094,7 +1094,7 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,  		return;  	}  	LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); +	add(LLStatViewer::EDIT_TEXTURE, 1);  	S32 num_faces = hit_obj->getNumTEs();  	for( S32 face = 0; face < num_faces; face++ )  	{ @@ -1162,7 +1162,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,  	}  	// update viewer side image in anticipation of update from simulator  	LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id); -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT ); +	add(LLStatViewer::EDIT_TEXTURE, 1);  	hit_obj->setTEImage(hit_face, image);  	dialog_refresh_all(); @@ -1386,7 +1386,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,  	effectp->setDuration(LL_HUD_DUR_SHORT);  	effectp->setColor(LLColor4U(gAgent.getEffectColor())); -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_REZ_COUNT); +	add(LLStatViewer::OBJECT_REZ, 1);  }  void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj, diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index fc9a316759..c912d81a03 100755 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -42,6 +42,7 @@  #include "llfloaterscriptdebug.h"  #include "lltooltip.h"  #include "llhudeffecttrail.h" +#include "llhudicon.h"  #include "llhudmanager.h"  #include "llkeyboard.h"  #include "llmediaentry.h" diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 641fbc5042..b7718847ae 100755 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -433,7 +433,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )  	effectp->setDuration(LL_HUD_DUR_SHORT);  	effectp->setColor(LLColor4U(gAgent.getEffectColor())); -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CREATE_COUNT); +	add(LLStatViewer::OBJECT_CREATE, 1);  	return TRUE;  } diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 7c604a04bf..0a9153eecb 100755 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -32,6 +32,7 @@  #include "llagentcamera.h"  #include "llviewercontrol.h"  #include "lldrawable.h" +#include "llhudicon.h"  #include "llmanip.h"  #include "llmenugl.h"  #include "llselectmgr.h" diff --git a/indra/newview/lltoolselect.h b/indra/newview/lltoolselect.h index baa27f6071..74dababe8c 100755 --- a/indra/newview/lltoolselect.h +++ b/indra/newview/lltoolselect.h @@ -34,7 +34,7 @@  class LLObjectSelection; -class LLToolSelect : public LLTool, public LLSingleton<LLToolSelect> +class LLToolSelect : public LLTool  {  public:  	LLToolSelect( LLToolComposite* composite ); diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index aaa81c57d4..3a6ee636d4 100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -31,6 +31,8 @@  #include "stdtypes.h"  #include "llvoavatar.h" +#include "llsdparam.h" +#include "llsdutil.h"  /*   * Classes and utility functions for per-thread and per-region @@ -78,126 +80,258 @@   *   */ +namespace LLViewerAssetStatsFF +{ +	static EViewerAssetCategories asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp) +	{ +		// For statistical purposes, we divide GETs into several +		// populations of asset fetches: +		//  - textures which are de-prioritized in the asset system +		//  - wearables (clothing, bodyparts) which directly affect +		//    user experiences when they log in +		//  - sounds +		//  - gestures +		//  - everything else. +		// +		llassert_always(50 == LLViewerAssetType::AT_COUNT); + +		// Multiple asset definitions are floating around so this requires some +		// maintenance and attention. +		static const EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] = +		{ +			EVACTextureTempHTTPGet,			// (0) AT_TEXTURE +			EVACSoundUDPGet,				// AT_SOUND +			EVACOtherGet,					// AT_CALLINGCARD +			EVACOtherGet,					// AT_LANDMARK +			EVACOtherGet,					// AT_SCRIPT +			EVACWearableUDPGet,				// AT_CLOTHING +			EVACOtherGet,					// AT_OBJECT +			EVACOtherGet,					// AT_NOTECARD +			EVACOtherGet,					// AT_CATEGORY +			EVACOtherGet,					// AT_ROOT_CATEGORY +			EVACOtherGet,					// (10) AT_LSL_TEXT +			EVACOtherGet,					// AT_LSL_BYTECODE +			EVACOtherGet,					// AT_TEXTURE_TGA +			EVACWearableUDPGet,				// AT_BODYPART +			EVACOtherGet,					// AT_TRASH +			EVACOtherGet,					// AT_SNAPSHOT_CATEGORY +			EVACOtherGet,					// AT_LOST_AND_FOUND +			EVACSoundUDPGet,				// AT_SOUND_WAV +			EVACOtherGet,					// AT_IMAGE_TGA +			EVACOtherGet,					// AT_IMAGE_JPEG +			EVACGestureUDPGet,				// (20) AT_ANIMATION +			EVACGestureUDPGet,				// AT_GESTURE +			EVACOtherGet,					// AT_SIMSTATE +			EVACOtherGet,					// AT_FAVORITE +			EVACOtherGet,					// AT_LINK +			EVACOtherGet,					// AT_LINK_FOLDER +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					// (30) +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					// (40) +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					// +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					//  +			EVACOtherGet,					// AT_MESH +			// (50) +		}; -// ------------------------------------------------------ -// Global data definitions -// ------------------------------------------------------ -LLViewerAssetStats * gViewerAssetStatsMain(0); -LLViewerAssetStats * gViewerAssetStatsThread1(0); +		if (at < 0 || at >= LLViewerAssetType::AT_COUNT) +		{ +			return EVACOtherGet; +		} +		EViewerAssetCategories ret(asset_to_bin_map[at]); +		if (EVACTextureTempHTTPGet == ret) +		{ +			// Indexed with [is_temp][with_http] +			static const EViewerAssetCategories texture_bin_map[2][2] = +			{ +				{ +					EVACTextureNonTempUDPGet, +						EVACTextureNonTempHTTPGet, +				}, +				{ +					EVACTextureTempUDPGet, +						EVACTextureTempHTTPGet, +					} +			}; +			ret = texture_bin_map[is_temp][with_http]; +		} +		return ret; +	} + +	static LLTrace::CountStatHandle<> sEnqueueAssetRequestsTempTextureHTTP   ("enqueuedassetrequeststemptexturehttp",  +																	"Number of temporary texture asset http requests enqueued"), +							sEnqueueAssetRequestsTempTextureUDP    ("enqueuedassetrequeststemptextureudp",  +																	"Number of temporary texture asset udp requests enqueued"), +							sEnqueueAssetRequestsNonTempTextureHTTP("enqueuedassetrequestsnontemptexturehttp",  +																	"Number of texture asset http requests enqueued"), +							sEnqueueAssetRequestsNonTempTextureUDP ("enqueuedassetrequestsnontemptextureudp",  +																	"Number of texture asset udp requests enqueued"), +							sEnqueuedAssetRequestsWearableUdp      ("enqueuedassetrequestswearableudp",  +																	"Number of wearable asset requests enqueued"), +							sEnqueuedAssetRequestsSoundUdp         ("enqueuedassetrequestssoundudp",  +																	"Number of sound asset requests enqueued"), +							sEnqueuedAssetRequestsGestureUdp       ("enqueuedassetrequestsgestureudp",  +																	"Number of gesture asset requests enqueued"), +							sEnqueuedAssetRequestsOther            ("enqueuedassetrequestsother",  +																	"Number of other asset requests enqueued"); + +	static LLTrace::CountStatHandle<>* sEnqueued[EVACCount] = {		 +		&sEnqueueAssetRequestsTempTextureHTTP,    +		&sEnqueueAssetRequestsTempTextureUDP,   +		&sEnqueueAssetRequestsNonTempTextureHTTP, +		&sEnqueueAssetRequestsNonTempTextureUDP, +		&sEnqueuedAssetRequestsWearableUdp, +		&sEnqueuedAssetRequestsSoundUdp, +		&sEnqueuedAssetRequestsGestureUdp, +		&sEnqueuedAssetRequestsOther             +	}; + +	static LLTrace::CountStatHandle<> sDequeueAssetRequestsTempTextureHTTP   ("dequeuedassetrequeststemptexturehttp",  +																	"Number of temporary texture asset http requests dequeued"), +							sDequeueAssetRequestsTempTextureUDP    ("dequeuedassetrequeststemptextureudp",  +																	"Number of temporary texture asset udp requests dequeued"), +							sDequeueAssetRequestsNonTempTextureHTTP("dequeuedassetrequestsnontemptexturehttp",  +																	"Number of texture asset http requests dequeued"), +							sDequeueAssetRequestsNonTempTextureUDP ("dequeuedassetrequestsnontemptextureudp",  +																	"Number of texture asset udp requests dequeued"), +							sDequeuedAssetRequestsWearableUdp      ("dequeuedassetrequestswearableudp",  +																	"Number of wearable asset requests dequeued"), +							sDequeuedAssetRequestsSoundUdp         ("dequeuedassetrequestssoundudp",  +																	"Number of sound asset requests dequeued"), +							sDequeuedAssetRequestsGestureUdp       ("dequeuedassetrequestsgestureudp",  +																	"Number of gesture asset requests dequeued"), +							sDequeuedAssetRequestsOther            ("dequeuedassetrequestsother",  +																	"Number of other asset requests dequeued"); + +	static LLTrace::CountStatHandle<>* sDequeued[EVACCount] = { +		&sDequeueAssetRequestsTempTextureHTTP,    +		&sDequeueAssetRequestsTempTextureUDP,   +		&sDequeueAssetRequestsNonTempTextureHTTP, +		&sDequeueAssetRequestsNonTempTextureUDP, +		&sDequeuedAssetRequestsWearableUdp, +		&sDequeuedAssetRequestsSoundUdp, +		&sDequeuedAssetRequestsGestureUdp, +		&sDequeuedAssetRequestsOther             +	}; + +	static LLTrace::EventStatHandle<LLTrace::Seconds>	sResponseAssetRequestsTempTextureHTTP   ("assetresponsetimestemptexturehttp", +																							"Time spent responding to temporary texture asset http requests"), +													sResponseAssetRequestsTempTextureUDP    ("assetresponsetimestemptextureudp",  +																							"Time spent responding to temporary texture asset udp requests"), +													sResponseAssetRequestsNonTempTextureHTTP("assetresponsetimesnontemptexturehttp",  +																							"Time spent responding to texture asset http requests"), +													sResponseAssetRequestsNonTempTextureUDP ("assetresponsetimesnontemptextureudp",  +																							"Time spent responding to texture asset udp requests"), +													sResponsedAssetRequestsWearableUdp      ("assetresponsetimeswearableudp",  +																							"Time spent responding to wearable asset requests"), +													sResponsedAssetRequestsSoundUdp         ("assetresponsetimessoundudp",  +																							"Time spent responding to sound asset requests"), +													sResponsedAssetRequestsGestureUdp       ("assetresponsetimesgestureudp",  +																							"Time spent responding to gesture asset requests"), +													sResponsedAssetRequestsOther            ("assetresponsetimesother",  +																							"Time spent responding to other asset requests"); + +	static LLTrace::EventStatHandle<LLTrace::Seconds>* sResponse[EVACCount] = { +		&sResponseAssetRequestsTempTextureHTTP,    +		&sResponseAssetRequestsTempTextureUDP,   +		&sResponseAssetRequestsNonTempTextureHTTP, +		&sResponseAssetRequestsNonTempTextureUDP, +		&sResponsedAssetRequestsWearableUdp, +		&sResponsedAssetRequestsSoundUdp, +		&sResponsedAssetRequestsGestureUdp, +		&sResponsedAssetRequestsOther             +	}; +}  // ------------------------------------------------------ -// Local declarations +// Global data definitions  // ------------------------------------------------------ -namespace -{ - -static LLViewerAssetStats::EViewerAssetCategories -asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp); - -} +LLViewerAssetStats * gViewerAssetStats(0);  // ------------------------------------------------------ -// LLViewerAssetStats::PerRegionStats struct definition +// LLViewerAssetStats class definition  // ------------------------------------------------------ -void -LLViewerAssetStats::PerRegionStats::reset() +LLViewerAssetStats::LLViewerAssetStats() +:	mRegionHandle(U64(0)), +	mCurRecording(NULL)  { -	for (int i(0); i < LL_ARRAY_SIZE(mRequests); ++i) -	{ -		mRequests[i].mEnqueued.reset(); -		mRequests[i].mDequeued.reset(); -		mRequests[i].mResponse.reset(); -	} -	mFPS.reset(); -	 -	mTotalTime = 0; -	mStartTimestamp = LLViewerAssetStatsFF::get_timestamp(); +	start();  } -void -LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionStats & src) +LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) +:	mRegionHandle(src.mRegionHandle)  { -	// mRegionHandle, mTotalTime, mStartTimestamp are left alone. +	mRegionRecordings = src.mRegionRecordings; + +	mCurRecording = &mRegionRecordings[mRegionHandle]; -	// mFPS -	if (src.mFPS.getCount() && mFPS.getCount()) +	// assume this is being passed to another thread, so make sure we have unique copies of recording data +	for (PerRegionRecordingContainer::iterator it = mRegionRecordings.begin(), end_it = mRegionRecordings.end(); +		it != end_it; +		++it)  	{ -		mFPS.merge(src.mFPS); +		it->second.stop(); +		it->second.makeUnique();  	} -	// Avatar stats - data all comes from main thread, so leave alone. +	LLStopWatchControlsMixin<LLViewerAssetStats>::setPlayState(src.getPlayState()); +} -	// Requests -	for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i) +void LLViewerAssetStats::handleStart() +{ +	if (mCurRecording)  	{ -		mRequests[i].mEnqueued.merge(src.mRequests[i].mEnqueued); -		mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued); -		mRequests[i].mResponse.merge(src.mRequests[i].mResponse); +		mCurRecording->start();  	} -  } - -void -LLViewerAssetStats::PerRegionStats::accumulateTime(duration_t now) +void LLViewerAssetStats::handleStop()  { -	mTotalTime += (now - mStartTimestamp); -	mStartTimestamp = now; +	if (mCurRecording) +	{ +		mCurRecording->stop(); +	}  } - -// ------------------------------------------------------ -// LLViewerAssetStats class definition -// ------------------------------------------------------ -LLViewerAssetStats::LLViewerAssetStats() -	: mRegionHandle(U64(0)) +void LLViewerAssetStats::handleReset()  {  	reset();  } -LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) -	: mRegionHandle(src.mRegionHandle), -	  mResetTimestamp(src.mResetTimestamp) -{ -	const PerRegionContainer::const_iterator it_end(src.mRegionStats.end()); -	for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) -	{ -		mRegionStats[it->first] = new PerRegionStats(*it->second); -	} -	mCurRegionStats = mRegionStats[mRegionHandle]; -} - - -void -LLViewerAssetStats::reset() +void LLViewerAssetStats::reset()  {  	// Empty the map of all region stats -	mRegionStats.clear(); +	mRegionRecordings.clear(); -	// If we have a current stats, reset it, otherwise, as at construction, -	// create a new one as we must always have a current stats block. -	if (mCurRegionStats) +	// initialize new recording for current region +	if (mRegionHandle)  	{ -		mCurRegionStats->reset(); +		mCurRecording = &mRegionRecordings[mRegionHandle];  	} -	else -	{ -		mCurRegionStats = new PerRegionStats(mRegionHandle); -	} - -	// And add reference to map -	mRegionStats[mRegionHandle] = mCurRegionStats; - -	// Start timestamp consistent with per-region collector -	mResetTimestamp = mCurRegionStats->mStartTimestamp;  } - -void -LLViewerAssetStats::setRegion(region_handle_t region_handle) +void LLViewerAssetStats::setRegion(region_handle_t region_handle)  {  	if (region_handle == mRegionHandle)  	{ @@ -205,410 +339,267 @@ LLViewerAssetStats::setRegion(region_handle_t region_handle)  		return;  	} -	// Get duration for current set -	const duration_t now = LLViewerAssetStatsFF::get_timestamp(); -	mCurRegionStats->accumulateTime(now); - -	// Prepare new set -	PerRegionContainer::iterator new_stats = mRegionStats.find(region_handle); -	if (mRegionStats.end() == new_stats) +	if (mCurRecording)  	{ -		// Haven't seen this region_id before, create a new block and make it current. -		mCurRegionStats = new PerRegionStats(region_handle); -		mRegionStats[region_handle] = mCurRegionStats; +		mCurRecording->pause();  	} -	else +	if (region_handle)  	{ -		mCurRegionStats = new_stats->second; +		mCurRecording = &mRegionRecordings[region_handle]; +		mCurRecording->start();  	} -	mCurRegionStats->mStartTimestamp = now; +  	mRegionHandle = region_handle;  } - -void -LLViewerAssetStats::recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp) +void LLViewerAssetStats::updateStats()  { -	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	 -	++(mCurRegionStats->mRequests[int(eac)].mEnqueued); +	if (mCurRecording && mCurRecording->isStarted()) +	{ +		mCurRecording->update(); +	}  } -	 -void -LLViewerAssetStats::recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp) + +void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)  { -	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); +	using namespace LLViewerAssetStatsFF; -	++(mCurRegionStats->mRequests[int(eac)].mDequeued); -} +	stats.regions.setProvided(); -void -LLViewerAssetStats::recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration) -{ -	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); +	for (PerRegionRecordingContainer::iterator it = mRegionRecordings.begin(), end_it = mRegionRecordings.end(); +		it != end_it; +		++it) +	{ +		RegionStats& r = stats.regions.add(); +		LLTrace::Recording& rec = it->second; +		if (!compact_output +			|| rec.getSum(*sEnqueued[EVACTextureTempHTTPGet])  +			|| rec.getSum(*sDequeued[EVACTextureTempHTTPGet]) +			|| rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value()) +		{ +			r.get_texture_temp_http	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempHTTPGet])) +									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempHTTPGet])) +									.resp_count((S32)rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value()) +									.resp_min(rec.getMin(*sResponse[EVACTextureTempHTTPGet]).value()) +									.resp_max(rec.getMax(*sResponse[EVACTextureTempHTTPGet]).value()) +									.resp_mean(rec.getMean(*sResponse[EVACTextureTempHTTPGet]).value()); +		} +		if (!compact_output +			|| rec.getSum(*sEnqueued[EVACTextureTempUDPGet])  +			|| rec.getSum(*sDequeued[EVACTextureTempUDPGet]) +			|| rec.getSum(*sResponse[EVACTextureTempUDPGet]).value()) +		{ +			r.get_texture_temp_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempUDPGet])) +									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempUDPGet])) +									.resp_count((S32)rec.getSum(*sResponse[EVACTextureTempUDPGet]).value()) +									.resp_min(rec.getMin(*sResponse[EVACTextureTempUDPGet]).value()) +									.resp_max(rec.getMax(*sResponse[EVACTextureTempUDPGet]).value()) +									.resp_mean(rec.getMean(*sResponse[EVACTextureTempUDPGet]).value()); +		} +		if (!compact_output +			|| rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet])  +			|| rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet]) +			|| rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value()) +		{ +			r.get_texture_non_temp_http	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet])) +										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet])) +										.resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value()) +										.resp_min(rec.getMin(*sResponse[EVACTextureNonTempHTTPGet]).value()) +										.resp_max(rec.getMax(*sResponse[EVACTextureNonTempHTTPGet]).value()) +										.resp_mean(rec.getMean(*sResponse[EVACTextureNonTempHTTPGet]).value()); +		} -	mCurRegionStats->mRequests[int(eac)].mResponse.record(duration); -} +		if (!compact_output +			|| rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet])  +			|| rec.getSum(*sDequeued[EVACTextureNonTempUDPGet]) +			|| rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value()) +		{ +			r.get_texture_non_temp_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet])) +										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempUDPGet])) +										.resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value()) +										.resp_min(rec.getMin(*sResponse[EVACTextureNonTempUDPGet]).value()) +										.resp_max(rec.getMax(*sResponse[EVACTextureNonTempUDPGet]).value()) +										.resp_mean(rec.getMean(*sResponse[EVACTextureNonTempUDPGet]).value()); +		} -void -LLViewerAssetStats::recordFPS(F32 fps) -{ -	mCurRegionStats->mFPS.record(fps); -} +		if (!compact_output +			|| rec.getSum(*sEnqueued[EVACWearableUDPGet])  +			|| rec.getSum(*sDequeued[EVACWearableUDPGet]) +			|| rec.getSum(*sResponse[EVACWearableUDPGet]).value()) +		{ +			r.get_wearable_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACWearableUDPGet])) +								.dequeued((S32)rec.getSum(*sDequeued[EVACWearableUDPGet])) +								.resp_count((S32)rec.getSum(*sResponse[EVACWearableUDPGet]).value()) +								.resp_min(rec.getMin(*sResponse[EVACWearableUDPGet]).value()) +								.resp_max(rec.getMax(*sResponse[EVACWearableUDPGet]).value()) +								.resp_mean(rec.getMean(*sResponse[EVACWearableUDPGet]).value()); +		} -LLSD -LLViewerAssetStats::asLLSD(bool compact_output) -{ -	// Top-level tags -	static const LLSD::String tags[EVACCount] =  +		if (!compact_output +			|| rec.getSum(*sEnqueued[EVACSoundUDPGet])  +			|| rec.getSum(*sDequeued[EVACSoundUDPGet]) +			|| rec.getSum(*sResponse[EVACSoundUDPGet]).value())  		{ -			LLSD::String("get_texture_temp_http"), -			LLSD::String("get_texture_temp_udp"), -			LLSD::String("get_texture_non_temp_http"), -			LLSD::String("get_texture_non_temp_udp"), -			LLSD::String("get_wearable_udp"), -			LLSD::String("get_sound_udp"), -			LLSD::String("get_gesture_udp"), -			LLSD::String("get_other") -		}; +			r.get_sound_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACSoundUDPGet])) +							.dequeued((S32)rec.getSum(*sDequeued[EVACSoundUDPGet])) +							.resp_count((S32)rec.getSum(*sResponse[EVACSoundUDPGet]).value()) +							.resp_min(rec.getMin(*sResponse[EVACSoundUDPGet]).value()) +							.resp_max(rec.getMax(*sResponse[EVACSoundUDPGet]).value()) +							.resp_mean(rec.getMean(*sResponse[EVACSoundUDPGet]).value()); +		} -	// Stats Group Sub-tags. -	static const LLSD::String enq_tag("enqueued"); -	static const LLSD::String deq_tag("dequeued"); -	static const LLSD::String rcnt_tag("resp_count"); -	static const LLSD::String rmin_tag("resp_min"); -	static const LLSD::String rmax_tag("resp_max"); -	static const LLSD::String rmean_tag("resp_mean"); - -	// MMM Group Sub-tags. -	static const LLSD::String cnt_tag("count"); -	static const LLSD::String min_tag("min"); -	static const LLSD::String max_tag("max"); -	static const LLSD::String mean_tag("mean"); - -	const duration_t now = LLViewerAssetStatsFF::get_timestamp(); -	mCurRegionStats->accumulateTime(now); - -	LLSD regions = LLSD::emptyArray(); -	for (PerRegionContainer::iterator it = mRegionStats.begin(); -		 mRegionStats.end() != it; -		 ++it) -	{ -		if (0 == it->first) +		if (!compact_output +			|| rec.getSum(*sEnqueued[EVACGestureUDPGet])  +			|| rec.getSum(*sDequeued[EVACGestureUDPGet]) +			|| rec.getSum(*sResponse[EVACGestureUDPGet]).value())  		{ -			// Never emit NULL UUID/handle in results. -			continue; +			r.get_gesture_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACGestureUDPGet])) +								.dequeued((S32)rec.getSum(*sDequeued[EVACGestureUDPGet])) +								.resp_count((S32)rec.getSum(*sResponse[EVACGestureUDPGet]).value()) +								.resp_min(rec.getMin(*sResponse[EVACGestureUDPGet]).value()) +								.resp_max(rec.getMax(*sResponse[EVACGestureUDPGet]).value()) +								.resp_mean(rec.getMean(*sResponse[EVACGestureUDPGet]).value());  		} -		PerRegionStats & stats = *it->second; -		 -		LLSD reg_stat = LLSD::emptyMap(); -		 -		for (int i = 0; i < LL_ARRAY_SIZE(tags); ++i) +		if (!compact_output +			|| rec.getSum(*sEnqueued[EVACOtherGet])  +			|| rec.getSum(*sDequeued[EVACOtherGet]) +			|| rec.getSum(*sResponse[EVACOtherGet]).value())  		{ -			PerRegionStats::prs_group & group(stats.mRequests[i]); -			 -			if ((! compact_output) || -				group.mEnqueued.getCount() || -				group.mDequeued.getCount() || -				group.mResponse.getCount()) -			{ -				LLSD & slot = reg_stat[tags[i]]; -				slot = LLSD::emptyMap(); -				slot[enq_tag] = LLSD(S32(stats.mRequests[i].mEnqueued.getCount())); -				slot[deq_tag] = LLSD(S32(stats.mRequests[i].mDequeued.getCount())); -				slot[rcnt_tag] = LLSD(S32(stats.mRequests[i].mResponse.getCount())); -				slot[rmin_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMin() * 1.0e-6)); -				slot[rmax_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMax() * 1.0e-6)); -				slot[rmean_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMean() * 1.0e-6)); -			} +			r.get_other	.enqueued((S32)rec.getSum(*sEnqueued[EVACOtherGet])) +						.dequeued((S32)rec.getSum(*sDequeued[EVACOtherGet])) +						.resp_count((S32)rec.getSum(*sResponse[EVACOtherGet]).value()) +						.resp_min(rec.getMin(*sResponse[EVACOtherGet]).value()) +						.resp_max(rec.getMax(*sResponse[EVACOtherGet]).value()) +						.resp_mean(rec.getMean(*sResponse[EVACOtherGet]).value());  		} -		if ((! compact_output) || stats.mFPS.getCount()) +		S32 fps = (S32)rec.getLastValue(LLStatViewer::FPS_SAMPLE); +		if (!compact_output || fps != 0)  		{ -			LLSD & slot = reg_stat["fps"]; -			slot = LLSD::emptyMap(); -			slot[cnt_tag] = LLSD(S32(stats.mFPS.getCount())); -			slot[min_tag] = LLSD(F64(stats.mFPS.getMin())); -			slot[max_tag] = LLSD(F64(stats.mFPS.getMax())); -			slot[mean_tag] = LLSD(F64(stats.mFPS.getMean())); +			r.fps.count(fps); +			r.fps.min(rec.getMin(LLStatViewer::FPS_SAMPLE)); +			r.fps.max(rec.getMax(LLStatViewer::FPS_SAMPLE)); +			r.fps.mean(rec.getMean(LLStatViewer::FPS_SAMPLE));  		}  		U32 grid_x(0), grid_y(0);  		grid_from_region_handle(it->first, &grid_x, &grid_y); -		reg_stat["grid_x"] = LLSD::Integer(grid_x); -		reg_stat["grid_y"] = LLSD::Integer(grid_y); -		reg_stat["duration"] = LLSD::Real(stats.mTotalTime * 1.0e-6);		 -		regions.append(reg_stat); +		r.grid_x(grid_x); +		r.grid_y(grid_y); +		r.duration(LLUnit<LLUnits::Microseconds, F64>(rec.getDuration()).value());  	} -	LLSD ret = LLSD::emptyMap(); -	ret["regions"] = regions; -	ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6); -	 -	return ret; +	stats.duration(mCurRecording ? LLUnit<LLUnits::Microseconds, F64>(mCurRecording->getDuration()).value() : 0.0);  } -void -LLViewerAssetStats::merge(const LLViewerAssetStats & src) +LLSD LLViewerAssetStats::asLLSD(bool compact_output)  { -	// mRegionHandle, mCurRegionStats and mResetTimestamp are left untouched. -	// Just merge the stats bodies - -	const PerRegionContainer::const_iterator it_end(src.mRegionStats.end()); -	for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it) +	LLParamSDParser parser; +	LLSD sd; +	AssetStats stats; +	getStats(stats, compact_output); +	LLInitParam::predicate_rule_t rule = LLInitParam::default_parse_rules(); +	if (!compact_output)  	{ -		PerRegionContainer::iterator dst(mRegionStats.find(it->first)); -		if (mRegionStats.end() == dst) -		{ -			// Destination is missing data, just make a private copy -			mRegionStats[it->first] = new PerRegionStats(*it->second); -		} -		else -		{ -			dst->second->merge(*it->second); -		} +		rule.allow(LLInitParam::EMPTY);  	} +	parser.writeSD(sd, stats, rule); +	return sd;  } -  // ------------------------------------------------------  // Global free-function definitions (LLViewerAssetStatsFF namespace)  // ------------------------------------------------------  namespace LLViewerAssetStatsFF  { - -// -// Target thread is elaborated in the function name.  This could -// have been something 'templatey' like specializations iterated -// over a set of constants but with so few, this is clearer I think. -// -// As for the threads themselves... rather than do fine-grained -// locking as we gather statistics, this code creates a collector -// for each thread, allocated and run independently.  Logging -// happens at relatively infrequent intervals and at that time -// the data is sent to a single thread to be aggregated into -// a single entity with locks, thread safety and other niceties. -// -// A particularly fussy implementation would distribute the -// per-thread pointers across separate cache lines.  But that should -// be beyond current requirements. -// - -// 'main' thread - initial program thread - -void -set_region_main(LLViewerAssetStats::region_handle_t region_handle) -{ -	if (! gViewerAssetStatsMain) -		return; - -	gViewerAssetStatsMain->setRegion(region_handle); -} - -void -record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp) -{ -	if (! gViewerAssetStatsMain) -		return; - -	gViewerAssetStatsMain->recordGetEnqueued(at, with_http, is_temp); -} - -void -record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp) -{ -	if (! gViewerAssetStatsMain) -		return; - -	gViewerAssetStatsMain->recordGetDequeued(at, with_http, is_temp); -} - -void -record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration) -{ -	if (! gViewerAssetStatsMain) -		return; - -	gViewerAssetStatsMain->recordGetServiced(at, with_http, is_temp, duration); -} - -void -record_fps_main(F32 fps) -{ -	if (! gViewerAssetStatsMain) -		return; - -	gViewerAssetStatsMain->recordFPS(fps); -} - -// 'thread1' - should be for TextureFetch thread - -void -set_region_thread1(LLViewerAssetStats::region_handle_t region_handle) +void set_region(LLViewerAssetStats::region_handle_t region_handle)  { -	if (! gViewerAssetStatsThread1) +	if (! gViewerAssetStats)  		return; -	gViewerAssetStatsThread1->setRegion(region_handle); +	gViewerAssetStats->setRegion(region_handle);  } -void -record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp) +void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp)  { -	if (! gViewerAssetStatsThread1) -		return; +	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	gViewerAssetStatsThread1->recordGetEnqueued(at, with_http, is_temp); +	add(*sEnqueued[int(eac)], 1);  } -void -record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp) +void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp)  { -	if (! gViewerAssetStatsThread1) -		return; +	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	gViewerAssetStatsThread1->recordGetDequeued(at, with_http, is_temp); +	add(*sDequeued[int(eac)], 1);  } -void -record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration) +void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration)  { -	if (! gViewerAssetStatsThread1) -		return; +	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp)); -	gViewerAssetStatsThread1->recordGetServiced(at, with_http, is_temp, duration); +	record(*sResponse[int(eac)], LLTrace::Microseconds(duration));  } - -void -init() +void init()  { -	if (! gViewerAssetStatsMain) -	{ -		gViewerAssetStatsMain = new LLViewerAssetStats(); -	} -	if (! gViewerAssetStatsThread1) +	if (! gViewerAssetStats)  	{ -		gViewerAssetStatsThread1 = new LLViewerAssetStats(); +		gViewerAssetStats = new LLViewerAssetStats();  	}  }  void  cleanup()  { -	delete gViewerAssetStatsMain; -	gViewerAssetStatsMain = 0; - -	delete gViewerAssetStatsThread1; -	gViewerAssetStatsThread1 = 0; +	delete gViewerAssetStats; +	gViewerAssetStats = 0;  }  } // namespace LLViewerAssetStatsFF -// ------------------------------------------------------ -// Local function definitions -// ------------------------------------------------------ - -namespace -{ - -LLViewerAssetStats::EViewerAssetCategories -asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp) -{ -	// For statistical purposes, we divide GETs into several -	// populations of asset fetches: -	//  - textures which are de-prioritized in the asset system -	//  - wearables (clothing, bodyparts) which directly affect -	//    user experiences when they log in -	//  - sounds -	//  - gestures -	//  - everything else. -	// -	llassert_always(50 == LLViewerAssetType::AT_COUNT); - -	// Multiple asset definitions are floating around so this requires some -	// maintenance and attention. -	static const LLViewerAssetStats::EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] = -		{ -			LLViewerAssetStats::EVACTextureTempHTTPGet,			// (0) AT_TEXTURE -			LLViewerAssetStats::EVACSoundUDPGet,				// AT_SOUND -			LLViewerAssetStats::EVACOtherGet,					// AT_CALLINGCARD -			LLViewerAssetStats::EVACOtherGet,					// AT_LANDMARK -			LLViewerAssetStats::EVACOtherGet,					// AT_SCRIPT -			LLViewerAssetStats::EVACWearableUDPGet,				// AT_CLOTHING -			LLViewerAssetStats::EVACOtherGet,					// AT_OBJECT -			LLViewerAssetStats::EVACOtherGet,					// AT_NOTECARD -			LLViewerAssetStats::EVACOtherGet,					// AT_CATEGORY -			LLViewerAssetStats::EVACOtherGet,					// AT_ROOT_CATEGORY -			LLViewerAssetStats::EVACOtherGet,					// (10) AT_LSL_TEXT -			LLViewerAssetStats::EVACOtherGet,					// AT_LSL_BYTECODE -			LLViewerAssetStats::EVACOtherGet,					// AT_TEXTURE_TGA -			LLViewerAssetStats::EVACWearableUDPGet,				// AT_BODYPART -			LLViewerAssetStats::EVACOtherGet,					// AT_TRASH -			LLViewerAssetStats::EVACOtherGet,					// AT_SNAPSHOT_CATEGORY -			LLViewerAssetStats::EVACOtherGet,					// AT_LOST_AND_FOUND -			LLViewerAssetStats::EVACSoundUDPGet,				// AT_SOUND_WAV -			LLViewerAssetStats::EVACOtherGet,					// AT_IMAGE_TGA -			LLViewerAssetStats::EVACOtherGet,					// AT_IMAGE_JPEG -			LLViewerAssetStats::EVACGestureUDPGet,				// (20) AT_ANIMATION -			LLViewerAssetStats::EVACGestureUDPGet,				// AT_GESTURE -			LLViewerAssetStats::EVACOtherGet,					// AT_SIMSTATE -			LLViewerAssetStats::EVACOtherGet,					// AT_FAVORITE -			LLViewerAssetStats::EVACOtherGet,					// AT_LINK -			LLViewerAssetStats::EVACOtherGet,					// AT_LINK_FOLDER -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					// (30) -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					// (40) -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					// -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					//  -			LLViewerAssetStats::EVACOtherGet,					// AT_MESH -																// (50) -		}; -	 -	if (at < 0 || at >= LLViewerAssetType::AT_COUNT) -	{ -		return LLViewerAssetStats::EVACOtherGet; -	} -	LLViewerAssetStats::EViewerAssetCategories ret(asset_to_bin_map[at]); -	if (LLViewerAssetStats::EVACTextureTempHTTPGet == ret) -	{ -		// Indexed with [is_temp][with_http] -		static const LLViewerAssetStats::EViewerAssetCategories texture_bin_map[2][2] = -			{ -				{ -					LLViewerAssetStats::EVACTextureNonTempUDPGet, -					LLViewerAssetStats::EVACTextureNonTempHTTPGet, -				}, -				{ -					LLViewerAssetStats::EVACTextureTempUDPGet, -					LLViewerAssetStats::EVACTextureTempHTTPGet, -				} -			}; - -		ret = texture_bin_map[is_temp][with_http]; -	} -	return ret; -} -} // anonymous namespace +LLViewerAssetStats::AssetRequestType::AssetRequestType()  +:	enqueued("enqueued"), +	dequeued("dequeued"), +	resp_count("resp_count"), +	resp_min("resp_min"), +	resp_max("resp_max"), +	resp_mean("resp_mean") +{} + +LLViewerAssetStats::FPSStats::FPSStats()  +:	count("count"), +	min("min"), +	max("max"), +	mean("mean") +{} + +LLViewerAssetStats::RegionStats::RegionStats()  +:	get_texture_temp_http("get_texture_temp_http"), +	get_texture_temp_udp("get_texture_temp_udp"), +	get_texture_non_temp_http("get_texture_non_temp_http"), +	get_texture_non_temp_udp("get_texture_non_temp_udp"), +	get_wearable_udp("get_wearable_udp"), +	get_sound_udp("get_sound_udp"), +	get_gesture_udp("get_gesture_udp"), +	get_other("get_other"), +	fps("fps"), +	grid_x("grid_x"), +	grid_y("grid_y"), +	duration("duration") +{} + +LLViewerAssetStats::AssetStats::AssetStats()  +:	regions("regions"), +	duration("duration"), +	session_id("session_id"), +	agent_id("agent_id"), +	message("message"), +	sequence("sequence"), +	initial("initial"), +	break_("break") +{} diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index e4581d2120..1a8770f8a7 100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h @@ -37,6 +37,8 @@  #include "llsimplestat.h"  #include "llsd.h"  #include "llvoavatar.h" +#include "lltrace.h" +#include "llinitparam.h"  /**   * @class LLViewerAssetStats @@ -73,29 +75,15 @@   * LLViewerAssetStatsFF is provided for conditional test-and-call   * operations.   */ -class LLViewerAssetStats +class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats>  {  public: -	enum EViewerAssetCategories -	{ -		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP -		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP -		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP -		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP -		EVACWearableUDPGet,				//< Wearable GETs -		EVACSoundUDPGet,				//< Sound GETs -		EVACGestureUDPGet,				//< Gesture GETs -		EVACOtherGet,					//< Other GETs -		 -		EVACCount						// Must be last -	}; -  	/**  	 * Type for duration and other time values in the metrics.  Selected  	 * for compatibility with the pre-existing timestamp on the texture  	 * fetcher class, LLTextureFetch.  	 */ -	typedef U64 duration_t; +	typedef LLUnit<LLUnits::Microseconds, U64> duration_t;  	/**  	 * Type for the region identifier used in stats.  Currently uses @@ -104,64 +92,65 @@ public:  	 */  	typedef U64 region_handle_t; -	/** -	 * @brief Collected data for a single region visited by the avatar. -	 * -	 * Fairly simple, for each asset bin enumerated above a count -	 * of enqueue and dequeue operations and simple stats on response -	 * times for completed requests. -	 */ -	class PerRegionStats : public LLRefCount +	struct AssetRequestType : public LLInitParam::Block<AssetRequestType>  	{ -	public: -		PerRegionStats(const region_handle_t region_handle) -			: LLRefCount(), -			  mRegionHandle(region_handle) -			{ -				reset(); -			} - -		PerRegionStats(const PerRegionStats & src) -			: LLRefCount(), -			  mRegionHandle(src.mRegionHandle), -			  mTotalTime(src.mTotalTime), -			  mStartTimestamp(src.mStartTimestamp), -			  mFPS(src.mFPS) -			{ -				for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i) -				{ -					mRequests[i] = src.mRequests[i]; -				} -			} - -		// Default assignment and destructor are correct. -		 -		void reset(); +		Mandatory<S32>	enqueued, +						dequeued, +						resp_count; +		Mandatory<F64>	resp_min, +						resp_max, +						resp_mean; +	 +		AssetRequestType(); +	}; -		void merge(const PerRegionStats & src); +	struct FPSStats : public LLInitParam::Block<FPSStats> +	{ +		Mandatory<S32>	count; +		Mandatory<F64>	min, +						max, +						mean; +		FPSStats(); +	}; + +	struct RegionStats : public LLInitParam::Block<RegionStats> +	{ +		Optional<AssetRequestType>	get_texture_temp_http, +									get_texture_temp_udp, +									get_texture_non_temp_http, +									get_texture_non_temp_udp, +									get_wearable_udp, +									get_sound_udp, +									get_gesture_udp, +									get_other; +		Optional<FPSStats>			fps; +		Optional<S32>				grid_x, +									grid_y; +		Optional<F64>				duration; + +		RegionStats(); +	}; + +	struct AssetStats : public LLInitParam::Block<AssetStats> +	{ +		Multiple<RegionStats>	regions; +		Mandatory<F64>			duration; -		// Apply current running time to total and reset start point. -		// Return current timestamp as a convenience. -		void accumulateTime(duration_t now); +		Mandatory<LLUUID>		session_id, +								agent_id; -	public: -		region_handle_t		mRegionHandle; -		duration_t			mTotalTime; -		duration_t			mStartTimestamp; -		LLSimpleStatMMM<>	mFPS; +		Mandatory<std::string>	message; +		Mandatory<S32>			sequence; +		Mandatory<bool>			initial, +								break_; -		struct prs_group -		{ -			LLSimpleStatCounter			mEnqueued; -			LLSimpleStatCounter			mDequeued; -			LLSimpleStatMMM<duration_t>	mResponse; -		} -		mRequests [EVACCount]; +		AssetStats();  	};  public:  	LLViewerAssetStats();  	LLViewerAssetStats(const LLViewerAssetStats &); +  	// Default destructor is correct.  	LLViewerAssetStats & operator=(const LLViewerAssetStats &);			// Not defined @@ -174,88 +163,32 @@ public:  	// collection calls.  	void setRegion(region_handle_t region_handle); -	// Asset GET Requests -	void recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp); -	void recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp); -	void recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration); - -	// Frames-Per-Second Samples -	void recordFPS(F32 fps); - -	// Avatar-related statistics -	void recordAvatarStats(); - -	// Merge a source instance into a destination instance.  This is -	// conceptually an 'operator+=()' method: -	// - counts are added -	// - minimums are min'd -	// - maximums are max'd -	// - other scalars are ignored ('this' wins) -	// -	void merge(const LLViewerAssetStats & src); +	// gather latest metrics data +	// call from main thread +	void updateStats();  	// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded) -    // Returned LLSD is structured as follows: -	// -	// &stats_group = { -	//   enqueued   : int, -	//   dequeued   : int, -	//   resp_count : int, -	//   resp_min   : float, -	//   resp_max   : float, -	//   resp_mean  : float -	// } -	// -	// &mmm_group = { -	//   count : int, -	//   min   : float, -	//   max   : float, -	//   mean  : float -	// } -	// -	// { -	//   duration: int -	//   regions: { -	//     $: {			// Keys are strings of the region's handle in hex -	//       duration:                 : int, -	//		 fps:					   : &mmm_group, -	//       get_texture_temp_http     : &stats_group, -	//       get_texture_temp_udp      : &stats_group, -	//       get_texture_non_temp_http : &stats_group, -	//       get_texture_non_temp_udp  : &stats_group, -	//       get_wearable_udp          : &stats_group, -	//       get_sound_udp             : &stats_group, -	//       get_gesture_udp           : &stats_group, -	//       get_other                 : &stats_group -	//     } -	//   } -	// } -	// -	// @param	compact_output		If true, omits from conversion any mmm_block -	//								or stats_block that would contain all zero data. -	//								Useful for transmission when the receiver knows -	//								what is expected and will assume zero for missing -	//								blocks. +    // Uses AssetStats structure seen above +	void getStats(AssetStats& stats, bool compact_output);  	LLSD asLLSD(bool compact_output);  protected: -	typedef std::map<region_handle_t, LLPointer<PerRegionStats> > PerRegionContainer; +	void handleStart(); +	void handleStop(); +	void handleReset(); + +	typedef std::map<region_handle_t, LLTrace::Recording > PerRegionRecordingContainer;  	// Region of the currently-active region.  Always valid but may  	// be zero after construction or when explicitly set.  Unchanged  	// by a reset() call.  	region_handle_t mRegionHandle; -	// Pointer to metrics collection for currently-active region.  Always -	// valid and unchanged after reset() though contents will be changed. -	// Always points to a collection contained in mRegionStats. -	LLPointer<PerRegionStats> mCurRegionStats; +	// Pointer to metrics collection for currently-active region.   +	LLTrace::Recording*			mCurRecording;  	// Metrics data for all regions during one collection cycle -	PerRegionContainer mRegionStats; - -	// Time of last reset -	duration_t mResetTimestamp; +	PerRegionRecordingContainer mRegionRecordings;  }; @@ -273,12 +206,24 @@ protected:   *  - Main:  main() program execution thread   *  - Thread1:  TextureFetch worker thread   */ -extern LLViewerAssetStats * gViewerAssetStatsMain; - -extern LLViewerAssetStats * gViewerAssetStatsThread1; +extern LLViewerAssetStats * gViewerAssetStats;  namespace LLViewerAssetStatsFF  { +	enum EViewerAssetCategories +	{ +		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP +		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP +		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP +		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP +		EVACWearableUDPGet,				//< Wearable GETs +		EVACSoundUDPGet,				//< Sound GETs +		EVACGestureUDPGet,				//< Gesture GETs +		EVACOtherGet,					//< Other GETs + +		EVACCount						// Must be last +	}; +  /**   * @brief Allocation and deallocation of globals.   * @@ -303,28 +248,16 @@ inline LLViewerAssetStats::duration_t get_timestamp()  /**   * Region context, event and duration loggers for the Main thread.   */ -void set_region_main(LLViewerAssetStats::region_handle_t region_handle); +void set_region(LLViewerAssetStats::region_handle_t region_handle); -void record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp); +void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp); -void record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp); +void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp); -void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp, +void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp,  						  LLViewerAssetStats::duration_t duration); -void record_fps_main(F32 fps); - -/** - * Region context, event and duration loggers for Thread 1. - */ -void set_region_thread1(LLViewerAssetStats::region_handle_t region_handle); - -void record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp); - -void record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp); - -void record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, -						  LLViewerAssetStats::duration_t duration); +void record_avatar_stats();  } // namespace LLViewerAssetStatsFF diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index d042f62830..5c2dd20ec3 100755 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -69,12 +69,12 @@ public:  protected:  	void recordMetrics()  		{ -			if (mMetricsStartTime) +			if (mMetricsStartTime.value())  			{  				// Okay, it appears this request was used for useful things.  Record  				// the expected dequeue and duration of request processing. -				LLViewerAssetStatsFF::record_dequeue_main(mType, false, false); -				LLViewerAssetStatsFF::record_response_main(mType, false, false, +				LLViewerAssetStatsFF::record_dequeue(mType, false, false); +				LLViewerAssetStatsFF::record_response(mType, false, false,  														   (LLViewerAssetStatsFF::get_timestamp()  															- mMetricsStartTime));  				mMetricsStartTime = 0; @@ -373,7 +373,7 @@ void LLViewerAssetStorage::_queueDataRequest(  			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET);  			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f)); -			LLViewerAssetStatsFF::record_enqueue_main(atype, false, false); +			LLViewerAssetStatsFF::record_enqueue(atype, false, false);  		}  	}  	else diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 094694dc06..ffdaa21c84 100755 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -37,6 +37,7 @@  #include "llviewerwindow.h"  #include "llvoiceclient.h"  #include "llviewermedia.h" +#include "llviewerregion.h"  #include "llprogressview.h"  #include "llcallbacklist.h"  #include "llstartup.h" @@ -501,11 +502,11 @@ void audio_update_wind(bool force_update)  		// standing still.  		static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);  		LLVector3 scaled_wind_vec = gWindVec * wind_level; - +          		// Mix in the avatar's motion, subtract because when you walk north,  		// the apparent wind moves south.  		LLVector3 final_wind_vec = scaled_wind_vec - gAgent.getVelocity(); - +          		// rotate the wind vector to be listener (agent) relative  		gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal( final_wind_vec ); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index b5aa0ac92a..ebc4f09edb 100755 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -49,11 +49,15 @@  #include "llglheaders.h"  #include "llquaternion.h"  #include "llwindow.h"			// getPixelAspectRatio() +#include "lltracerecording.h"  // System includes  #include <iomanip> // for setprecision -U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; +LLTrace::CountStatHandle<> LLViewerCamera::sVelocityStat("camera_velocity"); +LLTrace::CountStatHandle<> LLViewerCamera::sAngularVelocityStat("camera_angular_velocity"); + +LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;  //glu pick matrix implementation borrowed from Mesa3D  glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport) @@ -160,11 +164,11 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er,  	F32 drot;  	rotation.getAngleAxis(&drot, &x, &y, &z); -	mVelocityStat.addValue(dpos); -	mAngularVelocityStat.addValue(drot); +	add(sVelocityStat, dpos); +	add(sAngularVelocityStat, drot); -	mAverageSpeed = mVelocityStat.getMeanPerSec() ; -	mAverageAngularSpeed = mAngularVelocityStat.getMeanPerSec() ; +	mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat, 50); +	mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat);  	mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect()));  	// update pixel meter ratio using default fov, not modified one diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index b857c7fe89..7b2887d725 100755 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -29,10 +29,10 @@  #include "llcamera.h"  #include "llsingleton.h" -#include "llstat.h"  #include "lltimer.h"  #include "m4math.h"  #include "llcoord.h" +#include "lltrace.h"  class LLViewerObject; @@ -80,7 +80,7 @@ public:  		NUM_CAMERAS  	} eCameraID; -	static U32 sCurCameraID; +	static eCameraID sCurCameraID;  	LLViewerCamera(); @@ -100,9 +100,9 @@ public:  	BOOL projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp = TRUE) const;  	BOOL projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const; -	const LLVector3* getVelocityDir() const {return &mVelocityDir;} -	LLStat *getVelocityStat() { return &mVelocityStat; } -	LLStat *getAngularVelocityStat() { return &mAngularVelocityStat; } +	LLVector3 getVelocityDir() const {return mVelocityDir;} +	static LLTrace::CountStatHandle<>* getVelocityStat()		   {return &sVelocityStat; } +	static LLTrace::CountStatHandle<>* getAngularVelocityStat()  {return &sAngularVelocityStat; }  	F32     getCosHalfFov() {return mCosHalfCameraFOV;}  	F32     getAverageSpeed() {return mAverageSpeed ;}  	F32     getAverageAngularSpeed() {return mAverageAngularSpeed;} @@ -117,9 +117,9 @@ public:  	F32 getDefaultFOV() { return mCameraFOVDefault; }  	BOOL cameraUnderWater() const; +	BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts);  	const LLVector3 &getPointOfInterest() { return mLastPointOfInterest; } -	BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts);  	F32 getPixelMeterRatio() const				{ return mPixelMeterRatio; }  	S32 getScreenPixelArea() const				{ return mScreenPixelArea; } @@ -130,12 +130,12 @@ public:  protected:  	void calcProjection(const F32 far_distance) const; -	LLStat mVelocityStat; -	LLStat mAngularVelocityStat; +	static LLTrace::CountStatHandle<> sVelocityStat; +	static LLTrace::CountStatHandle<> sAngularVelocityStat; +  	LLVector3 mVelocityDir ;  	F32       mAverageSpeed ;  	F32       mAverageAngularSpeed ; -  	mutable LLMatrix4	mProjectionMatrix;	// Cache of perspective matrix  	mutable LLMatrix4	mModelviewMatrix;  	F32					mCameraFOVDefault; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index cf59e67955..7ad4743d82 100755 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -77,6 +77,7 @@  #include "llwlparammanager.h"  #include "llwaterparammanager.h"  #include "llpostprocess.h" +#include "llscenemonitor.h"  extern LLPointer<LLViewerTexture> gStartTexture;  extern bool gShiftFrame; @@ -84,9 +85,6 @@ extern bool gShiftFrame;  LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;  // used to toggle renderer back on after teleport -const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain -const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. -const F32 TELEPORT_LOCAL_DELAY = 1.0f;  // Delay to prevent teleports after starting an in-sim teleport.  BOOL		 gTeleportDisplay = FALSE;  LLFrameTimer gTeleportDisplayTimer;  LLFrameTimer gTeleportArrivalTimer; @@ -372,7 +370,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	{  		LLFastTimer t(FTM_TELEPORT_DISPLAY);  		LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport"); -		const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. +		static LLCachedControl<F32> teleport_arrival_delay(gSavedSettings, "TeleportArrivalDelay"); +		static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay");  		S32 attach_count = 0;  		if (isAgentAvatarValid()) @@ -440,7 +439,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		case LLAgent::TELEPORT_ARRIVING:  			// Make the user wait while content "pre-caches"  			{ -				F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); +				F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / teleport_arrival_delay());  				if( arrival_fraction > 1.f )  				{  					arrival_fraction = 1.f; @@ -457,7 +456,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			// Short delay when teleporting in the same sim (progress screen active but not shown - did not  			// fall-through from TELEPORT_START)  			{ -				if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY ) +				if( gTeleportDisplayTimer.getElapsedTimeF32() > teleport_local_delay() )  				{  					//LLFirstUse::useTeleport();  					gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); @@ -607,7 +606,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		{  			LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM); -			const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time +			const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time  			gPipeline.createObjects(max_geom_update_time);  			gPipeline.processPartitionQ();  			gPipeline.updateGeom(max_geom_update_time); @@ -748,8 +747,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			{  				LLFastTimer t(FTM_IMAGE_UPDATE_CLASS); -				LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), -											LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); +				LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); +				LLTrace::CountStatHandle<>* angular_velocity_stat = LLViewerCamera::getAngularVelocityStat(); +				LLViewerTexture::updateClass(LLTrace::get_frame_recording().getPeriodMeanPerSec(*velocity_stat), +											LLTrace::get_frame_recording().getPeriodMeanPerSec(*angular_velocity_stat));  			} @@ -760,7 +761,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			{  				LLFastTimer t(FTM_IMAGE_UPDATE_LIST); -				F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time +				F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time  				max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)  				gTextureList.updateImages(max_image_decode_time);  			} @@ -802,6 +803,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			}  		} +		LLSceneMonitor::getInstance()->fetchQueryResult(); +		  		LLGLState::checkStates();  		LLGLState::checkClientArrays(); @@ -989,6 +992,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		LLPipeline::sUnderWaterRender = FALSE; +		{ +			//capture the frame buffer. +			LLSceneMonitor::getInstance()->capture(); +		} +  		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");  		if (!for_snapshot)  		{ @@ -1033,7 +1041,7 @@ void render_hud_attachments()  	// clamp target zoom level to reasonable values  	gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f);  	// smoothly interpolate current zoom level -	gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f)); +	gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLSmoothInterpolation::getInterpolant(0.03f));  	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())  	{ @@ -1221,6 +1229,15 @@ void render_ui(F32 zoom_factor, int subfield)  		glh_set_current_modelview(glh_copy_matrix(gGLLastModelView));  	} +	if(LLSceneMonitor::getInstance()->needsUpdate()) +	{ +		gGL.pushMatrix(); +		gViewerWindow->setup2DRender(); +		LLSceneMonitor::getInstance()->compare(); +		gViewerWindow->setup3DRender(); +		gGL.popMatrix(); +	} +  	{  		BOOL to_texture = gPipeline.canUseVertexShaders() &&  							LLPipeline::sRenderGlow; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index c6b28b9e5e..39f8249300 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -28,66 +28,65 @@  #include "llviewerprecompiledheaders.h"  #include "llfloaterreg.h" -  #include "llviewerfloaterreg.h" -#include "llfloaterautoreplacesettings.h" + +#include "llcommandhandler.h"  #include "llcompilequeue.h"  #include "llfasttimerview.h"  #include "llfloaterabout.h"  #include "llfloaterauction.h" +#include "llfloaterautoreplacesettings.h"  #include "llfloateravatar.h"  #include "llfloateravatarpicker.h"  #include "llfloateravatartextures.h"  #include "llfloaterbeacons.h"  #include "llfloaterbuildoptions.h" +#include "llfloaterbulkpermission.h" +#include "llfloaterbump.h"  #include "llfloaterbuy.h"  #include "llfloaterbuycontents.h"  #include "llfloaterbuycurrency.h"  #include "llfloaterbuycurrencyhtml.h"  #include "llfloaterbuyland.h" -#include "llfloaterbulkpermission.h" -#include "llfloaterbump.h"  #include "llfloaterbvhpreview.h"  #include "llfloatercamera.h"  #include "llfloaterchatvoicevolume.h"  #include "llfloaterconversationlog.h"  #include "llfloaterconversationpreview.h"  #include "llfloaterdeleteenvpreset.h" +#include "llfloaterdestinations.h"  #include "llfloaterdisplayname.h"  #include "llfloatereditdaycycle.h"  #include "llfloatereditsky.h"  #include "llfloatereditwater.h"  #include "llfloaterenvironmentsettings.h"  #include "llfloaterevent.h" -#include "llfloaterdestinations.h"  #include "llfloaterfonttest.h"  #include "llfloatergesture.h"  #include "llfloatergodtools.h"  #include "llfloatergroups.h"  #include "llfloaterhardwaresettings.h"  #include "llfloaterhelpbrowser.h" -#include "llfloaterwebcontent.h" -#include "llfloaterwebprofile.h" -#include "llfloatermediasettings.h"  #include "llfloaterhud.h"  #include "llfloaterimagepreview.h"  #include "llfloaterimsession.h"  #include "llfloaterinspect.h"  #include "llfloaterinventory.h"  #include "llfloaterjoystick.h" -#include "llfloaterlagmeter.h"  #include "llfloaterland.h"  #include "llfloaterlandholdings.h"  #include "llfloatermap.h" +#include "llfloatermediasettings.h"  #include "llfloatermemleak.h" +#include "llfloatermodelpreview.h"  #include "llfloaternamedesc.h"  #include "llfloaternotificationsconsole.h"  #include "llfloaterobjectweights.h"  #include "llfloateropenobject.h"  #include "llfloateroutbox.h"  #include "llfloaterpathfindingcharacters.h" -#include "llfloaterpathfindinglinksets.h"  #include "llfloaterpathfindingconsole.h" +#include "llfloaterpathfindinglinksets.h"  #include "llfloaterpay.h"  #include "llfloaterperms.h"  #include "llfloaterpostprocess.h" @@ -96,6 +95,7 @@  #include "llfloaterregiondebugconsole.h"  #include "llfloaterregioninfo.h"  #include "llfloaterreporter.h" +#include "llfloatersceneloadstats.h"  #include "llfloaterscriptdebug.h"  #include "llfloaterscriptlimits.h"  #include "llfloatersearch.h" @@ -110,12 +110,14 @@  #include "llfloatertestlistview.h"  #include "llfloatertexturefetchdebugger.h"  #include "llfloatertools.h" -#include "llfloatertos.h"  #include "llfloatertopobjects.h" +#include "llfloatertos.h"  #include "llfloatertoybox.h"  #include "llfloatertranslationsettings.h"  #include "llfloateruipreview.h"  #include "llfloatervoiceeffect.h" +#include "llfloaterwebcontent.h" +#include "llfloaterwebprofile.h"  #include "llfloatervoicevolume.h"  #include "llfloaterwhitelistentry.h"  #include "llfloaterwindowsize.h" @@ -136,10 +138,8 @@  #include "llpreviewscript.h"  #include "llpreviewsound.h"  #include "llpreviewtexture.h" -#include "llsyswellwindow.h"  #include "llscriptfloater.h" -#include "llfloatermodelpreview.h" -#include "llcommandhandler.h" +#include "llsyswellwindow.h"  // *NOTE: Please add files in alphabetical order to keep merges easy. @@ -231,7 +231,6 @@ void LLViewerFloaterReg::registerFloaters()  	LLNotificationsUI::registerFloater();  	LLFloaterDisplayNameUtil::registerFloater(); -	LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);  	LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);  	LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); @@ -305,6 +304,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundDevices>);  	LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);  	LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>); +	LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);  	LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);  	LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);  	LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index f6e840adcd..f4155df4d1 100755 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -501,7 +501,7 @@ void LLViewerJoystick::moveObjects(bool reset)  	};  	F32 cur_delta[6]; -	F32 time = gFrameIntervalSeconds; +	F32 time = gFrameIntervalSeconds.value();  	// avoid making ridicously big movements if there's a big drop in fps   	if (time > .2f) @@ -665,7 +665,7 @@ void LLViewerJoystick::moveAvatar(bool reset)  	};  	// time interval in seconds between this frame and the previous -	F32 time = gFrameIntervalSeconds; +	F32 time = gFrameIntervalSeconds.value();  	// avoid making ridicously big movements if there's a big drop in fps   	if (time > .2f) @@ -878,7 +878,7 @@ void LLViewerJoystick::moveFlycam(bool reset)  		gSavedSettings.getF32("FlycamAxisDeadZone6")  	}; -	F32 time = gFrameIntervalSeconds; +	F32 time = gFrameIntervalSeconds.value();  	// avoid making ridiculously big movements if there's a big drop in fps   	if (time > .2f) diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 4ecdc31e21..49ac2735ca 100755 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -161,6 +161,11 @@ void agent_push_backward( EKeystate s )  		camera_move_backward(s);  		return;  	} +	else if (gAgentAvatarp->isSitting()) +	{ +		gAgentCamera.changeCameraToThirdPerson(); +		return; +	}  	agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD);  } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index beca08203f..bb3f0fe932 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -124,6 +124,7 @@  #include "llwindow.h"  #include "llpathfindingmanager.h"  #include "boost/unordered_map.hpp" +#include "llscenemonitor.h"  using namespace LLAvatarAppearanceDefines; @@ -524,7 +525,10 @@ class LLAdvancedToggleConsole : public view_listener_t  		{  			toggle_visibility( (void*)gSceneView);  		} - +		else if ("scene monitor" == console_type) +		{ +			toggle_visibility( (void*)gSceneMonitorView); +		}  #if MEM_TRACK_MEM  		else if ("memory view" == console_type)  		{ @@ -552,9 +556,9 @@ class LLAdvancedCheckConsole : public view_listener_t  		{  			new_value = LLFloaterReg::instanceVisible("fast_timers");  		} -		else if ("scene view" == console_type) +		else if ("scene monitor" == console_type)  		{ -			new_value = get_visibility( (void*) gSceneView); +			new_value = get_visibility( (void*) gSceneMonitorView);  		}  #if MEM_TRACK_MEM  		else if ("memory view" == console_type) @@ -3963,24 +3967,24 @@ class LLViewToggleUI : public view_listener_t  	{  		if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)  		{ -			LLNotification::Params params("ConfirmHideUI"); -			params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); -			LLSD substitutions; +		LLNotification::Params params("ConfirmHideUI"); +		params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2)); +		LLSD substitutions;  #if LL_DARWIN -			substitutions["SHORTCUT"] = "Cmd+Shift+U"; +		substitutions["SHORTCUT"] = "Cmd+Shift+U";  #else -			substitutions["SHORTCUT"] = "Ctrl+Shift+U"; +		substitutions["SHORTCUT"] = "Ctrl+Shift+U";  #endif -			params.substitutions = substitutions; +		params.substitutions = substitutions;  			if (!gSavedSettings.getBOOL("HideUIControls")) -			{ -				// hiding, so show notification -				LLNotifications::instance().add(params); -			} -			else -			{ -				LLNotifications::instance().forceResponse(params, 0); -			} +		{ +			// hiding, so show notification +			LLNotifications::instance().add(params); +		} +		else +		{ +			LLNotifications::instance().forceResponse(params, 0); +		}  		}  		return true;  	} @@ -4027,72 +4031,6 @@ void handle_duplicate_in_place(void*)  	LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE);  } -/* dead code 30-apr-2008 -void handle_deed_object_to_group(void*) -{ -	LLUUID group_id; -	 -	LLSelectMgr::getInstance()->selectGetGroup(group_id); -	LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE); -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT); -} - -BOOL enable_deed_object_to_group(void*) -{ -	if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) return FALSE; -	LLPermissions perm; -	LLUUID group_id; - -	if (LLSelectMgr::getInstance()->selectGetGroup(group_id) && -		gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && -		LLSelectMgr::getInstance()->selectGetPermissions(perm) && -		perm.deedToGroup(gAgent.getID(), group_id)) -	{ -		return TRUE; -	} -	return FALSE; -} - -*/ - - -/* - * No longer able to support viewer side manipulations in this way - * -void god_force_inv_owner_permissive(LLViewerObject* object, -									LLInventoryObject::object_list_t* inventory, -									S32 serial_num, -									void*) -{ -	typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t; -	item_array_t items; - -	LLInventoryObject::object_list_t::const_iterator inv_it = inventory->begin(); -	LLInventoryObject::object_list_t::const_iterator inv_end = inventory->end(); -	for ( ; inv_it != inv_end; ++inv_it) -	{ -		if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY)) -		{ -			LLInventoryObject* obj = *inv_it; -			LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj); -			LLPermissions perm(new_item->getPermissions()); -			perm.setMaskBase(PERM_ALL); -			perm.setMaskOwner(PERM_ALL); -			new_item->setPermissions(perm); -			items.push_back(new_item); -		} -	} -	item_array_t::iterator end = items.end(); -	item_array_t::iterator it; -	for(it = items.begin(); it != end; ++it) -	{ -		// since we have the inventory item in the callback, it should not -		// invalidate iteration through the selection manager. -		object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false); -	} -} -*/ -  void handle_object_owner_permissive(void*)  {  	// only send this if they're a god. @@ -7370,7 +7308,7 @@ void handle_dump_avatar_local_textures(void*)  void handle_dump_timers()  { -	LLFastTimer::dumpCurTimes(); +	LLTrace::TimeBlock::dumpCurTimes();  }  void handle_debug_avatar_textures(void*) @@ -7611,6 +7549,23 @@ void handle_web_browser_test(const LLSD& param)  	LLWeb::loadURLInternal(url);  } +bool callback_clear_cache_immediately(const LLSD& notification, const LLSD& response) +{ +	S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +	if ( option == 0 ) // YES +	{ +		//clear cache +		LLAppViewer::instance()->purgeCacheImmediate(); +	} + +	return false; +} + +void handle_cache_clear_immediately() +{ +	LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately); +} +  void handle_web_content_test(const LLSD& param)  {  	std::string url = param.asString(); @@ -8340,10 +8295,10 @@ void initialize_menus()  	view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway");  	view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");  	view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); -	 +  	// Me > Movement  	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying"); - +	  	// Communicate > Voice morphing > Subscribe...  	commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));  	LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance(); @@ -8351,7 +8306,7 @@ void initialize_menus()  		, boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));  	commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click"  		, boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing")); - +	  	// World menu  	view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");  	view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark"); @@ -8577,6 +8532,8 @@ void initialize_menus()  	//Develop (Texture Fetch Debug Console)  	view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger"); +	//Develop (clear cache immediately) +	commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );  	// Admin >Object  	view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index be78603e2d..b7282a8493 100755 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -1096,17 +1096,17 @@ void upload_new_resource(  	if( LLAssetType::AT_SOUND == asset_type )  	{ -		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT ); +		add(LLStatViewer::UPLOAD_SOUND, 1);  	}  	else  	if( LLAssetType::AT_TEXTURE == asset_type )  	{ -		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); +		add(LLStatViewer::UPLOAD_TEXTURE, 1);  	}  	else  	if( LLAssetType::AT_ANIMATION == asset_type)  	{ -		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT ); +		add(LLStatViewer::ANIMATION_UPLOADS, 1);  	}  	if(LLInventoryType::IT_NONE == inv_type) @@ -1231,18 +1231,15 @@ void increase_new_upload_stats(LLAssetType::EType asset_type)  {  	if ( LLAssetType::AT_SOUND == asset_type )  	{ -		LLViewerStats::getInstance()->incStat( -			LLViewerStats::ST_UPLOAD_SOUND_COUNT ); +		add(LLStatViewer::UPLOAD_SOUND, 1);  	}  	else if ( LLAssetType::AT_TEXTURE == asset_type )  	{ -		LLViewerStats::getInstance()->incStat( -			LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); +		add(LLStatViewer::UPLOAD_TEXTURE, 1);  	}  	else if ( LLAssetType::AT_ANIMATION == asset_type )  	{ -		LLViewerStats::getInstance()->incStat( -			LLViewerStats::ST_UPLOAD_ANIM_COUNT ); +		add(LLStatViewer::ANIMATION_UPLOADS, 1);  	}  } diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 3136358b83..3034d00b22 100755 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -31,6 +31,8 @@  #include "llassetstorage.h"  #include "llinventorytype.h"  #include "llfilepicker.h" +#include "llthread.h" +#include <queue>  class LLTransactionID; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ace16396db..f2a3ffc3dc 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1181,7 +1181,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)  		}  	}  } -  +  // Return "true" if we have a preview method for that asset type, "false" otherwise  bool check_asset_previewable(const LLAssetType::EType asset_type)  { @@ -1529,7 +1529,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  	from_string = chatHistory_string = mFromName;  	LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm()); - +	  	switch(button)  	{  	case IOR_SHOW: @@ -1627,7 +1627,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&  			{  				opener = discard_agent_offer;  			} - +			  			if (modified_form != NULL)  			{  				modified_form->setElementEnabled("Show", false); @@ -2376,7 +2376,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  	LLNotification::Params params;  	switch(dialog) -	{  +	{  	case IM_CONSOLE_AND_CHAT_HISTORY:  		args["MESSAGE"] = message;  		payload["from_id"] = from_id; @@ -2628,7 +2628,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				LLSD args;  				args["SUBJECT"] = subj;  				args["MESSAGE"] = mes; -				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp)); +				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(LLDate(timestamp)));  			}  			// Also send down the old path for now. @@ -3075,11 +3075,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				}  				else  				{ -			    LLNotification::Params params("TeleportOffered"); -			    params.substitutions = args; -			    params.payload = payload; -			    LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false); -			} +					LLNotification::Params params("TeleportOffered"); +					params.substitutions = args; +					params.payload = payload; +					LLPostponedNotification::add<LLPostponedOfferNotification>(	params, from_id, false); +				}  			}  		} @@ -3170,10 +3170,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  			}  			else  			{ -			// do not show a message box, because you're about to be -			// teleported. -			LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); -		} +				// do not show a message box, because you're about to be +				// teleported. +				LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); +			}  		}  		break; @@ -4129,7 +4129,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)  		{  			LLTracker::stopTracking(NULL);  		} -		else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() ) +		else if ( is_teleport && !gAgent.getTeleportKeepsLookAt() && look_at.isExactlyZero())  		{  			//look at the beacon  			LLVector3 global_agent_pos = agent_pos; @@ -4340,7 +4340,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  		msg_number += 1;  		if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)  		{ -			//LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL; +			//LL_INFOS("Messaging") << " head rot " << head_rotation << LL_ENDL;  			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL;  		}  		if (cam_rot_chg.magVec() > ROTATION_THRESHOLD)  @@ -4359,7 +4359,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  		{  			LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL;  		} -*/ +		*/  		duplicate_count = 0;  	} @@ -4480,18 +4480,18 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  // *TODO: Remove this dependency, or figure out a better way to handle  // this hack. -extern U32 gObjectBits; +extern LLUnit<LLUnits::Bits, U32> gObjectData;  void process_object_update(LLMessageSystem *mesgsys, void **user_data)  {	  	// Update the data counters  	if (mesgsys->getReceiveCompressedSize())  	{ -		gObjectBits += mesgsys->getReceiveCompressedSize() * 8; +		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize();  	}  	else  	{ -		gObjectBits += mesgsys->getReceiveSize() * 8; +		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize();  	}  	// Update the object... @@ -4503,11 +4503,11 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data  	// Update the data counters  	if (mesgsys->getReceiveCompressedSize())  	{ -		gObjectBits += mesgsys->getReceiveCompressedSize() * 8; +		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize();  	}  	else  	{ -		gObjectBits += mesgsys->getReceiveSize() * 8; +		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize();  	}  	// Update the object... @@ -4519,11 +4519,11 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)  	// Update the data counters  	if (mesgsys->getReceiveCompressedSize())  	{ -		gObjectBits += mesgsys->getReceiveCompressedSize() * 8; +		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize();  	}  	else  	{ -		gObjectBits += mesgsys->getReceiveSize() * 8; +		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize();  	}  	// Update the object... @@ -4535,11 +4535,11 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_  {  	if (mesgsys->getReceiveCompressedSize())  	{ -		gObjectBits += mesgsys->getReceiveCompressedSize() * 8; +		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize();  	}  	else  	{ -		gObjectBits += mesgsys->getReceiveSize() * 8; +		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize();  	}  	gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED); @@ -4547,30 +4547,42 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_  static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Kill Objects"); +const U32 KILLOBJECT_DELETE_OPCODE = 0; +  void process_kill_object(LLMessageSystem *mesgsys, void **user_data)  {  	LLFastTimer t(FTM_PROCESS_OBJECTS);  	LLUUID		id; -	U32			local_id; -	S32			i; -	S32			num_objects; -	num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); +	U32 ip = mesgsys->getSenderIP(); +	U32 port = mesgsys->getSenderPort(); +	LLViewerRegion* regionp = NULL; +	{ +		LLHost host(ip, port); +		regionp = LLWorld::getInstance()->getRegion(host); +	} -	for (i = 0; i < num_objects; i++) +	bool delete_object = false; +	S32	num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); +	for (S32 i = 0; i < num_objects; ++i)  	{ +		U32	local_id;  		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); +		if (local_id == KILLOBJECT_DELETE_OPCODE) +		{ +			// This local_id is invalid, but was sent by the server to flag +			// all subsequent local_id's as objects that were actually deleted +			// rather than unsubscribed from interestlist. +			delete_object = true; +			continue; +		} -		LLViewerObjectList::getUUIDFromLocal(id, -											local_id, -											gMessageSystem->getSenderIP(), -											gMessageSystem->getSenderPort()); +		LLViewerObjectList::getUUIDFromLocal(id, local_id, ip, port);   		if (id == LLUUID::null)  		{  			LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL; -			gObjectList.mNumUnknownKills++;  			continue;  		}  		else @@ -4578,9 +4590,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)  			LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;  		} -		// ...don't kill the avatar -		if (!(id == gAgentID)) +		if (id == gAgentID)  		{ +			// never kill our avatar +			continue; +		} +  			LLViewerObject *objectp = gObjectList.findObject(id);  			if (objectp)  			{ @@ -4594,18 +4609,16 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)  				// Do the kill  				gObjectList.killObject(objectp);  			} -			else + +		if(delete_object)  			{ -				LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL; -				gObjectList.mNumUnknownKills++; -			} +			regionp->killCacheEntry(local_id);  		}  		// We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab,          // which is using the object, release the mouse capture correctly when the object dies.          // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical().  		LLSelectMgr::getInstance()->removeObjectFromSelections(id); -  	}  } @@ -4817,145 +4830,18 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)  		F32 stat_value;  		msg->getU32("Stat", "StatID", stat_id, i);  		msg->getF32("Stat", "StatValue", stat_value, i); -		switch (stat_id) +		LLStatViewer::SimMeasurementSampler* measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id); +		 +		if (measurementp )  		{ -		case LL_SIM_STAT_TIME_DILATION: -			LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value); -			break; -		case LL_SIM_STAT_FPS: -			LLViewerStats::getInstance()->mSimFPS.addValue(stat_value); -			break; -		case LL_SIM_STAT_PHYSFPS: -			LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value); -			break; -		case LL_SIM_STAT_AGENTUPS: -			LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value); -			break; -		case LL_SIM_STAT_FRAMEMS: -			LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_NETMS: -			LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMOTHERMS: -			LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMPHYSICSMS: -			LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_AGENTMS: -			LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_IMAGESMS: -			LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_SCRIPTMS: -			LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_NUMTASKS: -			LLViewerStats::getInstance()->mSimObjects.addValue(stat_value); -			break; -		case LL_SIM_STAT_NUMTASKSACTIVE: -			LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value); -			break; -		case LL_SIM_STAT_NUMAGENTMAIN: -			LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value); -			break; -		case LL_SIM_STAT_NUMAGENTCHILD: -			LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value); -			break; -		case LL_SIM_STAT_NUMSCRIPTSACTIVE: -			LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value); -			break; -		case LL_SIM_STAT_SCRIPT_EPS: -			LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value); -			break; -		case LL_SIM_STAT_INPPS: -			LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value); -			break; -		case LL_SIM_STAT_OUTPPS: -			LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value); -			break; -		case LL_SIM_STAT_PENDING_DOWNLOADS: -			LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value); -			break; -		case LL_SIM_STAT_PENDING_UPLOADS: -			LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value); -			break; -		case LL_SIM_STAT_PENDING_LOCAL_UPLOADS: -			LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value); -			break; -		case LL_SIM_STAT_TOTAL_UNACKED_BYTES: -			LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f); -			break; -		case LL_SIM_STAT_PHYSICS_PINNED_TASKS: -			LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value); -			break; -		case LL_SIM_STAT_PHYSICS_LOD_TASKS: -			LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMPHYSICSSTEPMS: -			LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMPHYSICSSHAPEMS: -			LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMPHYSICSOTHERMS: -			LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMPHYSICSMEMORY: -			LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMSPARETIME: -			LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMSLEEPTIME: -			LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_IOPUMPTIME: -			LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_PCTSCRIPTSRUN: -			LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value); -			break; -		case LL_SIM_STAT_SIMAISTEPTIMEMS: -			LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value); -			break; -		case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS: -			LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value); -			break; -		case LL_SIM_STAT_PCTSTEPPEDCHARACTERS: -			LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value); -			break; -		default: -			// Used to be a commented out warning. - 			LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL; -		  break; +			measurementp->sample(stat_value); +		} +		else +		{ +			llwarns << "Unknown sim stat identifier: " << stat_id << llendl;  		}  	} -	/* -	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_PhysicsTimeDilation, time_dilation); -	LLViewerStats::getInstance()->mSimTDStat.addValue(time_dilation); - -	// Process information -	//	{	CpuUsage			F32				} -	//	{	SimMemTotal			F32				} -	//	{	SimMemRSS			F32				} -	//	{	ProcessUptime		F32				} -	F32 cpu_usage; -	F32 sim_mem_total; -	F32 sim_mem_rss; -	F32 process_uptime; -	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_CpuUsage, cpu_usage); -	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemTotal, sim_mem_total); -	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_SimMemRSS, sim_mem_rss); -	msg->getF32Fast(_PREHASH_Statistics, _PREHASH_ProcessUptime, process_uptime); -	LLViewerStats::getInstance()->mSimCPUUsageStat.addValue(cpu_usage); -	LLViewerStats::getInstance()->mSimMemTotalStat.addValue(sim_mem_total); -	LLViewerStats::getInstance()->mSimMemRSSStat.addValue(sim_mem_rss); -	*/ -  	//  	// Various hacks that aren't statistics, but are being handled here.  	// @@ -5864,7 +5750,7 @@ bool handle_teleport_access_blocked(LLSD& llsdBlock)  			maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);  			returnValue = true;  		} -		} +	}  	if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored())  	{ @@ -6010,7 +5896,7 @@ void process_alert_core(const std::string& message, BOOL modal)  	// HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml  	if ( message == "You died and have been teleported to your home location")  	{ -		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT); +		add(LLStatViewer::KILLED, 1);  	}  	else if( message == "Home position set." )  	{ @@ -6030,8 +5916,8 @@ void process_alert_core(const std::string& message, BOOL modal)  		std::string alert_name(message.substr(ALERT_PREFIX.length()));  		if (!handle_special_alerts(alert_name))  		{ -		LLNotificationsUtil::add(alert_name); -	} +			LLNotificationsUtil::add(alert_name); +		}  	}  	else if (message.find(NOTIFY_PREFIX) == 0)  	{ @@ -6484,7 +6370,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)  			args["DOWNLOADURL"] = LLTrans::getString("ViewerDownloadURL");  			LLNotificationsUtil::add("UnknownScriptQuestion",args,payload);  		} -		 +  		if (known_questions)  		{  			LLSD payload; @@ -7471,8 +7357,6 @@ void onCovenantLoadComplete(LLVFS *vfs,  	}  	else  	{ -		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED ); -		  		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||  		    LL_ERR_FILE_EMPTY == status)  		{ diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 064e96e394..9e6d8e78d1 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -39,6 +39,7 @@  #include "llfloaterreg.h"  #include "llfontgl.h"  #include "llframetimer.h" +#include "llhudicon.h"  #include "llinventory.h"  #include "llinventorydefines.h"  #include "llmaterialtable.h" @@ -100,6 +101,7 @@  #include "lltrans.h"  #include "llsdutil.h"  #include "llmediaentry.h" +#include "llvocache.h"  //#define DEBUG_UPDATE_TYPE @@ -112,6 +114,9 @@ BOOL		LLViewerObject::sMapDebug = TRUE;  LLColor4	LLViewerObject::sEditSelectColor(	1.0f, 1.f, 0.f, 0.3f);	// Edit OK  LLColor4	LLViewerObject::sNoEditSelectColor(	1.0f, 0.f, 0.f, 0.3f);	// Can't edit  S32			LLViewerObject::sAxisArrowLength(50); +LLTrace::MemStatHandle	LLViewerObject::sMemStat("LLViewerObject"); + +  BOOL		LLViewerObject::sPulseEnabled(FALSE);  BOOL		LLViewerObject::sUseSharedDrawables(FALSE); // TRUE @@ -119,6 +124,7 @@ BOOL		LLViewerObject::sUseSharedDrawables(FALSE); // TRUE  F64			LLViewerObject::sMaxUpdateInterpolationTime = 3.0;		// For motion interpolation: after X seconds with no updates, don't predict object motion  F64			LLViewerObject::sPhaseOutUpdateInterpolationTime = 2.0;	// For motion interpolation: after Y seconds with no updates, taper off motion prediction +std::map<std::string, U32> LLViewerObject::sObjectDataMap;  static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object"); @@ -481,6 +487,8 @@ void LLViewerObject::initVOClasses()  	LLVOGrass::initClass();  	LLVOWater::initClass();  	LLVOVolume::initClass(); + +	initObjectDataMap();  }  void LLViewerObject::cleanupVOClasses() @@ -490,6 +498,118 @@ void LLViewerObject::cleanupVOClasses()  	LLVOTree::cleanupClass();  	LLVOAvatar::cleanupClass();  	LLVOVolume::cleanupClass(); + +	sObjectDataMap.clear(); +} + +//object data map for compressed && !OUT_TERSE_IMPROVED +//static +void LLViewerObject::initObjectDataMap() +{ +	U32 count = 0; + +	sObjectDataMap["ID"] = count; //full id //LLUUID +	count += sizeof(LLUUID); + +	sObjectDataMap["LocalID"] = count; //U32 +	count += sizeof(U32); + +	sObjectDataMap["PCode"] = count;   //U8 +	count += sizeof(U8); + +	sObjectDataMap["State"] = count;   //U8 +	count += sizeof(U8); + +	sObjectDataMap["CRC"] = count;     //U32 +	count += sizeof(U32); + +	sObjectDataMap["Material"] = count; //U8 +	count += sizeof(U8); + +	sObjectDataMap["ClickAction"] = count; //U8 +	count += sizeof(U8); + +	sObjectDataMap["Scale"] = count; //LLVector3 +	count += sizeof(LLVector3); + +	sObjectDataMap["Pos"] = count;   //LLVector3 +	count += sizeof(LLVector3); + +	sObjectDataMap["Rot"] = count;    //LLVector3 +	count += sizeof(LLVector3); + +	sObjectDataMap["SpecialCode"] = count; //U32 +	count += sizeof(U32); + +	sObjectDataMap["Owner"] = count; //LLUUID +	count += sizeof(LLUUID); + +	sObjectDataMap["Omega"] = count; //LLVector3, when SpecialCode & 0x80 is set +	count += sizeof(LLVector3); + +	//ParentID is after Omega if there is Omega, otherwise is after Owner +	sObjectDataMap["ParentID"] = count;//U32, when SpecialCode & 0x20 is set +	count += sizeof(U32); + +	//------- +	//The rest items are not included here +	//------- +} + +//static  +void LLViewerObject::unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name) +{ +	dp->shift(sObjectDataMap[name]); +	dp->unpackVector3(value, name.c_str()); +	dp->reset(); +} + +//static  +void LLViewerObject::unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name) +{ +	dp->shift(sObjectDataMap[name]); +	dp->unpackUUID(value, name.c_str()); +	dp->reset(); +} +	 +//static  +void LLViewerObject::unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name) +{ +	dp->shift(sObjectDataMap[name]); +	dp->unpackU32(value, name.c_str()); +	dp->reset(); +} +	 +//static  +void LLViewerObject::unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name) +{ +	dp->shift(sObjectDataMap[name]); +	dp->unpackU8(value, name.c_str()); +	dp->reset(); +} + +//static  +U32 LLViewerObject::unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id) +{ +	dp->shift(sObjectDataMap["SpecialCode"]); +	U32 value; +	dp->unpackU32(value, "SpecialCode"); + +	parent_id = 0; +	if(value & 0x20) +	{ +		S32 offset = sObjectDataMap["ParentID"]; +		if(!(value & 0x80)) +		{ +			offset -= sizeof(LLVector3); +		} + +		dp->shift(offset); +		dp->unpackU32(parent_id, "ParentID"); +	} +	dp->reset(); + +	return parent_id;  }  // Replaces all name value pairs with data from \n delimited list @@ -870,6 +990,29 @@ U32 LLViewerObject::checkMediaURL(const std::string &media_url)      return retval;  } +//extract spatial information from object update message +//return parent_id +//static +U32 LLViewerObject::extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot) +{ +	U32	parent_id = 0; +	LLViewerObject::unpackParentID(dp, parent_id); +	if(parent_id > 0) +	{ +		//is a child, no need to decode further. +		return parent_id; +	} + +	LLViewerObject::unpackVector3(dp, scale, "Scale"); +	LLViewerObject::unpackVector3(dp, pos, "Pos"); +	 +	LLVector3 vec; +	LLViewerObject::unpackVector3(dp, vec, "Rot"); +	rot.unpackFromVector3(vec); +	 +	return parent_id; +} +  U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  					 void **user_data,  					 U32 block_num, @@ -886,10 +1029,11 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	}  	// Coordinates of objects on simulators are region-local. -	U64 region_handle; -	mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); +	U64 region_handle = 0;	 +	if(mesgsys != NULL)  	{ +		mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);  		LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle);  		if(regionp != mRegionp && regionp && mRegionp)//region cross  		{ @@ -915,11 +1059,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  		return retval;  	} +	if(mesgsys != NULL) +	{  	U16 time_dilation16;  	mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);  	F32 time_dilation = ((F32) time_dilation16) / 65535.f;  	mTimeDilation = time_dilation;  	mRegionp->setTimeDilation(time_dilation); +	}  	// this will be used to determine if we've really changed position  	// Use getPosition, not getPositionRegion, since this is what we're comparing directly against. @@ -1692,13 +1839,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				// Preload these five flags for every object.  				// Finer shades require the object to be selected, and the selection manager  				// stores the extended permission info. -				U32 flags; -				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); -				// keep local flags and overwrite remote-controlled flags -				mFlags = (mFlags & FLAGS_LOCAL) | flags; - -					// ...new objects that should come in selected need to be added to the selected list -				mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); +				if(mesgsys != NULL) +				{ +					U32 flags; +					mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, block_num); +					loadFlags(flags);					 +				}  			}  			break; @@ -1726,10 +1872,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  			{  				// No parent now, new parent in message -> attach to that parent if possible  				LLUUID parent_uuid; + +				if(mesgsys != NULL) +				{  				LLViewerObjectList::getUUIDFromLocal(parent_uuid,  														parent_id,  														mesgsys->getSenderIP(),  														mesgsys->getSenderPort()); +				} +				else +				{ +					LLViewerObjectList::getUUIDFromLocal(parent_uuid, +														parent_id, +														mRegionp->getHost().getAddress(), +														mRegionp->getHost().getPort()); +				}  				LLViewerObject *sent_parentp = gObjectList.findObject(parent_uuid); @@ -1805,9 +1962,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  					//  					//parent_id -					U32 ip = mesgsys->getSenderIP(); -					U32 port = mesgsys->getSenderPort(); +					U32 ip, port;  +					if(mesgsys != NULL) +					{ +						ip = mesgsys->getSenderIP(); +						port = mesgsys->getSenderPort(); +					} +					else +					{ +						ip = mRegionp->getHost().getAddress(); +						port = mRegionp->getHost().getPort(); +					}  					gObjectList.orphanize(this, parent_id, ip, port);  					// Hide particles, icon and HUD @@ -1845,10 +2011,21 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  				else  				{  					LLUUID parent_uuid; + +					if(mesgsys != NULL) +					{  					LLViewerObjectList::getUUIDFromLocal(parent_uuid,  														parent_id,  														gMessageSystem->getSenderIP(),  														gMessageSystem->getSenderPort()); +					} +					else +					{ +						LLViewerObjectList::getUUIDFromLocal(parent_uuid, +														parent_id, +														mRegionp->getHost().getAddress(), +														mRegionp->getHost().getPort()); +					}  					sent_parentp = gObjectList.findObject(parent_uuid);  					if (isAvatar()) @@ -1869,8 +2046,18 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  						//  						// Switching parents, but we don't know the new parent.  						// -						U32 ip = mesgsys->getSenderIP(); -						U32 port = mesgsys->getSenderPort(); +						U32 ip, port;  +					 +						if(mesgsys != NULL) +						{ +							ip = mesgsys->getSenderIP(); +							port = mesgsys->getSenderPort(); +						} +						else +						{ +							ip = mRegionp->getHost().getAddress(); +							port = mRegionp->getHost().getPort(); +						}  						// We're an orphan, flag things appropriately.  						gObjectList.orphanize(this, parent_id, ip, port); @@ -1954,7 +2141,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	new_rot.normQuat(); -	if (sPingInterpolate) +	if (sPingInterpolate && mesgsys != NULL)  	{   		LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());  		if (cdp) @@ -1977,6 +2164,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  	// If we're going to skip this message, why are we   	// doing all the parenting, etc above? +	if(mesgsys != NULL) +	{  	U32 packet_id = mesgsys->getCurrentRecvPacketID();   	if (packet_id < mLatestRecvPacketID &&   		mLatestRecvPacketID - packet_id < 65536) @@ -1984,8 +2173,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  		//skip application of this message, it's old  		return retval;  	} -  	mLatestRecvPacketID = packet_id; +	}  	// Set the change flags for scale  	if (new_scale != getScale()) @@ -2033,7 +2222,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,  		// If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps  		if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )  		{ -			LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() ); +			record(LLStatViewer::AGENT_POSITION_SNAP, LLTrace::Meters(diff.length()));  		}  	} @@ -2156,7 +2345,21 @@ BOOL LLViewerObject::isActive() const  	return TRUE;  } +//load flags from cache or from message +void LLViewerObject::loadFlags(U32 flags) +{ +	if(flags == (U32)(-1)) +	{ +		return; //invalid +	} +	// keep local flags and overwrite remote-controlled flags +	mFlags = (mFlags & FLAGS_LOCAL) | flags; + +	// ...new objects that should come in selected need to be added to the selected list +	mCreateSelected = ((flags & FLAGS_CREATE_SELECTED) != 0); +	return; +}  void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)  { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 316dbce7d0..41a559c19d 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -30,8 +30,7 @@  #include <map>  #include "llassetstorage.h" -#include "lldarrayptr.h" -#include "llhudicon.h" +//#include "llhudicon.h"  #include "llinventory.h"  #include "llrefcount.h"  #include "llprimitive.h" @@ -43,33 +42,30 @@  #include "v3math.h"  #include "llvertexbuffer.h"  #include "llbbox.h" -#include "llbbox.h"  class LLAgent;			// TODO: Get rid of this.  class LLAudioSource;  class LLAudioSourceVO; -class LLDataPacker;  class LLColor4; -class LLFrameTimer; +class LLDataPacker; +class LLDataPackerBinaryBuffer;  class LLDrawable; -class LLHost;  class LLHUDText; -class LLWorld; -class LLNameValue; -class LLNetMap; +class LLHost;  class LLMessageSystem; +class LLNameValue;  class LLPartSysData; -class LLPrimitive;  class LLPipeline;  class LLTextureEntry; -class LLViewerTexture; +class LLVOAvatar; +class LLVOInventoryListener;  class LLViewerInventoryItem;  class LLViewerObject; +class LLViewerObjectMedia;  class LLViewerPartSourceScript;  class LLViewerRegion; -class LLViewerObjectMedia; -class LLVOInventoryListener; -class LLVOAvatar; +class LLViewerTexture; +class LLWorld;  typedef enum e_object_update_type  { @@ -107,7 +103,11 @@ struct PotentialReturnableObject  //============================================================================ -class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate +class LLViewerObject  +:	public LLPrimitive,  +	public LLRefCount,  +	public LLGLUpdate, +	public LLTrace::MemTrackable<LLViewerObject>  {  protected:  	~LLViewerObject(); // use unref() @@ -157,6 +157,7 @@ public:          INVALID_UPDATE = 0x80000000      }; +	static  U32     extractSpatialExtents(LLDataPackerBinaryBuffer *dp, LLVector3& pos, LLVector3& scale, LLQuaternion& rot);  	virtual U32		processUpdateMessage(LLMessageSystem *mesgsys,  										void **user_data,  										U32 block_num, @@ -505,6 +506,7 @@ public:  	virtual void	updateRegion(LLViewerRegion *regionp);  	void updateFlags(BOOL physics_changed = FALSE); +	void loadFlags(U32 flags); //load flags from cache or from message  	BOOL setFlags(U32 flag, BOOL state);  	BOOL setFlagsWithoutUpdate(U32 flag, BOOL state);  	void setPhysicsShapeType(U8 type); @@ -535,6 +537,13 @@ public:  	friend class LLViewerMediaList;  public: +	static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name); +	static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name); +	static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name); +	static void unpackU8(LLDataPackerBinaryBuffer* dp, U8& value, std::string name); +	static U32 unpackParentID(LLDataPackerBinaryBuffer* dp, U32& parent_id); + +public:  	//counter-translation  	void resetChildrenPosition(const LLVector3& offset, BOOL simplified = FALSE) ;  	//counter-rotation @@ -557,6 +566,8 @@ private:  	// Motion prediction between updates  	void interpolateLinearMotion(const F64 & time, const F32 & dt); +	static void initObjectDataMap(); +  public:  	//  	// Viewer-side only types - use the LL_PCODE_APP mask. @@ -605,6 +616,7 @@ private:  	// Grabbed from UPDATE_FLAGS  	U32				mFlags; +	static std::map<std::string, U32> sObjectDataMap;  public:  	// Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties  	U8              mPhysicsShapeType; @@ -628,9 +640,10 @@ public:  	// TODO: Make all this stuff private.  JC  	LLPointer<LLHUDText> mText; -	LLPointer<LLHUDIcon> mIcon; +	LLPointer<class LLHUDIcon> mIcon;  	static			BOOL		sUseSharedDrawables; +	static	LLTrace::MemStatHandle	sMemStat;  protected:  	// delete an item in the inventory, but don't tell the @@ -666,8 +679,6 @@ protected:  	void deleteParticleSource();  	void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); -public: -		  private:  	void setNameValueList(const std::string& list);		// clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string  	void deleteTEImages(); // correctly deletes list of images @@ -746,6 +757,7 @@ protected:  	static			S32			sAxisArrowLength; +  	// These two caches are only correct for non-parented objects right now!  	mutable LLVector3		mPositionRegion;  	mutable LLVector3		mPositionAgent; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index caacf26cb3..546a7acfc6 100755 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -47,6 +47,7 @@  #include "lltooltip.h"  #include "llworld.h"  #include "llstring.h" +#include "llhudicon.h"  #include "llhudnametag.h"  #include "lldrawable.h"  #include "llflexibleobject.h" @@ -76,6 +77,7 @@  #include "object_flags.h"  #include "llappviewer.h" +#include "llvocache.h"  extern F32 gMinObjectDistance;  extern BOOL gAnimateTextures; @@ -93,7 +95,7 @@ extern LLPipeline	gPipeline;  U32						LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check.  std::map<U64, U32>		LLViewerObjectList::sIPAndPortToIndex;  std::map<U64, LLUUID>	LLViewerObjectList::sIndexAndLocalIDToUUID; -LLStat					LLViewerObjectList::sCacheHitRate("object_cache_hits", 128); +LLTrace::SampleStatHandle<>	LLViewerObjectList::sCacheHitRate("object_cache_hits");  LLViewerObjectList::LLViewerObjectList()  { @@ -106,7 +108,6 @@ LLViewerObjectList::LLViewerObjectList()  	mNumNewObjects = 0;  	mWasPaused = FALSE;  	mNumDeadObjectUpdates = 0; -	mNumUnknownKills = 0;  	mNumUnknownUpdates = 0;  } @@ -228,9 +229,15 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,  										   U32 i,   										   const EObjectUpdateType update_type,   										   LLDataPacker* dpp,  -										   BOOL just_created) +										   bool just_created, +										   bool from_cache)  { -	LLMessageSystem* msg = gMessageSystem; +	LLMessageSystem* msg = NULL; +	 +	if(!from_cache) +	{ +		msg = gMessageSystem; +	}  	// ignore returned flags  	objectp->processUpdateMessage(msg, user_data, i, update_type, dpp); @@ -254,7 +261,18 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,  	// RN: this must be called after we have a drawable   	// (from gPipeline.addObject)  	// so that the drawable parent is set properly -	findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); +	if(msg != NULL) +	{ +		findOrphans(objectp, msg->getSenderIP(), msg->getSenderPort()); +	} +	else +	{ +		LLViewerRegion* regionp = objectp->getRegion(); +		if(regionp != NULL) +		{ +			findOrphans(objectp, regionp->getHost().getAddress(), regionp->getHost().getPort()); +		} +	}  	// If we're just wandering around, don't create new objects selected.  	if (just_created  @@ -277,10 +295,89 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,  static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects"); +LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) +{ +	LLDataPacker *cached_dpp = entry->getDP(); + +	if (!cached_dpp) +	{ +		return NULL; //nothing cached. +	} +	 +	LLViewerObject *objectp; +	U32			    local_id; +	LLPCode		    pcode = 0; +	LLUUID		    fullid; +	LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); + +	// Cache Hit. +	cached_dpp->reset(); +	cached_dpp->unpackUUID(fullid, "ID"); +	cached_dpp->unpackU32(local_id, "LocalID"); +	cached_dpp->unpackU8(pcode, "PCode"); + +	objectp = findObject(fullid); + +	if (objectp) +	{ +		if(!objectp->isDead() && (objectp->mLocalID != entry->getLocalID() || +			objectp->getRegion() != regionp)) +		{ +			removeFromLocalIDTable(objectp); +			setUUIDAndLocal(fullid, entry->getLocalID(), +							regionp->getHost().getAddress(), +							regionp->getHost().getPort()); +				 +			if (objectp->mLocalID != entry->getLocalID()) +			{	// Update local ID in object with the one sent from the region +				objectp->mLocalID = entry->getLocalID(); +			} +			 +			if (objectp->getRegion() != regionp) +			{	// Object changed region, so update it +				objectp->updateRegion(regionp); // for LLVOAvatar +			} +		} +		else +		{ +			return objectp; //already loaded. +		} +	} + +	bool justCreated = false; +	if (!objectp) +	{ +		objectp = createObjectFromCache(pcode, regionp, fullid, entry->getLocalID()); +		 +		if (!objectp) +		{ +			llinfos << "createObject failure for object: " << fullid << llendl; +			recorder.objectUpdateFailure(entry->getLocalID(), OUT_FULL_CACHED, 0); +			return NULL; +		} +		justCreated = true; +		mNumNewObjects++; +		sample(sCacheHitRate, 100.f); +	} + +	if (objectp->isDead()) +	{ +		llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl; +	} +		 +	processUpdateCore(objectp, NULL, 0, OUT_FULL_CACHED, cached_dpp, justCreated, true); +	objectp->loadFlags(entry->getUpdateFlags()); //just in case, reload update flags from cache. + +	recorder.log(0.2f); +	LLVOAvatar::cullAvatarsByPixelArea(); + +	return objectp; +} +  void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  											 void **user_data,  											 const EObjectUpdateType update_type, -											 bool cached, bool compressed) +											 bool compressed)  {  	LLFastTimer t(FTM_PROCESS_OBJECTS);	 @@ -298,7 +395,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  	num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData);  	// I don't think this case is ever hit.  TODO* Test this. -	if (!cached && !compressed && update_type != OUT_FULL) +	if (!compressed && update_type != OUT_FULL)  	{  		//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;  		gTerseObjectUpdates += num_objects; @@ -346,7 +443,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  	U8 compressed_dpbuffer[2048];  	LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048); -	LLDataPacker *cached_dpp = NULL;  	LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance();  	for (i = 0; i < num_objects; i++) @@ -355,57 +451,37 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  		LLTimer update_timer;  		BOOL justCreated = FALSE;  		S32	msg_size = 0; +		bool remove_from_cache = false; //remove from object cache if it is a full-update or terse update -		if (cached) -		{ -			U32 id; -			U32 crc; -			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); -			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); -			msg_size += sizeof(U32) * 2; -		 -			// Lookup data packer and add this id to cache miss lists if necessary. -			U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; -			cached_dpp = regionp->getDP(id, crc, cache_miss_type); -			if (cached_dpp) -			{ -				// Cache Hit. -				cached_dpp->reset(); -				cached_dpp->unpackUUID(fullid, "ID"); -				cached_dpp->unpackU32(local_id, "LocalID"); -				cached_dpp->unpackU8(pcode, "PCode"); -			} -			else -			{ -				// Cache Miss. -				recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size); - -				continue; // no data packer, skip this object -			} -		} -		else if (compressed) +		if (compressed)  		{ -			S32							uncompressed_length = 2048; +			S32	uncompressed_length = 2048;  			compressed_dp.reset(); -			U32 flags = 0; -			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? -			{ -				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); -			} -			  			uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);  			mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);  			compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);  			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{ -				compressed_dp.unpackUUID(fullid, "ID"); -				compressed_dp.unpackU32(local_id, "LocalID"); -				compressed_dp.unpackU8(pcode, "PCode"); +				U32 flags = 0; +				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); +			 +				if(flags & FLAGS_TEMPORARY_ON_REZ) +				{ +					compressed_dp.unpackUUID(fullid, "ID"); +					compressed_dp.unpackU32(local_id, "LocalID"); +					compressed_dp.unpackU8(pcode, "PCode"); +				} +				else //send to object cache +				{ +					regionp->cacheFullUpdate(compressed_dp, flags); +					continue; +				}  			}  			else  			{ +				remove_from_cache = true;  				compressed_dp.unpackU32(local_id, "LocalID");  				getUUIDFromLocal(fullid,  								 local_id, @@ -435,6 +511,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  		}  		else // OUT_FULL only?  		{ +			remove_from_cache = true;  			mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i);  			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);  			msg_size += sizeof(LLUUID); @@ -443,6 +520,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  		}  		objectp = findObject(fullid); +		if(remove_from_cache) +		{ +			objectp = regionp->forceToRemoveFromCache(local_id, objectp); +		} +  		// This looks like it will break if the local_id of the object doesn't change  		// upon boundary crossing, but we check for region id matching later...  		// Reset object local id and region pointer if things have changed @@ -488,9 +570,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  					continue;  				}  			} -			else if (cached) // Cache hit only? -			{ -			}  			else  			{  				if (update_type != OUT_FULL) @@ -521,13 +600,11 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  				recorder.objectUpdateFailure(local_id, update_type, msg_size);  				continue;  			} +  			justCreated = TRUE;  			mNumNewObjects++; -			sCacheHitRate.addValue(cached ? 100.f : 0.f); -  		} -  		if (objectp->isDead())  		{  			llwarns << "Dead object " << objectp->mID << " in UUID map 1!" << llendl; @@ -541,17 +618,21 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,  				objectp->mLocalID = local_id;  			}  			processUpdateCore(objectp, user_data, i, update_type, &compressed_dp, justCreated); + +#if 0  			if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?  			{ -				bCached = true; -				LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); -				recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); +				U32 flags = 0; +				mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); +			 +				if(!(flags & FLAGS_TEMPORARY_ON_REZ)) +				{ +					bCached = true; +					LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp, flags); +					recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); +				}  			} -		} -		else if (cached) // Cache hit only? -		{ -			objectp->mLocalID = local_id; -			processUpdateCore(objectp, user_data, i, update_type, cached_dpp, justCreated); +#endif  		}  		else  		{ @@ -575,14 +656,53 @@ void LLViewerObjectList::processCompressedObjectUpdate(LLMessageSystem *mesgsys,  											 void **user_data,  											 const EObjectUpdateType update_type)  { -	processObjectUpdate(mesgsys, user_data, update_type, false, true); +	processObjectUpdate(mesgsys, user_data, update_type, true);  }  void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,  											 void **user_data,  											 const EObjectUpdateType update_type)  { -	processObjectUpdate(mesgsys, user_data, update_type, true, false); +	//processObjectUpdate(mesgsys, user_data, update_type, true, false); + +	S32 num_objects = mesgsys->getNumberOfBlocksFast(_PREHASH_ObjectData); +	gFullObjectUpdates += num_objects; + +	U64 region_handle; +	mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle);	 +	LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); +	if (!regionp) +	{ +		llwarns << "Object update from unknown region! " << region_handle << llendl; +		return; +	} + +	LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); + +	for (S32 i = 0; i < num_objects; i++) +	{ +		S32	msg_size = 0; +		U32 id; +		U32 crc; +		U32 flags; +		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); +		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); +		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i); +		msg_size += sizeof(U32) * 2; +		 +		// Lookup data packer and add this id to cache miss lists if necessary. +		U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; +		if(!regionp->probeCache(id, crc, flags, cache_miss_type)) +		{ +			// Cache Miss. +			recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size); + +			continue; // no data packer, skip this object +		} +		sample(sCacheHitRate, 100.f); +	} + +	return;  }	  void LLViewerObjectList::dirtyAllObjectInventory() @@ -853,6 +973,8 @@ private:  	LLSD mObjectIDs;  }; +static LLFastTimer::DeclareTimer FTM_IDLE_COPY("Idle Copy"); +  void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  {  	// Update globals @@ -903,10 +1025,8 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  	U32 idle_count = 0; -	static LLFastTimer::DeclareTimer idle_copy("Idle Copy"); -  	{ -		LLFastTimer t(idle_copy); +		LLFastTimer t(FTM_IDLE_COPY);   		for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();  			active_iter != mActiveObjects.end(); active_iter++) @@ -916,9 +1036,9 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  			{  				if (idle_count >= idle_list.size())  				{ -				idle_list.push_back( objectp ); -			} -			else +					idle_list.push_back( objectp ); +				} +				else  				{  					idle_list[idle_count] = objectp;  				} @@ -1032,10 +1152,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)  	}  	*/ -	LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size()); -	LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count); -	LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled); -	LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled); +	sample(LLStatViewer::NUM_OBJECTS, mObjects.size()); +	sample(LLStatViewer::NUM_ACTIVE_OBJECTS, idle_count); +	sample(LLStatViewer::NUM_SIZE_CULLED, mNumSizeCulled); +	sample(LLStatViewer::NUM_VIS_CULLED, mNumVisCulled);  }  void LLViewerObjectList::fetchObjectCosts() @@ -1248,16 +1368,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)  	if (objectp)  	{ -		if (objectp->isDead()) -		{ -			// This object is already dead.  Don't need to do more. -			return TRUE; -		} -		else -		{ -			objectp->markDead(); -		} - +		objectp->markDead(); // does the right thing if object already dead  		return TRUE;  	} @@ -1409,10 +1520,10 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)  			{  				mActiveObjects.push_back(objectp);  				objectp->setListIndex(mActiveObjects.size()-1); -			objectp->setOnActiveList(TRUE); -		} -		else -		{ +				objectp->setOnActiveList(TRUE); +			} +			else +			{  				llassert(idx < mActiveObjects.size());  				llassert(mActiveObjects[idx] == objectp); @@ -1541,13 +1652,13 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)  	{  		LLFastTimer t(FTM_PIPELINE_SHIFT); -	gPipeline.shiftObjects(offset); +		gPipeline.shiftObjects(offset);  	}  	{  		LLFastTimer t(FTM_REGION_SHIFT); -	LLWorld::getInstance()->shiftRegions(offset); -} +		LLWorld::getInstance()->shiftRegions(offset); +	}  }  void LLViewerObjectList::repartitionObjects() @@ -1893,6 +2004,29 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi  	return objectp;  } +LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id) +{ +	llassert_always(uuid.notNull()); + +	LLViewerObject *objectp = LLViewerObject::createObject(uuid, pcode, regionp); +	if (!objectp) +	{ +// 		llwarns << "Couldn't create object of type " << LLPrimitive::pCodeToString(pcode) << " id:" << fullid << llendl; +		return NULL; +	} + +	objectp->mLocalID = local_id; +	mUUIDObjectMap[uuid] = objectp; +	setUUIDAndLocal(uuid, +					local_id, +					regionp->getHost().getAddress(), +					regionp->getHost().getPort()); +	mObjects.push_back(objectp); +	 +	updateActive(objectp); + +	return objectp; +}  LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,  												 const LLUUID &uuid, const U32 local_id, const LLHost &sender) @@ -1960,9 +2094,7 @@ S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const  void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port)  { -#ifdef ORPHAN_SPAM -	llinfos << "Orphaning object " << childp->getID() << " with parent " << parent_id << llendl; -#endif +	LL_DEBUGS("ORPHANS") << "Orphaning object " << childp->getID() << " with parent " << parent_id << LL_ENDL;  	// We're an orphan, flag things appropriately.  	childp->mOrphaned = TRUE; @@ -2015,6 +2147,12 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)  		return;  	} +	//search object cache to get orphans +	if(objectp->getRegion()) +	{ +		objectp->getRegion()->findOrphans(objectp->getLocalID()); +	} +  	// See if we are a parent of an orphan.  	// Note:  This code is fairly inefficient but it should happen very rarely.  	// It can be sped up if this is somehow a performance issue... @@ -2050,11 +2188,11 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)  				continue;  			} +			LL_DEBUGS("ORPHANS") << "Reunited parent " << objectp->mID  +				<< " with child " << childp->mID << LL_ENDL; +			LL_DEBUGS("ORPHANS") << "Glob: " << objectp->getPositionGlobal() << LL_ENDL; +			LL_DEBUGS("ORPHANS") << "Agent: " << objectp->getPositionAgent() << LL_ENDL;  #ifdef ORPHAN_SPAM -			llinfos << "Reunited parent " << objectp->mID  -				<< " with child " << childp->mID << llendl; -			llinfos << "Glob: " << objectp->getPositionGlobal() << llendl; -			llinfos << "Agent: " << objectp->getPositionAgent() << llendl;  			addDebugBeacon(objectp->getPositionAgent(),"");  #endif  			gPipeline.markMoved(objectp->mDrawable);				 @@ -2142,3 +2280,10 @@ bool LLViewerObjectList::OrphanInfo::operator!=(const OrphanInfo &rhs) const  } +LLDebugBeacon::~LLDebugBeacon() +{ +	if (mHUDObject.notNull()) +	{ +		mHUDObject->markDead(); +	} +} diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 449a4633ff..464554245e 100755 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -31,8 +31,8 @@  #include <set>  // common includes -#include "llstat.h"  #include "llstring.h" +#include "lltrace.h"  // project includes  #include "llviewerobject.h" @@ -40,6 +40,7 @@  class LLCamera;  class LLNetMap;  class LLDebugBeacon; +class LLVOCacheEntry;  const U32 CLOSE_BIN_SIZE = 10;  const U32 NUM_BINS = 128; @@ -65,6 +66,7 @@ public:  	inline LLViewerObject *findObject(const LLUUID &id);  	LLViewerObject *createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp); // Create a viewer-side object +	LLViewerObject *createObjectFromCache(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id);  	LLViewerObject *createObject(const LLPCode pcode, LLViewerRegion *regionp,  								 const LLUUID &uuid, const U32 local_id, const LLHost &sender); @@ -78,8 +80,10 @@ public:  	void cleanDeadObjects(const BOOL use_timer = TRUE);	// Clean up the dead object list.  	// Simulator and viewer side object updates... -	void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type, LLDataPacker* dpp, BOOL justCreated); -	void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool cached=false, bool compressed=false); +	void processUpdateCore(LLViewerObject* objectp, void** data, U32 block, const EObjectUpdateType update_type,  +		                   LLDataPacker* dpp, bool justCreated, bool from_cache = false); +	LLViewerObject* processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp); +	void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool compressed=false);  	void processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);  	void processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);  	void updateApparentAngles(LLAgent &agent); @@ -188,14 +192,13 @@ public:  	S32 mNumUnknownUpdates;  	S32 mNumDeadObjectUpdates; -	S32 mNumUnknownKills;  	S32 mNumDeadObjects;  protected:  	std::vector<U64>	mOrphanParents;	// LocalID/ip,port of orphaned objects  	std::vector<OrphanInfo> mOrphanChildren;	// UUID's of orphaned objects  	S32 mNumOrphans; -	static LLStat sCacheHitRate; +	static LLTrace::SampleStatHandle<> sCacheHitRate;  	typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t; @@ -234,20 +237,14 @@ protected:  class LLDebugBeacon  {  public: -	~LLDebugBeacon() -	{ -		if (mHUDObject.notNull()) -		{ -			mHUDObject->markDead(); -		} -	} +	~LLDebugBeacon();  	LLVector3 mPositionAgent;  	std::string mString;  	LLColor4 mColor;  	LLColor4 mTextColor;  	S32 mLineWidth; -	LLPointer<LLHUDObject> mHUDObject; +	LLPointer<class LLHUDObject> mHUDObject;  }; diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp new file mode 100644 index 0000000000..d631985e82 --- /dev/null +++ b/indra/newview/llvieweroctree.cpp @@ -0,0 +1,1459 @@ +/**  + * @file llvieweroctree.cpp + * @brief LLViewerOctreeGroup class implementation and supporting functions + * + * $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$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llvieweroctree.h" +#include "llviewerregion.h" +#include "pipeline.h" +#include "llviewercontrol.h" +#include "llappviewer.h" +#include "llglslshader.h" +#include "llviewershadermgr.h" + +//----------------------------------------------------------------------------------- +//static variables definitions +//----------------------------------------------------------------------------------- +U32 LLViewerOctreeEntryData::sCurVisible = 0; +BOOL LLViewerOctreeDebug::sInDebug = FALSE; + +//----------------------------------------------------------------------------------- +//some global functions definitions +//----------------------------------------------------------------------------------- +typedef enum +{ +	b000 = 0x00, +	b001 = 0x01, +	b010 = 0x02, +	b011 = 0x03, +	b100 = 0x04, +	b101 = 0x05, +	b110 = 0x06, +	b111 = 0x07, +} eLoveTheBits; + +//contact Runitai Linden for a copy of the SL object used to write this table +//basically, you give the table a bitmask of the look-at vector to a node and it +//gives you a triangle fan index array +static U16 sOcclusionIndices[] = +{ +	 //000 +		b111, b110, b010, b011, b001, b101, b100, b110, +	 //001  +		b011, b010, b000, b001, b101, b111, b110, b010, +	 //010 +		b101, b100, b110, b111, b011, b001, b000, b100, +	 //011  +		b001, b000, b100, b101, b111, b011, b010, b000, +	 //100  +		b110, b000, b010, b011, b111, b101, b100, b000, +	 //101  +		b010, b100, b000, b001, b011, b111, b110, b100, +	 //110 +		b100, b010, b110, b111, b101, b001, b000, b010, +	 //111 +		b000, b110, b100, b101, b001, b011, b010, b110, +}; + +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) +{ +	LLVector4a origin; +	origin.load3(camera->getOrigin().mV); + +	S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; +	 +	return cypher*8; +} + +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) +{ +	LLVector4a origin; +	origin.load3(camera->getOrigin().mV); + +	S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; +	 +	return (U8*) (sOcclusionIndices+cypher*8); +} + +//create a vertex buffer for efficiently rendering cubes +LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) +{ +	LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); + +	ret->allocateBuffer(8, 64, true); + +	LLStrider<LLVector3> pos; +	LLStrider<U16> idx; + +	ret->getVertexStrider(pos); +	ret->getIndexStrider(idx); + +	pos[0] = LLVector3(-1,-1,-1); +	pos[1] = LLVector3(-1,-1, 1); +	pos[2] = LLVector3(-1, 1,-1); +	pos[3] = LLVector3(-1, 1, 1); +	pos[4] = LLVector3( 1,-1,-1); +	pos[5] = LLVector3( 1,-1, 1); +	pos[6] = LLVector3( 1, 1,-1); +	pos[7] = LLVector3( 1, 1, 1); + +	for (U32 i = 0; i < 64; i++) +	{ +		idx[i] = sOcclusionIndices[i]; +	} + +	ret->flush(); + +	return ret; +} + + +#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 + +const F32 SG_OCCLUSION_FUDGE = 0.25f; +#define SG_DISCARD_TOLERANCE 0.01f + + +S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) +{ +	return AABBSphereIntersectR2(min, max, origin, rad*rad); +} + +S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &r) +{ +	F32 d = 0.f; +	F32 t; +	 +	if ((min-origin).magVecSquared() < r && +		(max-origin).magVecSquared() < r) +	{ +		return 2; +	} + +	for (U32 i = 0; i < 3; i++) +	{ +		if (origin.mV[i] < min.mV[i]) +		{ +			t = min.mV[i] - origin.mV[i]; +			d += t*t; +		} +		else if (origin.mV[i] > max.mV[i]) +		{ +			t = origin.mV[i] - max.mV[i]; +			d += t*t; +		} + +		if (d > r) +		{ +			return 0; +		} +	} + +	return 1; +} + + +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) +{ +	return AABBSphereIntersectR2(min, max, origin, rad*rad); +} + +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) +{ +	F32 d = 0.f; +	F32 t; +	 +	LLVector4a origina; +	origina.load3(origin.mV); + +	LLVector4a v; +	v.setSub(min, origina); +	 +	if (v.dot3(v) < r) +	{ +		v.setSub(max, origina); +		if (v.dot3(v) < r) +		{ +			return 2; +		} +	} + + +	for (U32 i = 0; i < 3; i++) +	{ +		if (origin.mV[i] < min[i]) +		{ +			t = min[i] - origin.mV[i]; +			d += t*t; +		} +		else if (origin.mV[i] > max[i]) +		{ +			t = origin.mV[i] - max[i]; +			d += t*t; +		} + +		if (d > r) +		{ +			return 0; +		} +	} + +	return 1; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeEntry definitions +//----------------------------------------------------------------------------------- +LLViewerOctreeEntry::LLViewerOctreeEntry()  +	: mGroup(NULL), +	  mBinRadius(0.f), +	  mBinIndex(-1) +{ +	mPositionGroup.clear(); +	mExtents[0].clear(); +	mExtents[1].clear();	 + +	for(S32 i = 0; i < NUM_DATA_TYPE; i++) +	{ +		mData[i] = NULL; +	} +} + +LLViewerOctreeEntry::~LLViewerOctreeEntry() +{ +	llassert(!mGroup); +} + +void LLViewerOctreeEntry::addData(LLViewerOctreeEntryData* data) +{ +	//llassert(mData[data->getDataType()] == NULL);	 +	llassert(data != NULL); + +	mData[data->getDataType()] = data; +} + +void LLViewerOctreeEntry::removeData(LLViewerOctreeEntryData* data) +{ +	//llassert(data->getDataType() != LLVOCACHEENTRY); //can not remove VOCache entry + +	if(!mData[data->getDataType()]) +	{ +		return; +	} + +	mData[data->getDataType()] = NULL; +	 +	if(mGroup != NULL && !mData[LLDRAWABLE]) +	{ +		LLviewerOctreeGroup* group = mGroup; +		mGroup = NULL; +		group->removeFromGroup(data); + +		llassert(mBinIndex == -1);				 +	} +} + +//called by group handleDestruction() ONLY when group is destroyed by octree. +void LLViewerOctreeEntry::nullGroup() +{ +	mGroup = NULL; +} + +void LLViewerOctreeEntry::setGroup(LLviewerOctreeGroup* group) +{ +	if(mGroup == group) +	{ +		return; +	} + +	if(mGroup) +	{ +		LLviewerOctreeGroup* group = mGroup; +		mGroup = NULL; +		group->removeFromGroup(this); + +		llassert(mBinIndex == -1); +	} + +	mGroup = group; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeEntryData definitions +//----------------------------------------------------------------------------------- +LLViewerOctreeEntryData::~LLViewerOctreeEntryData() +{ +	if(mEntry) +	{ +		mEntry->removeData(this); +	} +} + +LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type) +	: mDataType(data_type), +	  mEntry(NULL) +{ +} + +//virtual +void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry) +{ +	if(mEntry.notNull()) +	{ +		return;  +	} + +	if(!entry) +	{ +		mEntry = new LLViewerOctreeEntry(); +	} +	else +	{ +		mEntry = entry; +	} +	mEntry->addData(this); +} + +void LLViewerOctreeEntryData::setSpatialExtents(const LLVector3& min, const LLVector3& max) +{  +	mEntry->mExtents[0].load3(min.mV);  +	mEntry->mExtents[1].load3(max.mV); +} + +void LLViewerOctreeEntryData::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) +{  +	mEntry->mExtents[0] = min;  +	mEntry->mExtents[1] = max; +} + +void LLViewerOctreeEntryData::setPositionGroup(const LLVector4a& pos) +{ +	mEntry->mPositionGroup = pos; +} + +const LLVector4a* LLViewerOctreeEntryData::getSpatialExtents() const  +{ +	return mEntry->getSpatialExtents(); +} + +//virtual +void LLViewerOctreeEntryData::setGroup(LLviewerOctreeGroup* group) +{ +	mEntry->setGroup(group); +} + +void LLViewerOctreeEntryData::shift(const LLVector4a &shift_vector) +{ +	mEntry->mExtents[0].add(shift_vector); +	mEntry->mExtents[1].add(shift_vector); +	mEntry->mPositionGroup.add(shift_vector); +} + +LLviewerOctreeGroup* LLViewerOctreeEntryData::getGroup()const         +{ +	return mEntry.notNull() ? mEntry->mGroup : NULL; +} + +const LLVector4a& LLViewerOctreeEntryData::getPositionGroup() const   +{ +	return mEntry->getPositionGroup(); +}	 + +//virtual +bool LLViewerOctreeEntryData::isVisible() const +{ +	if(mEntry) +	{ +		return mEntry->mVisible == sCurVisible; +	} +	return false; +} + +//virtual +bool LLViewerOctreeEntryData::isRecentlyVisible() const +{ +	if(!mEntry) +	{ +		return false; +	} + +	if(isVisible()) +	{ +		return true; +	} +	if(getGroup() && getGroup()->isRecentlyVisible()) +	{ +		setVisible(); +		return true; +	} + +	return (sCurVisible - mEntry->mVisible < getMinFrameRange()); +} + +void LLViewerOctreeEntryData::setVisible() const +{ +	if(mEntry) +	{ +		mEntry->mVisible = sCurVisible; +	} +} + +//----------------------------------------------------------------------------------- +//class LLviewerOctreeGroup definitions +//----------------------------------------------------------------------------------- + +LLviewerOctreeGroup::~LLviewerOctreeGroup() +{ +	//empty here +} + +LLviewerOctreeGroup::LLviewerOctreeGroup(OctreeNode* node) : +	mOctreeNode(node), +	mState(CLEAN) +{ +	LLVector4a tmp; +	tmp.splat(0.f); +	mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =  +		mObjectExtents[0] = mObjectExtents[1] = tmp; +	 +	mBounds[0] = node->getCenter(); +	mBounds[1] = node->getSize(); + +	mOctreeNode->addListener(this); +} + +bool LLviewerOctreeGroup::hasElement(LLViewerOctreeEntryData* data)  +{  +	if(!data->getEntry()) +	{ +		return false; +	} +	return std::find(getDataBegin(), getDataEnd(), data->getEntry()) != getDataEnd();  +} + +bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntryData* data) +{ +	return removeFromGroup(data->getEntry()); +} + +bool LLviewerOctreeGroup::removeFromGroup(LLViewerOctreeEntry* entry) +{ +	llassert(entry != NULL); +	llassert(!entry->getGroup()); + +	unbound(); +	if (mOctreeNode) +	{ +		if (!mOctreeNode->remove(entry)) +		{ +			OCT_ERRS << "Could not remove LLVOCacheEntry from LLVOCacheOctreeGroup" << llendl; +			return false; +		} +	} +	setState(OBJECT_DIRTY); + +	return true; +} + +//virtual  +void LLviewerOctreeGroup::unbound() +{ +	if (isDirty()) +	{ +		return; +	} + +	setState(DIRTY); +	 +	//all the parent nodes need to rebound this child +	if (mOctreeNode) +	{ +		OctreeNode* parent = (OctreeNode*) mOctreeNode->getParent(); +		while (parent != NULL) +		{ +			LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) parent->getListener(0); +			if (!group || group->isDirty()) +			{ +				return; +			} +			 +			group->setState(DIRTY); +			parent = (OctreeNode*) parent->getParent(); +		} +	} +} +	 +//virtual  +void LLviewerOctreeGroup::rebound() +{ +	if (!isDirty()) +	{	 +		return; +	} +	 +	if (mOctreeNode->getChildCount() == 1 && mOctreeNode->getElementCount() == 0) +	{ +		LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0); +		group->rebound(); +		 +		//copy single child's bounding box +		mBounds[0] = group->mBounds[0]; +		mBounds[1] = group->mBounds[1]; +		mExtents[0] = group->mExtents[0]; +		mExtents[1] = group->mExtents[1]; +		 +		group->setState(SKIP_FRUSTUM_CHECK); +	} +	else if (mOctreeNode->isLeaf()) +	{ //copy object bounding box if this is a leaf +		boundObjects(TRUE, mExtents[0], mExtents[1]); +		mBounds[0] = mObjectBounds[0]; +		mBounds[1] = mObjectBounds[1]; +	} +	else +	{ +		LLVector4a& newMin = mExtents[0]; +		LLVector4a& newMax = mExtents[1]; +		LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) mOctreeNode->getChild(0)->getListener(0); +		group->clearState(SKIP_FRUSTUM_CHECK); +		group->rebound(); +		//initialize to first child +		newMin = group->mExtents[0]; +		newMax = group->mExtents[1]; + +		//first, rebound children +		for (U32 i = 1; i < mOctreeNode->getChildCount(); i++) +		{ +			group = (LLviewerOctreeGroup*) mOctreeNode->getChild(i)->getListener(0); +			group->clearState(SKIP_FRUSTUM_CHECK); +			group->rebound(); +			const LLVector4a& max = group->mExtents[1]; +			const LLVector4a& min = group->mExtents[0]; + +			newMax.setMax(newMax, max); +			newMin.setMin(newMin, min); +		} + +		boundObjects(FALSE, newMin, newMax); +		 +		mBounds[0].setAdd(newMin, newMax); +		mBounds[0].mul(0.5f); +		mBounds[1].setSub(newMax, newMin); +		mBounds[1].mul(0.5f); +	} +	 +	clearState(DIRTY); + +	return; +} + +//virtual  +void LLviewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj) +{ +	obj->setGroup(this);	 +	unbound(); +	setState(OBJECT_DIRTY); +} +	 +//virtual  +void LLviewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj) +{ +	obj->setGroup(NULL); +	unbound(); +	setState(OBJECT_DIRTY); +} +	 +//virtual  +void LLviewerOctreeGroup::handleDestruction(const TreeNode* node) +{ +	for (OctreeNode::element_iter i = mOctreeNode->getDataBegin(); i != mOctreeNode->getDataEnd(); ++i) +	{ +		LLViewerOctreeEntry* obj = *i; +		if (obj && obj->getGroup() == this) +		{ +			obj->nullGroup(); +			//obj->setGroup(NULL); +		} +	} +	mOctreeNode = NULL; +} +	 +//virtual  +void LLviewerOctreeGroup::handleStateChange(const TreeNode* node) +{ +	//drop bounding box upon state change +	if (mOctreeNode != node) +	{ +		mOctreeNode = (OctreeNode*) node; +	} +	unbound(); +} +	 +//virtual  +void LLviewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) +{ +	if (child->getListenerCount() == 0) +	{ +		new LLviewerOctreeGroup(child); +	} +	else +	{ +		OCT_ERRS << "LLviewerOctreeGroup redundancy detected." << llendl; +	} + +	unbound(); +	 +	((LLviewerOctreeGroup*)child->getListener(0))->unbound(); +} +	 +//virtual  +void LLviewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) +{ +	unbound(); +} + +LLviewerOctreeGroup* LLviewerOctreeGroup::getParent() +{ +	if (isDead()) +	{ +		return NULL; +	} + +	if(!mOctreeNode) +	{ +		return NULL; +	} +	 +	OctreeNode* parent = mOctreeNode->getOctParent(); + +	if (parent) +	{ +		return (LLviewerOctreeGroup*) parent->getListener(0); +	} + +	return NULL; +} + +//virtual  +bool LLviewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) +{ +	const OctreeNode* node = mOctreeNode; + +	if (node->isEmpty()) +	{	//don't do anything if there are no objects +		if (empty && mOctreeNode->getParent()) +		{	//only root is allowed to be empty +			OCT_ERRS << "Empty leaf found in octree." << llendl; +		} +		return false; +	} + +	LLVector4a& newMin = mObjectExtents[0]; +	LLVector4a& newMax = mObjectExtents[1]; +	 +	if (hasState(OBJECT_DIRTY)) +	{ //calculate new bounding box +		clearState(OBJECT_DIRTY); + +		//initialize bounding box to first element +		OctreeNode::const_element_iter i = node->getDataBegin(); +		LLViewerOctreeEntry* entry = *i; +		const LLVector4a* minMax = entry->getSpatialExtents(); + +		newMin = minMax[0]; +		newMax = minMax[1]; + +		for (++i; i != node->getDataEnd(); ++i) +		{ +			entry = *i; +			minMax = entry->getSpatialExtents(); +			 +			update_min_max(newMin, newMax, minMax[0]); +			update_min_max(newMin, newMax, minMax[1]); +		} +		 +		mObjectBounds[0].setAdd(newMin, newMax); +		mObjectBounds[0].mul(0.5f); +		mObjectBounds[1].setSub(newMax, newMin); +		mObjectBounds[1].mul(0.5f); +	} +	 +	if (empty) +	{ +		minOut = newMin; +		maxOut = newMax; +	} +	else +	{ +		minOut.setMin(minOut, newMin); +		maxOut.setMax(maxOut, newMax); +	} +		 +	return TRUE; +} + +//virtual  +BOOL LLviewerOctreeGroup::isVisible() const +{ +	return mVisible[LLViewerCamera::sCurCameraID] >= LLViewerOctreeEntryData::getCurrentFrame() ? TRUE : FALSE; +} + +//virtual  +BOOL LLviewerOctreeGroup::isRecentlyVisible() const  +{ +	return FALSE; +} + +void LLviewerOctreeGroup::setVisible() +{ +	mVisible[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame(); +} + +void LLviewerOctreeGroup::checkStates() +{ +#if LL_OCTREE_PARANOIA_CHECK +	//LLOctreeStateCheck checker; +	//checker.traverse(mOctreeNode); +#endif +} + +//------------------------------------------------------------------------------------------- +//occulsion culling functions and classes +//------------------------------------------------------------------------------------------- +std::set<U32> LLOcclusionCullingGroup::sPendingQueries; +class LLOcclusionQueryPool : public LLGLNamePool +{ +public: +	LLOcclusionQueryPool() +	{ +		mCurQuery = 1; +	} + +protected: + +	std::list<GLuint> mAvailableName; +	GLuint mCurQuery; +		 +	virtual GLuint allocateName() +	{ +		GLuint ret = 0; + +		if (!mAvailableName.empty()) +		{ +			ret = mAvailableName.front(); +			mAvailableName.pop_front(); +		} +		else +		{ +			ret = mCurQuery++; +		} + +		return ret; +	} + +	virtual void releaseName(GLuint name) +	{ +#if LL_TRACK_PENDING_OCCLUSION_QUERIES +		LLSpatialGroup::sPendingQueries.erase(name); +#endif +		llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end()); +		mAvailableName.push_back(name); +	} +}; + +static LLOcclusionQueryPool sQueryPool; +U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName() +{ +	return sQueryPool.allocate(); +} + +void LLOcclusionCullingGroup::releaseOcclusionQueryObjectName(GLuint name) +{ +	sQueryPool.release(name); +} + +//===================================== +//		Occlusion State Set/Clear +//===================================== +class LLSpatialSetOcclusionState : public OctreeTraveler +{ +public: +	U32 mState; +	LLSpatialSetOcclusionState(U32 state) : mState(state) { } +	virtual void visit(const OctreeNode* branch) { ((LLOcclusionCullingGroup*) branch->getListener(0))->setOcclusionState(mState); }	 +}; + +class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState +{ +public: +	LLSpatialSetOcclusionStateDiff(U32 state) : LLSpatialSetOcclusionState(state) { } + +	virtual void traverse(const OctreeNode* n) +	{ +		LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*) n->getListener(0); +		 +		if (!group->isOcclusionState(mState)) +		{ +			OctreeTraveler::traverse(n); +		} +	} +}; + + +LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part) :  +	LLviewerOctreeGroup(node), +	mSpatialPartition(part) +{ +	part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; +	mLODHash = part->mLODSeed; + +	OctreeNode* oct_parent = node->getOctParent(); +	LLOcclusionCullingGroup* parent = oct_parent ? (LLOcclusionCullingGroup*) oct_parent->getListener(0) : NULL; + +	for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) +	{ +		mOcclusionQuery[i] = 0; +		mOcclusionIssued[i] = 0; +		mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; +		mVisible[i] = 0; +	} +} + +LLOcclusionCullingGroup::~LLOcclusionCullingGroup() +{ +	releaseOcclusionQueryObjectNames(); +} + +BOOL LLOcclusionCullingGroup::needsUpdate() +{ +	return (LLDrawable::getCurrentFrame() % mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; +} + +//virtual  +void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) +{ +	if (child->getListenerCount() == 0) +	{ +		new LLOcclusionCullingGroup(child, mSpatialPartition); +	} +	else +	{ +		OCT_ERRS << "LLOcclusionCullingGroup redundancy detected." << llendl; +	} + +	unbound(); +	 +	((LLviewerOctreeGroup*)child->getListener(0))->unbound(); +} + +void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames() +{ +	if (gGLManager.mHasOcclusionQuery) +	{ +		for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) +		{ +			if (mOcclusionQuery[i]) +			{ +				releaseOcclusionQueryObjectName(mOcclusionQuery[i]); +				mOcclusionQuery[i] = 0; +			} +		} +	} +} + +void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode)  +{ +	if (mode > STATE_MODE_SINGLE) +	{ +		if (mode == STATE_MODE_DIFF) +		{ +			LLSpatialSetOcclusionStateDiff setter(state); +			setter.traverse(mOctreeNode); +		} +		else if (mode == STATE_MODE_BRANCH) +		{ +			LLSpatialSetOcclusionState setter(state); +			setter.traverse(mOctreeNode); +		} +		else +		{ +			for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) +			{ +				mOcclusionState[i] |= state; + +				if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) +				{ +					releaseOcclusionQueryObjectName(mOcclusionQuery[i]); +					mOcclusionQuery[i] = 0; +				} +			} +		} +	} +	else +	{ +		mOcclusionState[LLViewerCamera::sCurCameraID] |= state; +		if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) +		{ +			releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +			mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; +		} +	} +} + +class LLSpatialClearOcclusionState : public OctreeTraveler +{ +public: +	U32 mState; +	 +	LLSpatialClearOcclusionState(U32 state) : mState(state) { } +	virtual void visit(const OctreeNode* branch) { ((LLOcclusionCullingGroup*) branch->getListener(0))->clearOcclusionState(mState); } +}; + +class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState +{ +public: +	LLSpatialClearOcclusionStateDiff(U32 state) : LLSpatialClearOcclusionState(state) { } + +	virtual void traverse(const OctreeNode* n) +	{ +		LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*) n->getListener(0); +		 +		if (group->isOcclusionState(mState)) +		{ +			OctreeTraveler::traverse(n); +		} +	} +}; + +void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode) +{ +	if (mode > STATE_MODE_SINGLE) +	{ +		if (mode == STATE_MODE_DIFF) +		{ +			LLSpatialClearOcclusionStateDiff clearer(state); +			clearer.traverse(mOctreeNode); +		} +		else if (mode == STATE_MODE_BRANCH) +		{ +			LLSpatialClearOcclusionState clearer(state); +			clearer.traverse(mOctreeNode); +		} +		else +		{ +			for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) +			{ +				mOcclusionState[i] &= ~state; +			} +		} +	} +	else +	{ +		mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; +	} +} + +static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait"); + +BOOL LLOcclusionCullingGroup::earlyFail(LLCamera* camera) +{ +	if (camera->getOrigin().isExactlyZero()) +	{ +		return FALSE; +	} + +	const F32 vel = SG_OCCLUSION_FUDGE*2.f; +	LLVector4a fudge; +	fudge.splat(vel); + +	const LLVector4a* bounds = getBounds(); +	const LLVector4a& c = bounds[0]; +	LLVector4a r; +	r.setAdd(bounds[1], fudge); + +	/*if (r.magVecSquared() > 1024.0*1024.0) +	{ +		return TRUE; +	}*/ + +	LLVector4a e; +	e.load3(camera->getOrigin().mV); +	 +	LLVector4a min; +	min.setSub(c,r); +	LLVector4a max; +	max.setAdd(c,r); +	 +	S32 lt = e.lessThan(min).getGatheredBits() & 0x7; +	if (lt) +	{ +		return FALSE; +	} + +	S32 gt = e.greaterThan(max).getGatheredBits() & 0x7; +	if (gt) +	{ +		return FALSE; +	} + +	return TRUE; +} + +void LLOcclusionCullingGroup::checkOcclusion() +{ +	if (LLPipeline::sUseOcclusion > 1) +	{ +		LLFastTimer t(FTM_OCCLUSION_READBACK); +		LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent(); +		if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) +		{	//if the parent has been marked as occluded, the child is implicitly occluded +			clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); +		} +		else if (isOcclusionState(QUERY_PENDING)) +		{	//otherwise, if a query is pending, read it back + +			GLuint available = 0; +			if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) +			{ +				glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + +				static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion"); + +				if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount) +				{ //query was issued last frame, wait until it's available +					S32 max_loop = 1024; +					LLFastTimer t(FTM_OCCLUSION_WAIT); +					while (!available && max_loop-- > 0) +					{ +						//do some usefu work while we wait +						F32 max_time = llmin(gFrameIntervalSeconds.value()*10.f, 1.f); +						LLAppViewer::instance()->updateTextureThreads(max_time); +						 +						glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); +					} +				} +			} +			else +			{ +				available = 1; +			} + +			if (available) +			{ //result is available, read it back, otherwise wait until next frame +				GLuint res = 1; +				if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) +				{ +					glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);	 +#if LL_TRACK_PENDING_OCCLUSION_QUERIES +					sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif +				} +				else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) +				{ //delete the query to avoid holding onto hundreds of pending queries +					releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +					mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; +				} +				 +				if (isOcclusionState(DISCARD_QUERY)) +				{ +					res = 2; +				} + +				if (res > 0) +				{ +					assert_states_valid(this); +					clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); +					assert_states_valid(this); +				} +				else +				{ +					assert_states_valid(this); +					 +					setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); +					 +					assert_states_valid(this); +				} + +				clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); +			} +		} +		else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) +		{	//check occlusion has been issued for occluded node that has not had a query issued +			assert_states_valid(this); +			clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); +			assert_states_valid(this); +		} +	} +} + +static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); +static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_ALLOCATE("Allocate"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_BUILD("Build"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_BEGIN_QUERY("Begin Query"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_END_QUERY("End Query"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_SET_BUFFER("Set Buffer"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW_WATER("Draw Water"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_DRAW("Draw"); + +void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera) +{ +	if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) +	{ +		// Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension +		if (earlyFail(camera)) +		{ +			LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); +			setOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY); +			assert_states_valid(this); +			clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF); +			assert_states_valid(this); +		} +		else +		{ +			if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) +			{ +				{ //no query pending, or previous query to be discarded +					LLFastTimer t(FTM_RENDER_OCCLUSION); + +					if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) +					{ +						LLFastTimer t(FTM_OCCLUSION_ALLOCATE); +						mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName(); +					} + +					// Depth clamp all water to avoid it being culled as a result of being +					// behind the far clip plane, and in the case of edge water to avoid +					// it being culled while still visible. +					bool const use_depth_clamp = gGLManager.mHasDepthClamp && +												(mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||						 +												mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); + +					LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);				 +						 +#if !LL_DARWIN					 +					U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; +#else +					U32 mode = GL_SAMPLES_PASSED_ARB; +#endif +					 +#if LL_TRACK_PENDING_OCCLUSION_QUERIES +					sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif + +					{ +						LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); +						 +						//store which frame this query was issued on +						mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount; + +						{ +							LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY); +							glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);					 +						} +					 +						LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; +						llassert(shader); + +						shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr()); +						shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE,  +																 mBounds[1][1]+SG_OCCLUSION_FUDGE,  +																 mBounds[1][2]+SG_OCCLUSION_FUDGE); + +						if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) +						{ +							LLFastTimer t(FTM_OCCLUSION_DRAW_WATER); + +							LLGLSquashToFarClip squash(glh_get_current_projection(), 1); +							if (camera->getOrigin().isExactlyZero()) +							{ //origin is invalid, draw entire box +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				 +							} +							else +							{ +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); +							} +						} +						else +						{ +							LLFastTimer t(FTM_OCCLUSION_DRAW); +							if (camera->getOrigin().isExactlyZero()) +							{ //origin is invalid, draw entire box +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);				 +							} +							else +							{ +								gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); +							} +						} + + +						{ +							LLFastTimer t(FTM_OCCLUSION_END_QUERY); +							glEndQueryARB(mode); +						} +					} +				} + +				{ +					LLFastTimer t(FTM_SET_OCCLUSION_STATE); +					setOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING); +					clearOcclusionState(LLOcclusionCullingGroup::DISCARD_QUERY); +				} +			} +		} +	} +} +//------------------------------------------------------------------------------------------- +//end of occulsion culling functions and classes +//------------------------------------------------------------------------------------------- + +//----------------------------------------------------------------------------------- +//class LLViewerOctreePartition definitions +//----------------------------------------------------------------------------------- +LLViewerOctreePartition::LLViewerOctreePartition() :  +	mRegionp(NULL),  +	mOcclusionEnabled(TRUE),  +	mDrawableType(0), +	mLODSeed(0), +	mLODPeriod(1) +{ +	LLVector4a center, size; +	center.splat(0.f); +	size.splat(1.f); + +	mOctree = new OctreeRoot(center,size, NULL); +} +	 +LLViewerOctreePartition::~LLViewerOctreePartition() +{ +	delete mOctree; +	mOctree = NULL; +} + +BOOL LLViewerOctreePartition::isOcclusionEnabled() +{ +	return mOcclusionEnabled || LLPipeline::sUseOcclusion > 2; +} + +//----------------------------------------------------------------------------------- +//class LLViewerOctreeCull definitions +//----------------------------------------------------------------------------------- + +//virtual  +bool LLViewerOctreeCull::earlyFail(LLviewerOctreeGroup* group) +{	 +	return false; +} +	 +//virtual  +void LLViewerOctreeCull::traverse(const OctreeNode* n) +{ +	LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) n->getListener(0); + +	if (earlyFail(group)) +	{ +		return; +	} +		 +	if (mRes == 2 ||  +		(mRes && group->hasState(LLviewerOctreeGroup::SKIP_FRUSTUM_CHECK))) +	{	//fully in, just add everything +		OctreeTraveler::traverse(n); +	} +	else +	{ +		mRes = frustumCheck(group); +				 +		if (mRes) +		{ //at least partially in, run on down +			OctreeTraveler::traverse(n); +		} + +		mRes = 0; +	} +} +	 +//------------------------------------------ +//agent space group culling +S32 LLViewerOctreeCull::AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group) +{ +	return mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); +} + +S32 LLViewerOctreeCull::AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group) +{ +	return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist); +} + +S32 LLViewerOctreeCull::AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group) +{ +	return mCamera->AABBInFrustum(group->mBounds[0], group->mBounds[1]); +} +//------------------------------------------ + +//------------------------------------------ +//agent space object set culling +S32 LLViewerOctreeCull::AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group) +{ +	return mCamera->AABBInFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); +} + +S32 LLViewerOctreeCull::AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group) +{ +	return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin(), mCamera->mFrustumCornerDist); +} + +S32 LLViewerOctreeCull::AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group) +{ +	return mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); +} +//------------------------------------------ + +//------------------------------------------ +//local regional space group culling +S32 LLViewerOctreeCull::AABBInRegionFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group) +{ +	return mCamera->AABBInRegionFrustumNoFarClip(group->mBounds[0], group->mBounds[1]); +} + +S32 LLViewerOctreeCull::AABBInRegionFrustumGroupBounds(const LLviewerOctreeGroup* group) +{ +	return mCamera->AABBInRegionFrustum(group->mBounds[0], group->mBounds[1]); +} + +S32 LLViewerOctreeCull::AABBRegionSphereIntersectGroupExtents(const LLviewerOctreeGroup* group, const LLVector3& shift) +{ +	return AABBSphereIntersect(group->mExtents[0], group->mExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist); +} +//------------------------------------------ + +//------------------------------------------ +//local regional space object culling +S32 LLViewerOctreeCull::AABBInRegionFrustumObjectBounds(const LLviewerOctreeGroup* group) +{ +	return mCamera->AABBInRegionFrustum(group->mObjectBounds[0], group->mObjectBounds[1]); +} + +S32 LLViewerOctreeCull::AABBInRegionFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group) +{ +	return mCamera->AABBInRegionFrustumNoFarClip(group->mObjectBounds[0], group->mObjectBounds[1]); +} + +S32 LLViewerOctreeCull::AABBRegionSphereIntersectObjectExtents(const LLviewerOctreeGroup* group, const LLVector3& shift) +{ +	return AABBSphereIntersect(group->mObjectExtents[0], group->mObjectExtents[1], mCamera->getOrigin() - shift, mCamera->mFrustumCornerDist); +} +//------------------------------------------ + +//virtual  +bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group) +{ +	if (branch->getElementCount() == 0) //no elements +	{ +		return false; +	} +	else if (branch->getChildCount() == 0) //leaf state, already checked tightest bounding box +	{ +		return true; +	} +	else if (mRes == 1 && !frustumCheckObjects(group)) //no objects in frustum +	{ +		return false; +	} +		 +	return true; +} + +//virtual  +void LLViewerOctreeCull::preprocess(LLviewerOctreeGroup* group) +{		 +} +	 +//virtual  +void LLViewerOctreeCull::processGroup(LLviewerOctreeGroup* group) +{ +} +	 +//virtual  +void LLViewerOctreeCull::visit(const OctreeNode* branch)  +{	 +	LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) branch->getListener(0); + +	preprocess(group); +		 +	if (checkObjects(branch, group)) +	{ +		processGroup(group); +	} +} + +//-------------------------------------------------------------- +//class LLViewerOctreeDebug +//virtual  +void LLViewerOctreeDebug::visit(const OctreeNode* branch) +{ +#if 0 +	llinfos << "Node: " << (U32)branch << " # Elements: " << branch->getElementCount() << " # Children: " << branch->getChildCount() << llendl; +	for (U32 i = 0; i < branch->getChildCount(); i++) +	{ +		llinfos << "Child " << i << " : " << (U32)branch->getChild(i) << llendl; +	} +#endif +	LLviewerOctreeGroup* group = (LLviewerOctreeGroup*) branch->getListener(0); +	processGroup(group);	 +} + +//virtual  +void LLViewerOctreeDebug::processGroup(LLviewerOctreeGroup* group) +{ +#if 0 +	const LLVector4a* vec4 = group->getBounds(); +	LLVector3 vec[2]; +	vec[0].set(vec4[0].getF32ptr()); +	vec[1].set(vec4[1].getF32ptr()); +	llinfos << "Bounds: " << vec[0] << " : " << vec[1] << llendl; + +	vec4 = group->getExtents(); +	vec[0].set(vec4[0].getF32ptr()); +	vec[1].set(vec4[1].getF32ptr()); +	llinfos << "Extents: " << vec[0] << " : " << vec[1] << llendl; + +	vec4 = group->getObjectBounds(); +	vec[0].set(vec4[0].getF32ptr()); +	vec[1].set(vec4[1].getF32ptr()); +	llinfos << "ObjectBounds: " << vec[0] << " : " << vec[1] << llendl; + +	vec4 = group->getObjectExtents(); +	vec[0].set(vec4[0].getF32ptr()); +	vec[1].set(vec4[1].getF32ptr()); +	llinfos << "ObjectExtents: " << vec[0] << " : " << vec[1] << llendl; +#endif +} +//-------------------------------------------------------------- diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h new file mode 100644 index 0000000000..0a96676be1 --- /dev/null +++ b/indra/newview/llvieweroctree.h @@ -0,0 +1,422 @@ +/**  + * @file llvieweroctree.h + * @brief LLViewerObjectOctree.cpp header file, defining all supporting classes. + * + * $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$ + */ + +#ifndef LL_VIEWEROCTREE_H +#define LL_VIEWEROCTREE_H + +#include <vector> +#include <map> + +#include "v2math.h" +#include "v3math.h" +#include "v4math.h" +#include "m4math.h" +#include "llvector4a.h" +#include "llquaternion.h" +#include "lloctree.h" +#include "llviewercamera.h" + +class LLViewerRegion; +class LLViewerOctreeEntryData; +class LLviewerOctreeGroup; +class LLViewerOctreeEntry; +class LLViewerOctreePartition; + +typedef LLOctreeListener<LLViewerOctreeEntry>	OctreeListener; +typedef LLTreeNode<LLViewerOctreeEntry>			TreeNode; +typedef LLOctreeNode<LLViewerOctreeEntry>		OctreeNode; +typedef LLOctreeRoot<LLViewerOctreeEntry>		OctreeRoot; +typedef LLOctreeTraveler<LLViewerOctreeEntry>	OctreeTraveler; + +#if LL_OCTREE_PARANOIA_CHECK +#define assert_octree_valid(x) x->validate() +#define assert_states_valid(x) ((LLviewerOctreeGroup*) x->mSpatialPartition->mOctree->getListener(0))->checkStates() +#else +#define assert_octree_valid(x) +#define assert_states_valid(x) +#endif + +// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center); + +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); + +S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); +S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); + +//defines data needed for octree of an entry +LL_ALIGN_PREFIX(16) +class LLViewerOctreeEntry : public LLRefCount +{ +	friend class LLViewerOctreeEntryData; + +public: +	typedef enum +	{ +		LLDRAWABLE = 0, +		LLVOCACHEENTRY, +		NUM_DATA_TYPE +	}eEntryDataType_t; + +	~LLViewerOctreeEntry(); +public: +	LLViewerOctreeEntry(); +	 +	void nullGroup(); //called by group handleDestruction() only +	void setGroup(LLviewerOctreeGroup* group); +	void removeData(LLViewerOctreeEntryData* data); + +	LLViewerOctreeEntryData* getDrawable() const {return mData[LLDRAWABLE];} +	bool                     hasDrawable() const {return mData[LLDRAWABLE] != NULL;} +	LLViewerOctreeEntryData* getVOCacheEntry() const {return mData[LLVOCACHEENTRY];} +	bool                     hasVOCacheEntry() const {return mData[LLVOCACHEENTRY] != NULL;} + +	const LLVector4a* getSpatialExtents() const {return mExtents;}  +	const LLVector4a& getPositionGroup() const  {return mPositionGroup;}	 +	LLviewerOctreeGroup* getGroup()const        {return mGroup;} +	 +	F32  getBinRadius() const                   {return mBinRadius;} +	S32	 getBinIndex() const			        {return mBinIndex; } +	void setBinIndex(S32 index) const	        {mBinIndex = index; } + +	void* operator new(size_t size) +	{ +		return ll_aligned_malloc_16(size); +	} + +	void operator delete(void* ptr) +	{ +		ll_aligned_free_16(ptr); +	} + +private: +	void addData(LLViewerOctreeEntryData* data);			 + +private: +	LLViewerOctreeEntryData*    mData[NUM_DATA_TYPE]; //do not use LLPointer here. +	LLviewerOctreeGroup*        mGroup; + +	//aligned members +	LL_ALIGN_16(LLVector4a		mExtents[2]); +	LL_ALIGN_16(LLVector4a		mPositionGroup); +	F32				            mBinRadius; +	mutable S32		            mBinIndex; +	mutable U32		            mVisible;	 + +} LL_ALIGN_POSTFIX(16); + +//defines an abstract class for entry data +LL_ALIGN_PREFIX(16) +class LLViewerOctreeEntryData : public LLRefCount +{ +protected: +	~LLViewerOctreeEntryData(); + +public: +	LLViewerOctreeEntryData(const LLViewerOctreeEntryData& rhs) +	{ +		*this = rhs; +	} +	LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t data_type); +	 +	LLViewerOctreeEntry::eEntryDataType_t getDataType() const {return mDataType;} +	LLViewerOctreeEntry* getEntry() {return mEntry;} +	 +	virtual void setOctreeEntry(LLViewerOctreeEntry* entry); + +	virtual S32  getMinFrameRange()const = 0; + +	F32                  getBinRadius() const   {return mEntry->getBinRadius();} +	const LLVector4a*    getSpatialExtents() const; +	LLviewerOctreeGroup* getGroup()const; +	const LLVector4a&    getPositionGroup() const; +	 +	void setBinRadius(F32 rad)  {mEntry->mBinRadius = rad;} +	void setSpatialExtents(const LLVector3& min, const LLVector3& max); +	void setSpatialExtents(const LLVector4a& min, const LLVector4a& max); +	void setPositionGroup(const LLVector4a& pos); +	 +	virtual void setGroup(LLviewerOctreeGroup* group); +	void         shift(const LLVector4a &shift_vector); + +	U32          getVisible() const {return mEntry ? mEntry->mVisible : 0;} +	void         setVisible() const; +	virtual bool isVisible() const; +	virtual bool isRecentlyVisible() const;	 +	 +	static S32 getCurrentFrame() { return sCurVisible; } + +protected: +	LLVector4a& getGroupPosition()  {return mEntry->mPositionGroup;} +	void        initVisible(U32 visible) {mEntry->mVisible = visible;} + +	static void incrementVisible() {sCurVisible++;} +protected: +	LLPointer<LLViewerOctreeEntry>        mEntry; +	LLViewerOctreeEntry::eEntryDataType_t mDataType; +	static  U32                           sCurVisible; // Counter for what value of mVisible means currently visible +}LL_ALIGN_POSTFIX(16); + + +//defines an octree group for an octree node, which contains multiple entries. +LL_ALIGN_PREFIX(16) +class LLviewerOctreeGroup : public LLOctreeListener<LLViewerOctreeEntry> +{ +	friend class LLViewerOctreeCull; +protected: +	~LLviewerOctreeGroup(); + +public:	 +	enum +	{ +		CLEAN              = 0x00000000, +		DIRTY              = 0x00000001, +		OBJECT_DIRTY       = 0x00000002, +		SKIP_FRUSTUM_CHECK = 0x00000004, +		DEAD               = 0x00000008, +		INVALID_STATE      = 0x00000010, +	}; + +public: +	typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter; +	typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list; + +	LLviewerOctreeGroup(OctreeNode* node); +	LLviewerOctreeGroup(const LLviewerOctreeGroup& rhs) +	{ +		*this = rhs; +	} + +	void* operator new(size_t size) +	{ +		return ll_aligned_malloc_16(size); +	} + +	void operator delete(void* ptr) +	{ +		ll_aligned_free_16(ptr); +	} + +	bool removeFromGroup(LLViewerOctreeEntryData* data); +	bool removeFromGroup(LLViewerOctreeEntry* entry); + +	virtual void unbound(); +	virtual void rebound(); +	 +	BOOL isDead()							{ return hasState(DEAD); }	 + +	void setVisible(); +	BOOL isVisible() const; +	virtual BOOL isRecentlyVisible() const; +	bool isEmpty() const { return mOctreeNode->isEmpty(); } + +	U32  getState()				   {return mState; } +	bool isDirty() const           {return mState & DIRTY;} +	bool hasState(U32 state) const {return mState & state;} +	void setState(U32 state)       {mState |= state;} +	void clearState(U32 state)     {mState &= ~state;}	 + +	//LISTENER FUNCTIONS +	virtual void handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj); +	virtual void handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj); +	virtual void handleDestruction(const TreeNode* node); +	virtual void handleStateChange(const TreeNode* node); +	virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); +	virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); + +	OctreeNode*          getOctreeNode() {return mOctreeNode;} +	LLviewerOctreeGroup* getParent(); + +	const LLVector4a* getBounds() const        {return mBounds;} +	const LLVector4a* getExtents() const       {return mExtents;} +	const LLVector4a* getObjectBounds() const  {return mObjectBounds;} +	const LLVector4a* getObjectExtents() const {return mObjectExtents;} + +	//octree wrappers to make code more readable +	element_list& getData() { return mOctreeNode->getData(); } +	element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } +	element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } +	U32 getElementCount() const { return mOctreeNode->getElementCount(); } +	bool hasElement(LLViewerOctreeEntryData* data); +	 +protected: +	void checkStates(); +private: +	virtual bool boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut);			 + +protected: +	U32         mState; +	OctreeNode* mOctreeNode;	 + +	LL_ALIGN_16(LLVector4a mBounds[2]);        // bounding box (center, size) of this node and all its children (tight fit to objects) +	LL_ALIGN_16(LLVector4a mObjectBounds[2]);  // bounding box (center, size) of objects in this node +	LL_ALIGN_16(LLVector4a mExtents[2]);       // extents (min, max) of this node and all its children +	LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node	 + +public: +	S32         mVisible[LLViewerCamera::NUM_CAMERAS];	 + +}LL_ALIGN_POSTFIX(16); + +//octree group which has capability to support occlusion culling +//LL_ALIGN_PREFIX(16) +class LLOcclusionCullingGroup : public LLviewerOctreeGroup +{ +public: +	typedef enum +	{ +		OCCLUDED				= 0x00010000, +		QUERY_PENDING			= 0x00020000, +		ACTIVE_OCCLUSION		= 0x00040000, +		DISCARD_QUERY			= 0x00080000, +		EARLY_FAIL				= 0x00100000, +	} eOcclusionState; + +	typedef enum +	{ +		STATE_MODE_SINGLE = 0,		//set one node +		STATE_MODE_BRANCH,			//set entire branch +		STATE_MODE_DIFF,			//set entire branch as long as current state is different +		STATE_MODE_ALL_CAMERAS,		//used for occlusion state, set state for all cameras +	} eSetStateMode; + +public: +	LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part); +	LLOcclusionCullingGroup(const LLOcclusionCullingGroup& rhs) : LLviewerOctreeGroup(rhs) +	{ +		*this = rhs; +	} +	~LLOcclusionCullingGroup(); + +	void setOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); +	void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE); +	void checkOcclusion(); //read back last occlusion query (if any) +	void doOcclusion(LLCamera* camera); //issue occlusion query +	BOOL isOcclusionState(U32 state) const	{ return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }		 +	 +	BOOL needsUpdate(); + +	//virtual  +	void handleChildAddition(const OctreeNode* parent, OctreeNode* child); + +	static U32 getNewOcclusionQueryObjectName(); +	static void releaseOcclusionQueryObjectName(U32 name); + +protected: +	void releaseOcclusionQueryObjectNames(); + +private:	 +	BOOL earlyFail(LLCamera* camera); + +protected: +	U32         mOcclusionState[LLViewerCamera::NUM_CAMERAS]; +	U32         mOcclusionIssued[LLViewerCamera::NUM_CAMERAS]; + +	S32         mLODHash; + +	LLViewerOctreePartition* mSpatialPartition; +	U32		                 mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; + +public:		 +	static std::set<U32> sPendingQueries; +};//LL_ALIGN_POSTFIX(16); + +class LLViewerOctreePartition +{ +public: +	LLViewerOctreePartition(); +	virtual ~LLViewerOctreePartition(); + +	// Cull on arbitrary frustum +	virtual S32 cull(LLCamera &camera) = 0; +	BOOL isOcclusionEnabled(); + +public:	 +	U32              mPartitionType; +	U32              mDrawableType; +	OctreeNode*      mOctree; +	LLViewerRegion*  mRegionp; // the region this partition belongs to. +	BOOL             mOcclusionEnabled; // if TRUE, occlusion culling is performed +	U32              mLODSeed; +	U32              mLODPeriod;	//number of frames between LOD updates for a given spatial group (staggered by mLODSeed) +}; + +class LLViewerOctreeCull : public OctreeTraveler +{ +public: +	LLViewerOctreeCull(LLCamera* camera) +		: mCamera(camera), mRes(0) { } + +	virtual bool earlyFail(LLviewerOctreeGroup* group); +	virtual void traverse(const OctreeNode* n); +	 +	//agent space group cull +	S32 AABBInFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group);	 +	S32 AABBSphereIntersectGroupExtents(const LLviewerOctreeGroup* group); +	S32 AABBInFrustumGroupBounds(const LLviewerOctreeGroup* group); + +	//agent space object set cull +	S32 AABBInFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group); +	S32 AABBSphereIntersectObjectExtents(const LLviewerOctreeGroup* group);	 +	S32 AABBInFrustumObjectBounds(const LLviewerOctreeGroup* group); +	 +	//local region space group cull +	S32 AABBInRegionFrustumNoFarClipGroupBounds(const LLviewerOctreeGroup* group); +	S32 AABBInRegionFrustumGroupBounds(const LLviewerOctreeGroup* group); +	S32 AABBRegionSphereIntersectGroupExtents(const LLviewerOctreeGroup* group, const LLVector3& shift); + +	//local region space object set cull +	S32 AABBInRegionFrustumNoFarClipObjectBounds(const LLviewerOctreeGroup* group); +	S32 AABBInRegionFrustumObjectBounds(const LLviewerOctreeGroup* group); +	S32 AABBRegionSphereIntersectObjectExtents(const LLviewerOctreeGroup* group, const LLVector3& shift);	 +	 +	virtual S32 frustumCheck(const LLviewerOctreeGroup* group) = 0; +	virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) = 0; + +	virtual bool checkObjects(const OctreeNode* branch, const LLviewerOctreeGroup* group); +	virtual void preprocess(LLviewerOctreeGroup* group); +	virtual void processGroup(LLviewerOctreeGroup* group); +	virtual void visit(const OctreeNode* branch); +	 +protected: +	LLCamera *mCamera; +	S32 mRes; +}; + +//scan the octree, output the info of each node for debug use. +class LLViewerOctreeDebug : public OctreeTraveler +{ +public: +	virtual void processGroup(LLviewerOctreeGroup* group); +	virtual void visit(const OctreeNode* branch); + +public: +	static BOOL sInDebug; +}; + +#endif diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 6bd9f66b9c..a23a15da32 100755 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -151,8 +151,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo  	if (group != NULL)  	{ -		LLVector3 center(group->mOctreeNode->getCenter().getF32ptr()); -		LLVector3 size(group->mOctreeNode->getSize().getF32ptr()); +		LLVector3 center(group->getOctreeNode()->getCenter().getF32ptr()); +		LLVector3 size(group->getOctreeNode()->getSize().getF32ptr());  		size += LLVector3(0.01f, 0.01f, 0.01f);  		mMinObjPos = center - size;  		mMaxObjPos = center + size; @@ -467,6 +467,20 @@ LLViewerPartSim::LLViewerPartSim()  	mID = ++id_seed;  } +//enable/disable particle system +void LLViewerPartSim::enable(bool enabled) +{ +	if(!enabled && sMaxParticleCount > 0) +	{ +		sMaxParticleCount = 0; //disable +	} +	else if(enabled && sMaxParticleCount < 1) +	{ +		sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT); +	} + +	return; +}  void LLViewerPartSim::destroyClass()  { diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index c91fcf0691..5c71b4c49e 100755 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -27,7 +27,6 @@  #ifndef LL_LLVIEWERPARTSIM_H  #define LL_LLVIEWERPARTSIM_H -#include "lldarrayptr.h"  #include "llframetimer.h"  #include "llpointer.h"  #include "llpartdata.h" @@ -36,7 +35,6 @@  class LLViewerTexture;  class LLViewerPart;  class LLViewerRegion; -class LLViewerTexture;  class LLVOPartGroup;  #define LL_MAX_PARTICLE_COUNT 8192 @@ -134,6 +132,8 @@ public:  	typedef std::vector<LLViewerPartGroup *> group_list_t;  	typedef std::vector<LLPointer<LLViewerPartSource> > source_list_t; +	void enable(bool enabled); +  	void shift(const LLVector3 &offset);  	void updateSimulation(); diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index a565005f30..5df456dab6 100755 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -52,11 +52,9 @@  // Library headers from llcommon project:  #include "bitpack.h" -#include "lldeleteutils.h"  #include "imageids.h"  #include "indra_constants.h"  #include "llinitparam.h" -  #include "llallocator.h"  #include "llapp.h"  #include "llcriticaldamp.h" @@ -65,11 +63,7 @@  #include "llerror.h"  #include "llfasttimer.h"  #include "llframetimer.h" -#include "llhash.h" -#include "lllocalidhashmap.h" -#include "llnametable.h"  #include "llpointer.h" -#include "llpriqueuemap.h"  #include "llprocessor.h"  #include "llrefcount.h"  #include "llsafehandle.h" @@ -79,9 +73,7 @@  #include "llstrider.h"  #include "llstring.h"  #include "llsys.h" -#include "llthread.h"  #include "lltimer.h" -#include "lluuidhashmap.h"  #include "stdenums.h"  #include "stdtypes.h"  #include "timing.h" diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b8b53aa6e4..781a754b7c 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -70,6 +70,7 @@  #include "stringize.h"  #include "llviewercontrol.h"  #include "llsdserialize.h" +#include "llvieweroctree.h"  #ifdef LL_WINDOWS  	#pragma warning(disable:4355) @@ -85,31 +86,36 @@ const F32 CAP_REQUEST_TIMEOUT = 18;  // Even though we gave up on login, keep trying for caps after we are logged in:  const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; +BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE; +  typedef std::map<std::string, std::string> CapabilityMap;  class LLViewerRegionImpl {  public:  	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host) -		:	mHost(host), -			mCompositionp(NULL), -			mEventPoll(NULL), -			mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), -			mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), -			mSeedCapAttempts(0), -			mHttpResponderID(0), -		    // I'd prefer to set the LLCapabilityListener name to match the region -		    // name -- it's disappointing that's not available at construction time. -		    // We could instead store an LLCapabilityListener*, making -		    // setRegionNameAndZone() replace the instance. Would that pose -		    // consistency problems? Can we even request a capability before calling -		    // setRegionNameAndZone()? -		    // For testability -- the new Michael Feathers paradigm -- -		    // LLCapabilityListener binds all the globals it expects to need at -		    // construction time. -		    mCapabilityListener(host.getString(), gMessageSystem, *region, -		                        gAgent.getID(), gAgent.getSessionID()) -	{ -	} +	:	mHost(host), +		mCompositionp(NULL), +		mEventPoll(NULL), +		mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), +		mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), +		mSeedCapAttempts(0), +		mHttpResponderID(0), +		mLastCameraUpdate(0), +		mLastCameraOrigin(), +		mVOCachePartition(NULL), +		mLandp(NULL), +		// I'd prefer to set the LLCapabilityListener name to match the region +		// name -- it's disappointing that's not available at construction time. +		// We could instead store an LLCapabilityListener*, making +		// setRegionNameAndZone() replace the instance. Would that pose +		// consistency problems? Can we even request a capability before calling +		// setRegionNameAndZone()? +		// For testability -- the new Michael Feathers paradigm -- +		// LLCapabilityListener binds all the globals it expects to need at +		// construction time. +		mCapabilityListener(host.getString(), gMessageSystem, *region, +		                    gAgent.getID(), gAgent.getSessionID()) +	{}  	void buildCapabilityNames(LLSD& capabilityNames); @@ -133,7 +139,14 @@ public:  	// Misc  	LLVLComposition *mCompositionp;		// Composition layer for the surface -	LLVOCacheEntry::vocache_entry_map_t		mCacheMap; +	LLVOCacheEntry::vocache_entry_map_t	  mCacheMap; //all cached entries +	LLVOCacheEntry::vocache_entry_set_t   mActiveSet; //all active entries; +	LLVOCacheEntry::vocache_entry_set_t   mWaitingSet; //entries waiting for LLDrawable to be generated.	 +	std::set< LLPointer<LLviewerOctreeGroup> >      mVisibleGroups; //visible groupa +	LLVOCachePartition*                   mVOCachePartition; +	LLVOCacheEntry::vocache_entry_set_t   mVisibleEntries; //must-be-created visible entries wait for objects creation.	 +	LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation. +  	// time?  	// LRU info? @@ -143,7 +156,7 @@ public:  	CapabilityMap mCapabilities;  	CapabilityMap mSecondCapabilitiesTracker;  - +	  	LLEventPoll* mEventPoll;  	S32 mSeedCapMaxAttempts; @@ -158,7 +171,10 @@ public:  	LLCapabilityListener mCapabilityListener;  	//spatial partitions for objects in this region -	std::vector<LLSpatialPartition*> mObjectPartition; +	std::vector<LLViewerOctreePartition*> mObjectPartition; + +	LLVector3 mLastCameraOrigin; +	U32       mLastCameraUpdate;  };  // support for secondlife:///app/region/{REGION} SLapps @@ -350,7 +366,10 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	mCacheLoaded(FALSE),  	mCacheDirty(FALSE),  	mReleaseNotesRequested(FALSE), -	mCapabilitiesReceived(false) +	mCapabilitiesReceived(false), +	mBitsReceived(0.f), +	mPacketsReceived(0.f), +	mDead(FALSE)  {  	mWidth = region_width_meters;  	mImpl->mOriginGlobal = from_region_handle(handle);  @@ -382,17 +401,20 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	//create object partitions  	//MUST MATCH declaration of eObjectPartitions -	mImpl->mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD -	mImpl->mObjectPartition.push_back(new LLTerrainPartition());	//PARTITION_TERRAIN -	mImpl->mObjectPartition.push_back(new LLVoidWaterPartition());	//PARTITION_VOIDWATER -	mImpl->mObjectPartition.push_back(new LLWaterPartition());		//PARTITION_WATER -	mImpl->mObjectPartition.push_back(new LLTreePartition());		//PARTITION_TREE -	mImpl->mObjectPartition.push_back(new LLParticlePartition());	//PARTITION_PARTICLE -	mImpl->mObjectPartition.push_back(new LLGrassPartition());		//PARTITION_GRASS -	mImpl->mObjectPartition.push_back(new LLVolumePartition());	//PARTITION_VOLUME -	mImpl->mObjectPartition.push_back(new LLBridgePartition());	//PARTITION_BRIDGE -	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE +	mImpl->mObjectPartition.push_back(new LLHUDPartition(this));		//PARTITION_HUD +	mImpl->mObjectPartition.push_back(new LLTerrainPartition(this));	//PARTITION_TERRAIN +	mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this));	//PARTITION_VOIDWATER +	mImpl->mObjectPartition.push_back(new LLWaterPartition(this));		//PARTITION_WATER +	mImpl->mObjectPartition.push_back(new LLTreePartition(this));		//PARTITION_TREE +	mImpl->mObjectPartition.push_back(new LLParticlePartition(this));	//PARTITION_PARTICLE +	mImpl->mObjectPartition.push_back(new LLGrassPartition(this));		//PARTITION_GRASS +	mImpl->mObjectPartition.push_back(new LLVolumePartition(this));	//PARTITION_VOLUME +	mImpl->mObjectPartition.push_back(new LLBridgePartition(this));	//PARTITION_BRIDGE +	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE +	mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE  	mImpl->mObjectPartition.push_back(NULL);						//PARTITION_NONE + +	mImpl->mVOCachePartition = getVOCachePartition();  } @@ -413,6 +435,12 @@ void LLViewerRegion::initStats()  LLViewerRegion::~LLViewerRegion()   { +	mDead = TRUE; +	mImpl->mActiveSet.clear(); +	mImpl->mVisibleEntries.clear(); +	mImpl->mVisibleGroups.clear(); +	mImpl->mWaitingSet.clear(); +  	gVLManager.cleanupData(this);  	// Can't do this on destruction, because the neighbor pointers might be invalid.  	// This should be reference counted... @@ -427,10 +455,10 @@ LLViewerRegion::~LLViewerRegion()  	delete mImpl->mEventPoll;  	LLHTTPSender::clearSender(mImpl->mHost); -	saveObjectCache(); -  	std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); +	saveObjectCache(); +  	delete mImpl;  	mImpl = NULL;  } @@ -471,9 +499,13 @@ void LLViewerRegion::loadObjectCache()  	// Presume success.  If it fails, we don't want to try again.  	mCacheLoaded = TRUE; -	if(LLVOCache::hasInstance()) +	if(LLVOCache::instanceExists())  	{  		LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ; +		if (mImpl->mCacheMap.empty()) +		{ +			mCacheDirty = TRUE; +		}  	}  } @@ -490,16 +522,15 @@ void LLViewerRegion::saveObjectCache()  		return;  	} -	if(LLVOCache::hasInstance()) +	if(LLVOCache::instanceExists())  	{ -		LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ; +		const F32 start_time_threshold = 600.0f; //seconds +		bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file. +		 +		LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ;  		mCacheDirty = FALSE;  	} -	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter) -	{ -		delete iter->second; -	}  	mImpl->mCacheMap.clear();  } @@ -765,8 +796,339 @@ void LLViewerRegion::dirtyHeights()  	}  } +void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) +{ +	U32 state = LLVOCacheEntry::INACTIVE; +	bool in_vo_tree = false; + +	if(old_entry) +	{ +		old_entry->moveTo(new_entry); +		state = old_entry->getState(); +		in_vo_tree = (state == LLVOCacheEntry::INACTIVE && old_entry->getGroup() != NULL); +		killCacheEntry(old_entry); +	} + +	mImpl->mCacheMap[new_entry->getLocalID()] = new_entry; + +	if(state == LLVOCacheEntry::ACTIVE) +	{ +		llassert(new_entry->getEntry()->hasDrawable()); +		mImpl->mActiveSet.insert(new_entry); +	} +	else if(state == LLVOCacheEntry::WAITING) +	{ +		mImpl->mWaitingSet.insert(new_entry); +	} +	else if(!old_entry || in_vo_tree) +	{ +		addToVOCacheTree(new_entry); +	} +	new_entry->setState(state); +} + +//physically delete the cache entry +void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry) +{	 +	if(!entry) +	{ +		return; +	} + +	//remove from active list and waiting list +	if(entry->isState(LLVOCacheEntry::ACTIVE)) +	{ +		mImpl->mActiveSet.erase(entry); +	} +	else +	{ +		if(entry->isState(LLVOCacheEntry::WAITING)) +		{ +			mImpl->mWaitingSet.erase(entry); +		} +		 +		//remove from mVOCachePartition +		removeFromVOCacheTree(entry); +	} + +	//remove from the forced visible list +	mImpl->mVisibleEntries.erase(entry); + +	//kill LLViewerObject if exists +	//this should be done by the rendering pipeline automatically. +	 +	entry->setState(LLVOCacheEntry::INACTIVE); +	 +	//remove from mCacheMap, real deletion +	mImpl->mCacheMap.erase(entry->getLocalID()); +} + +//physically delete the cache entry	 +void LLViewerRegion::killCacheEntry(U32 local_id)  +{ +	killCacheEntry(getCacheEntry(local_id)); +} + +U32 LLViewerRegion::getNumOfActiveCachedObjects() const +{ +	return  mImpl->mActiveSet.size(); +} + +void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry) +{ +	if(!entry || mDead) +	{ +		return; +	} + +	if(entry->isState(LLVOCacheEntry::WAITING)) +	{ +		mImpl->mWaitingSet.erase(entry); +	} + +	entry->setState(LLVOCacheEntry::ACTIVE); +	entry->setVisible(); + +	llassert(entry->getEntry()->hasDrawable()); +	mImpl->mActiveSet.insert(entry); +} + +void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep) +{ +	if(mDead) +	{ +		return; +	} + +	if(drawablep->getParent()) //child object +	{ +		LLViewerOctreeEntry* parent_oct_entry = drawablep->getParent()->getEntry(); +		if(parent_oct_entry && parent_oct_entry->hasVOCacheEntry()) +		{ +			LLVOCacheEntry* parent = (LLVOCacheEntry*)parent_oct_entry->getVOCacheEntry(); +			parent->addChild(entry); +		} +	} +	else //insert to vo cache tree. +	{ +		//shift to the local regional space from agent space +		const LLVector3 pos = drawablep->getVObj()->getPositionRegion(); +		LLVector4a vec(pos[0], pos[1], pos[2]); +		LLVector4a shift;  +		shift.setSub(vec, entry->getPositionGroup()); +		entry->shift(shift); +		 +		addToVOCacheTree(entry); +	} + +	mImpl->mVisibleEntries.erase(entry); +	mImpl->mActiveSet.erase(entry); +	mImpl->mWaitingSet.erase(entry); +	entry->setState(LLVOCacheEntry::INACTIVE); +} + +void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) +{ +	if(mDead || group->isEmpty()) +	{ +		return; +	} +	group->setVisible(); +	mImpl->mVisibleGroups.insert(group); +} + +void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) +{ +	if(!sVOCacheCullingEnabled) +	{ +		return; +	} + +	if(mDead || !entry || !entry->getEntry()) +	{ +		return; +	} +	if(entry->getGroup()) //already in octree. +	{ +		return; +	} + +	mImpl->mVOCachePartition->addEntry(entry->getEntry()); +} + +void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry) +{ +	if(mDead || !entry || !entry->getEntry()) +	{ +		return; +	} +	if(!entry->getGroup()) +	{ +		return; +	} + +	mImpl->mVOCachePartition->removeEntry(entry->getEntry()); +} + +//add the visible entries +void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) +{ +	if(mDead || !entry) +	{ +		return;  +	} + +	if(entry->isState(LLVOCacheEntry::IN_QUEUE)) +	{ +		return; +	} + +	if(entry->isState(LLVOCacheEntry::INACTIVE)) +	{ +		entry->setState(LLVOCacheEntry::IN_QUEUE); +	} +	mImpl->mVisibleEntries.insert(entry); +} + +F32 LLViewerRegion::updateVisibleEntries(F32 max_time) +{ +	if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty()) +	{ +		return max_time; +	} + +	LLTimer update_timer; + +	const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin(); +	const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame(); +	bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f);	 + +	//process visible entries +	max_time *= 0.5f; //only use up to half available time to update entries. + +#if 1 +	for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) +	{ +		LLVOCacheEntry* vo_entry = *iter; +		vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); + +		if(vo_entry->getState() < LLVOCacheEntry::WAITING) +		{			 +			mImpl->mWaitingList.insert(vo_entry); +		} + +		LLVOCacheEntry* child; +		S32 num_child = vo_entry->getNumOfChildren(); +		S32 num_done = 0; +		for(S32 i = 0; i < num_child; i++) +		{ +			child = vo_entry->getChild(i); +			if(child->getState() < LLVOCacheEntry::WAITING) +			{ +				child->setSceneContribution(vo_entry->getSceneContribution()); +				mImpl->mWaitingList.insert(child); +			} +			else +			{ +				num_done++; +			} +		} +		if(num_done == num_child) +		{ +			vo_entry->clearChildrenList(); +		} + +		if(!vo_entry->getNumOfChildren()) +		{ +			if(vo_entry->getState() >= LLVOCacheEntry::WAITING) +			{ +				LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter; +				++next_iter; +				mImpl->mVisibleEntries.erase(iter); +				iter = next_iter; +			} +			else +			{ +				++iter; +			} +		} +		else +		{ +			++iter; +		} +	} +#endif + +	//process visible groups +	std::set< LLPointer<LLviewerOctreeGroup> >::iterator group_iter = mImpl->mVisibleGroups.begin(); +	for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter) +	{ +		LLPointer<LLviewerOctreeGroup> group = *group_iter; +		if(group->getNumRefs() < 3 || //group to be deleted +			!group->getOctreeNode() || group->isEmpty()) //group empty +		{ +			continue; +		} + +		for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) +		{ +			if((*i)->hasVOCacheEntry()) +			{ +				LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry(); + +				if(vo_entry->getParentID() > 0) //is a child +				{ +					//child visibility depends on its parent. +					continue; +				} + +				vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate);				 +				mImpl->mWaitingList.insert(vo_entry); +			} +		} +	} + +	if(needs_update) +	{ +		mImpl->mLastCameraOrigin = camera_origin; +		mImpl->mLastCameraUpdate = cur_frame; +	} + +	return 2.0f * max_time - update_timer.getElapsedTimeF32(); +} + +F32 LLViewerRegion::createVisibleObjects(F32 max_time) +{ +	if(mImpl->mWaitingList.empty()) +	{ +		return max_time; +	} + +	LLTimer update_timer; +	S32 max_num_objects = 64; //minimum number of new objects to be added +	for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin(); +		iter != mImpl->mWaitingList.end(); ++iter) +	{ +		LLVOCacheEntry* vo_entry = *iter; +			 +		if(vo_entry->getState() < LLVOCacheEntry::WAITING) +		{ +			addNewObject(vo_entry); +			if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) +			{ +				break; +			} +		} +	} +	mImpl->mWaitingList.clear(); + +	return max_time - update_timer.getElapsedTimeF32(); +} +  BOOL LLViewerRegion::idleUpdate(F32 max_update_time)  { +	LLTimer update_timer; +  	// did_update returns TRUE if we did at least one significant update  	BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); @@ -776,9 +1138,146 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)  		mParcelOverlay->idleUpdate();  	} +	max_update_time -= update_timer.getElapsedTimeF32(); +	if(max_update_time < 0.f || mImpl->mCacheMap.empty()) +	{ +		return did_update; +	} + +	if(!sVOCacheCullingEnabled) +	{ +		return did_update; +	} + +	//kill invisible objects +	max_update_time = killInvisibleObjects(max_update_time);	 +	 +	max_update_time = updateVisibleEntries(max_update_time); +	createVisibleObjects(max_update_time); + +	mImpl->mVisibleGroups.clear(); +  	return did_update;  } +F32 LLViewerRegion::killInvisibleObjects(F32 max_time) +{ +#if 1 +	if(!sVOCacheCullingEnabled) +	{ +		return max_time; +	} +	if(mImpl->mActiveSet.empty()) +	{ +		return max_time; +	} + +	static LLVOCacheEntry* last_visited_entry = NULL; + +	const size_t MAX_UPDATE = 32;  +	std::vector<LLDrawable*> delete_list; +	S32 update_counter = llmin(MAX_UPDATE, mImpl->mActiveSet.size()); +	LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(last_visited_entry);	 +	 +	for(; update_counter > 0; --update_counter, ++iter) +	{	 +		if(iter == mImpl->mActiveSet.end()) +		{ +			iter = mImpl->mActiveSet.begin(); +		} + +		if(!(*iter)->isRecentlyVisible()) +		{ +			killObject((*iter), delete_list); +		} +	} + +	if(iter == mImpl->mActiveSet.end()) +	{ +		last_visited_entry = NULL; +	} +	else +	{ +		last_visited_entry = *iter; +	} + +	for(S32 i = 0; i < delete_list.size(); i++) +	{ +		gObjectList.killObject(delete_list[i]->getVObj()); +	} +	delete_list.clear(); +#endif +	return max_time; +} + +void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list) +{ +	//kill the object. +	LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable(); +	llassert(drawablep); + +	if(!drawablep->getParent()) +	{ +		LLViewerObject::const_child_list_t& child_list = drawablep->getVObj()->getChildren(); +		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); +			iter != child_list.end(); iter++) +		{ +			LLViewerObject* child = *iter; +			if(child->mDrawable->isRecentlyVisible()) +			{ +				//set the parent group visible if any of its children visible. +				((LLViewerOctreeEntryData*)drawablep)->setVisible(); +				return; +			} +		} +		delete_list.push_back(drawablep);				 +	}				 +} + +LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) +{ +	LLViewerObject* obj = NULL; +	if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet +	{ +		//add the object +		obj = gObjectList.processObjectUpdateFromCache(entry, this); +		if(obj) +		{ +			if(!entry->isState(LLVOCacheEntry::ACTIVE)) +			{ +				mImpl->mWaitingSet.insert(entry); +				entry->setState(LLVOCacheEntry::WAITING); +			} +		} +	} +	else +	{ +		llerrs << "Object is already created." << llendl; +	} +	return obj; +} + +//remove from object cache if the object receives a full-update or terse update +LLViewerObject* LLViewerRegion::forceToRemoveFromCache(U32 local_id, LLViewerObject* objectp) +{ +	LLVOCacheEntry* entry = getCacheEntry(local_id); +	if (!entry) +	{ +		return objectp; //not in the cache, do nothing. +	} +	if(!objectp) //object not created +	{ +		entry->setTouched(FALSE); //mark this entry invalid + +		//create a new object before delete it from cache. +		objectp = gObjectList.processObjectUpdateFromCache(entry, this); +	} + +	//remove from cache. +	killCacheEntry(entry); + +	return objectp; +}  // As above, but forcibly do the update.  void LLViewerRegion::forceUpdate() @@ -956,9 +1455,8 @@ void LLViewerRegion::updateNetStats()  	mPacketsLost =				cdp->getPacketsLost();  	mPingDelay =				cdp->getPingDelay(); -	mBitStat.addValue(mBitsIn - mLastBitsIn); -	mPacketsStat.addValue(mPacketsIn - mLastPacketsIn); -	mPacketsLostStat.addValue(mPacketsLost); +	mBitsReceived += mBitsIn - mLastBitsIn; +	mPacketsReceived += mPacketsIn - mLastPacketsIn;  } @@ -1234,12 +1732,118 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)  	mSimulatorFeatures = sim_features;  } -LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) +//this is called when the parent is not cacheable. +//move all orphan children out of cache and insert to rendering octree. +void LLViewerRegion::findOrphans(U32 parent_id) +{ +	orphan_list_t::iterator iter = mOrphanMap.find(parent_id); +	if(iter != mOrphanMap.end()) +	{ +		std::vector<U32>* children = &mOrphanMap[parent_id]; +		for(S32 i = 0; i < children->size(); i++) +		{ +			forceToRemoveFromCache((*children)[i], NULL); +		} +		children->clear(); +		mOrphanMap.erase(parent_id); +	} +} + +void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) +{ +	if(!sVOCacheCullingEnabled) +	{ +		gObjectList.processObjectUpdateFromCache(entry, this); +		return; +	} + +	if(entry != NULL && !entry->getEntry()) +	{ +		entry->setOctreeEntry(NULL); +	} +	else if(entry->getGroup() != NULL) +	{ +		return; //already in octree, no post processing. +	} + +	LLVector3 pos; +	LLVector3 scale; +	LLQuaternion rot; + +	//decode spatial info and parent info +	U32 parent_id = LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot); +	 +	if(parent_id > 0) //has parent +	{ +		entry->setParentID(parent_id); +	 +		//1, find the parent in cache +		LLVOCacheEntry* parent = getCacheEntry(parent_id); +		 +		//2, parent is not in the cache, put into the orphan list. +		if(!parent) +		{ +			mOrphanMap[parent_id].push_back(entry->getLocalID()); +		} +		else //parent in cache +		{ +			if(!parent->isState(LLVOCacheEntry::INACTIVE))  +			{ +				//parent is visible, so is the child. +				addVisibleCacheEntry(entry); +			} +			else +			{ +				parent->addChild(entry); +			} +		} + +		return; +	} +	 +	// +	//no parent +	// +	entry->setBoundingInfo(pos, scale); +	if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) +	{ +		addToVOCacheTree(entry); +	} + +	if(!parent_id) //a potential parent +	{ +		//find all children and update their bounding info +		orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID()); +		if(iter != mOrphanMap.end()) +		{			 +			std::vector<U32>* orphans = &mOrphanMap[entry->getLocalID()]; +			S32 size = orphans->size(); +			for(S32 i = 0; i < size; i++) +			{ +				LLVOCacheEntry* child = getCacheEntry((*orphans)[i]); +				if(child) +				{ +					entry->addChild(child); +				} +			} +			orphans->clear(); +			mOrphanMap.erase(entry->getLocalID()); +		} +	} +	 +	return ; +} + +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags)  { -	U32 local_id = objectp->getLocalID(); -	U32 crc = objectp->getCRC(); +	eCacheUpdateResult result; +	U32 crc; +	U32 local_id; -	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); +	LLViewerObject::unpackU32(&dp, local_id, "LocalID"); +	LLViewerObject::unpackU32(&dp, crc, "CRC"); + +	LLVOCacheEntry* entry = getCacheEntry(local_id);  	if (entry)  	{ @@ -1248,41 +1852,110 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec  		{  			// Record a hit  			entry->recordDupe(); -			return CACHE_UPDATE_DUPE; +			result = CACHE_UPDATE_DUPE;  		} +		else +		{ +			// Update the cache entry +			LLPointer<LLVOCacheEntry> new_entry = new LLVOCacheEntry(local_id, crc, dp); -		// Update the cache entry -		mImpl->mCacheMap.erase(local_id); -		delete entry; +			//if visible, update it +			if(!entry->isState(LLVOCacheEntry::INACTIVE)) +			{ +				replaceCacheEntry(entry, new_entry); +			} +			else //invisible +			{ +				//remove old entry +				killCacheEntry(entry); +				entry = new_entry; +				 +				mImpl->mCacheMap[local_id] = entry; +				decodeBoundingInfo(entry); +			} +			 +			result = CACHE_UPDATE_CHANGED; +		} +	} +	else +	{ +		// we haven't seen this object before +		// Create new entry and add to map +		result = CACHE_UPDATE_ADDED;  		entry = new LLVOCacheEntry(local_id, crc, dp); +		  		mImpl->mCacheMap[local_id] = entry; -		return CACHE_UPDATE_CHANGED; +		 +		decodeBoundingInfo(entry);  	} +	entry->setUpdateFlags(flags); + +	return result; +} -	// we haven't seen this object before +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags) +{ +	eCacheUpdateResult result = cacheFullUpdate(dp, flags); -	// Create new entry and add to map -	eCacheUpdateResult result = CACHE_UPDATE_ADDED; -	if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) +#if 0 +	LLVOCacheEntry* entry = mImpl->mCacheMap[objectp->getLocalID()]; +	if(!entry)  	{ -		delete mImpl->mCacheMap.begin()->second ; -		mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); -		result = CACHE_UPDATE_REPLACED; +		return result; +	} +	if(objectp->mDrawable.notNull() && !entry->getEntry()) +	{ +		entry->setOctreeEntry(objectp->mDrawable->getEntry()); +	} +	if(entry->getEntry() && entry->getEntry()->hasDrawable() && entry->isState(LLVOCacheEntry::INACTIVE)) +	{ +		addActiveCacheEntry(entry);  	} -	entry = new LLVOCacheEntry(local_id, crc, dp); +#endif -	mImpl->mCacheMap[local_id] = entry;  	return result;  } +LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) +{ +	if(!sVOCacheCullingEnabled) +	{ +		return NULL; +	} + +	LLVOCacheEntry* entry = getCacheEntry(local_id); +	removeFromVOCacheTree(entry); +		 +	return entry; +} + +LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) +{ +	LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id); +	if(iter != mImpl->mCacheMap.end()) +	{ +		return iter->second; +	} +	return NULL; +} + +void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type) +{ +#if 0 +	mCacheMissList.insert(CacheMissItem(id, miss_type)); +#else +	mCacheMissList.push_back(CacheMissItem(id, miss_type)); +#endif +} +  // Get data packer for this object, if we have cached data  // AND the CRC matches. JC -LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) +bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type)  {  	//llassert(mCacheLoaded);  This assert failes often, changing to early-out -- davep, 2010/10/18 -	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); +	LLVOCacheEntry* entry = getCacheEntry(local_id);  	if (entry)  	{ @@ -1291,45 +1964,57 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)  		{  			// Record a hit  			entry->recordHit(); -		cache_miss_type = CACHE_MISS_TYPE_NONE; -			return entry->getDP(crc); +			cache_miss_type = CACHE_MISS_TYPE_NONE; +			entry->setUpdateFlags(flags); +			 +			if(entry->isState(LLVOCacheEntry::ACTIVE)) +			{ +				((LLDrawable*)entry->getEntry()->getDrawable())->getVObj()->loadFlags(flags); +				return true; +			} + +			if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE)) +			{ +				return true; +			} + +			decodeBoundingInfo(entry); +			return true;  		}  		else  		{  			// llinfos << "CRC miss for " << local_id << llendl; -		cache_miss_type = CACHE_MISS_TYPE_CRC; -			mCacheMissCRC.put(local_id); + +			addCacheMiss(local_id, CACHE_MISS_TYPE_CRC);  		}  	}  	else  	{  		// llinfos << "Cache miss for " << local_id << llendl; -	cache_miss_type = CACHE_MISS_TYPE_FULL; -		mCacheMissFull.put(local_id); +		addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);  	} -	return NULL; +	return false;  }  void LLViewerRegion::addCacheMissFull(const U32 local_id)  { -	mCacheMissFull.put(local_id); +	addCacheMiss(local_id, CACHE_MISS_TYPE_FULL);  }  void LLViewerRegion::requestCacheMisses()  { -	S32 full_count = mCacheMissFull.count(); -	S32 crc_count = mCacheMissCRC.count(); -	if (full_count == 0 && crc_count == 0) return; +	if (!mCacheMissList.size())  +	{ +		return; +	}  	LLMessageSystem* msg = gMessageSystem;  	BOOL start_new_message = TRUE;  	S32 blocks = 0; -	S32 i; -	// Send full cache miss updates.  For these, we KNOW we don't -	// have a viewer object. -	for (i = 0; i < full_count; i++) +	//send requests for all cache-missed objects +	for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter)  	{  		if (start_new_message)  		{ @@ -1341,34 +2026,8 @@ void LLViewerRegion::requestCacheMisses()  		}  		msg->nextBlockFast(_PREHASH_ObjectData); -		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL); -		msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]); -		blocks++; - -		if (blocks >= 255) -		{ -			sendReliableMessage(); -			start_new_message = TRUE; -			blocks = 0; -		} -	} - -	// Send CRC miss updates.  For these, we _might_ have a viewer object, -	// but probably not. -	for (i = 0; i < crc_count; i++) -	{ -		if (start_new_message) -		{ -			msg->newMessageFast(_PREHASH_RequestMultipleObjects); -			msg->nextBlockFast(_PREHASH_AgentData); -			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -			start_new_message = FALSE; -		} - -		msg->nextBlockFast(_PREHASH_ObjectData); -		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC); -		msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]); +		msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType); +		msg->addU32Fast(_PREHASH_ID, (*iter).mID);  		blocks++;  		if (blocks >= 255) @@ -1384,13 +2043,13 @@ void LLViewerRegion::requestCacheMisses()  	{  		sendReliableMessage();  	} -	mCacheMissFull.reset(); -	mCacheMissCRC.reset();  	mCacheDirty = TRUE ;  	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl; -	LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count); +	LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size());  	LLViewerStatsRecorder::instance().log(0.2f); + +	mCacheMissList.clear();  }  void LLViewerRegion::dumpCache() @@ -1568,8 +2227,20 @@ void LLViewerRegion::unpackRegionHandshake()  	msg->addUUID("AgentID", gAgent.getID());  	msg->addUUID("SessionID", gAgent.getSessionID());  	msg->nextBlock("RegionInfo"); -	msg->addU32("Flags", 0x0 ); + +	U32 flags = 0; +	if(sVOCacheCullingEnabled) +	{ +		flags = 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects. +		if(mImpl->mCacheMap.empty()) +		{ +			flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes. +		} +	} +	msg->addU32("Flags", flags );  	msg->sendReliable(host); + +	mRegionTimer.reset(); //reset region timer.  }  void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) @@ -1587,7 +2258,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("EventQueueGet");  	if (gSavedSettings.getBOOL("UseHTTPInventory")) -	{	 +	{  		capabilityNames.append("FetchLib2");  		capabilityNames.append("FetchLibDescendents2");  		capabilityNames.append("FetchInventory2"); @@ -1606,7 +2277,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("LandResources");  	capabilityNames.append("MapLayer");  	capabilityNames.append("MapLayerGod"); -	capabilityNames.append("MeshUploadFlag");	 +	capabilityNames.append("MeshUploadFlag");  	capabilityNames.append("NavMeshGenerationStatus");  	capabilityNames.append("NewFileAgentInventory");  	capabilityNames.append("ObjectMedia"); @@ -1646,7 +2317,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("ViewerMetrics");  	capabilityNames.append("ViewerStartAuction");  	capabilityNames.append("ViewerStats"); - +	  	// Please add new capabilities alphabetically to reduce  	// merge conflicts.  } @@ -1654,7 +2325,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  void LLViewerRegion::setSeedCapability(const std::string& url)  {  	if (getCapability("Seed") == url) -    {	 +    {  		//llwarns << "Ignoring duplicate seed capability" << llendl;  		//Instead of just returning we build up a second set of seed caps and compare them   		//to the "original" seed cap received and determine why there is problem! @@ -1864,9 +2535,18 @@ void LLViewerRegion::logActiveCapabilities() const  LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)  { -	if (type < mImpl->mObjectPartition.size()) +	if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE) +	{ +		return (LLSpatialPartition*)mImpl->mObjectPartition[type]; +	} +	return NULL; +} + +LLVOCachePartition* LLViewerRegion::getVOCachePartition() +{ +	if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size())  	{ -		return mImpl->mObjectPartition[type]; +		return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE];  	}  	return NULL;  } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b5fe4677b7..b39bac62bc 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -34,7 +34,6 @@  #include "lldarray.h"  #include "llwind.h" -#include "llstat.h"  #include "v3dmath.h"  #include "llstring.h"  #include "llregionflags.h" @@ -66,8 +65,11 @@ class LLDataPacker;  class LLDataPackerBinaryBuffer;  class LLHost;  class LLBBox; - +class LLSpatialGroup; +class LLDrawable;  class LLViewerRegionImpl; +class LLviewerOctreeGroup; +class LLVOCachePartition;  class LLViewerRegion: public LLCapabilityProvider // implements this interface  { @@ -85,6 +87,7 @@ public:  		PARTITION_VOLUME,  		PARTITION_BRIDGE,  		PARTITION_HUD_PARTICLE, +		PARTITION_VO_CACHE,  		PARTITION_NONE,  		NUM_PARTITIONS  	} eObjectPartitions; @@ -223,6 +226,11 @@ public:  	F32	getWidth() const						{ return mWidth; }  	BOOL idleUpdate(F32 max_update_time); +	void addVisibleGroup(LLviewerOctreeGroup* group); +	void addVisibleCacheEntry(LLVOCacheEntry* entry); +	void addActiveCacheEntry(LLVOCacheEntry* entry); +	void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep);	 +	void killCacheEntry(U32 local_id); //physically delete the cache entry	  	// Like idleUpdate, but forces everything to complete regardless of  	// how long it takes. @@ -315,10 +323,16 @@ public:  	} eCacheUpdateResult;  	// handle a full update message -	eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp); -	LLDataPacker *getDP(U32 local_id, U32 crc, U8 &cache_miss_type); +	eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags); +	eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags);	 +	LLVOCacheEntry* getCacheEntryForOctree(U32 local_id); +	LLVOCacheEntry* getCacheEntry(U32 local_id); +	bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type);  	void requestCacheMisses();  	void addCacheMissFull(const U32 local_id); +	//remove from object cache if the object receives a full-update or terse update +	LLViewerObject* forceToRemoveFromCache(U32 local_id, LLViewerObject* objectp); +	void findOrphans(U32 parent_id);  	void dumpCache(); @@ -332,7 +346,9 @@ public:      virtual std::string getDescription() const;  	std::string getHttpUrl() const { return mHttpUrl ;} +	U32 getNumOfActiveCachedObjects() const;  	LLSpatialPartition* getSpatialPartition(U32 type); +	LLVOCachePartition* getVOCachePartition();  	bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;  	bool childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const; @@ -342,7 +358,21 @@ public:  	void getNeighboringRegionsStatus( std::vector<S32>& regions );  	const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }  	LLViewerRegionImpl * getRegionImplNC() { return mImpl; } - +	 +private: +	void addToVOCacheTree(LLVOCacheEntry* entry); +	LLViewerObject* addNewObject(LLVOCacheEntry* entry); +	void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list);	 +	void removeFromVOCacheTree(LLVOCacheEntry* entry); +	void replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry); +	void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry	 + +	F32 killInvisibleObjects(F32 max_time); +	F32 createVisibleObjects(F32 max_time); +	F32 updateVisibleEntries(F32 max_time); //update visible entries + +	void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type); +	void decodeBoundingInfo(LLVOCacheEntry* entry);  public:  	struct CompareDistance  	{ @@ -362,9 +392,8 @@ public:  	LLWind  mWind;  	LLViewerParcelOverlay	*mParcelOverlay; -	LLStat	mBitStat; -	LLStat	mPacketsStat; -	LLStat	mPacketsLostStat; +	F32		mBitsReceived; +	F32		mPacketsReceived;  	LLMatrix4 mRenderMatrix; @@ -376,8 +405,10 @@ public:  	LLDynamicArray<U32> mMapAvatars;  	LLDynamicArray<LLUUID> mMapAvatarIDs; +	static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not.  private:  	LLViewerRegionImpl * mImpl; +	LLFrameTimer         mRegionTimer;  	F32			mWidth;			// Width of region on a side (meters)  	U64			mHandle; @@ -421,18 +452,29 @@ private:  	// Maps local ids to cache entries.  	// Regions can have order 10,000 objects, so assume  	// a structure of size 2^14 = 16,000 -	BOOL									mCacheLoaded; -	BOOL                                    mCacheDirty; +	BOOL	mCacheLoaded; +	BOOL    mCacheDirty; +	BOOL	mAlive;					// can become false if circuit disconnects +	BOOL	mCapabilitiesReceived; +	BOOL    mReleaseNotesRequested; +	BOOL    mDead;  //if true, this region is in the process of deleting. -	LLDynamicArray<U32>						mCacheMissFull; -	LLDynamicArray<U32>						mCacheMissCRC; +	typedef std::map<U32, std::vector<U32> > orphan_list_t; +	orphan_list_t mOrphanMap; -	bool	mAlive;					// can become false if circuit disconnects -	bool	mCapabilitiesReceived; -	caps_received_signal_t mCapabilitiesReceivedSignal; +	class CacheMissItem +	{ +	public: +		CacheMissItem(U32 id, LLViewerRegion::eCacheMissType miss_type) : mID(id), mType(miss_type){} + +		U32                            mID;     //local object id +		LLViewerRegion::eCacheMissType mType;   //cache miss type -	BOOL mReleaseNotesRequested; +		typedef std::list<CacheMissItem> cache_miss_list_t; +	}; +	CacheMissItem::cache_miss_list_t   mCacheMissList; +	caps_received_signal_t mCapabilitiesReceivedSignal;		  	LLSD mSimulatorFeatures;  }; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index ba9818946c..78775c7205 100755 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -78,6 +78,8 @@ LLGLSLShader	gGlowCombineProgram;  LLGLSLShader	gSplatTextureRectProgram;  LLGLSLShader	gGlowCombineFXAAProgram;  LLGLSLShader	gTwoTextureAddProgram; +LLGLSLShader	gTwoTextureCompareProgram; +LLGLSLShader	gOneTextureFilterProgram;  LLGLSLShader	gOneTextureNoColorProgram;  LLGLSLShader	gDebugProgram;  LLGLSLShader	gClipProgram; @@ -672,6 +674,8 @@ void LLViewerShaderMgr::unloadShaders()  	gSplatTextureRectProgram.unload();  	gGlowCombineFXAAProgram.unload();  	gTwoTextureAddProgram.unload(); +	gTwoTextureCompareProgram.unload(); +	gOneTextureFilterProgram.unload();  	gOneTextureNoColorProgram.unload();  	gSolidColorProgram.unload(); @@ -2709,6 +2713,38 @@ BOOL LLViewerShaderMgr::loadShadersInterface()  	if (success)  	{ +		gTwoTextureCompareProgram.mName = "Two Texture Compare Shader"; +		gTwoTextureCompareProgram.mShaderFiles.clear(); +		gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB)); +		gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gTwoTextureCompareProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gTwoTextureCompareProgram.createShader(NULL, NULL); +		if (success) +		{ +			gTwoTextureCompareProgram.bind(); +			gTwoTextureCompareProgram.uniform1i("tex0", 0); +			gTwoTextureCompareProgram.uniform1i("tex1", 1); +			gTwoTextureCompareProgram.uniform1i("dither_tex", 2); +		} +	} + +	if (success) +	{ +		gOneTextureFilterProgram.mName = "One Texture Filter Shader"; +		gOneTextureFilterProgram.mShaderFiles.clear(); +		gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB)); +		gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gOneTextureFilterProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE]; +		success = gOneTextureFilterProgram.createShader(NULL, NULL); +		if (success) +		{ +			gOneTextureFilterProgram.bind(); +			gOneTextureFilterProgram.uniform1i("tex0", 0); +		} +	} + +	if (success) +	{  		gOneTextureNoColorProgram.mName = "One Texture No Color Shader";  		gOneTextureNoColorProgram.mShaderFiles.clear();  		gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB)); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e3d28f2f5c..24f9111d3d 100755 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -232,6 +232,10 @@ extern LLGLSLShader			gClipProgram;  //output tex0[tc0] + tex1[tc1]  extern LLGLSLShader			gTwoTextureAddProgram; +//output tex0[tc0] - tex1[tc1] +extern LLGLSLShader			gTwoTextureCompareProgram; +//discard some fragments based on user-set color tolerance +extern LLGLSLShader			gOneTextureFilterProgram;  extern LLGLSLShader			gOneTextureNoColorProgram; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 35bba4184e..be477f7f9a 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -61,363 +61,242 @@  #include "llviewernetwork.h"  #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived - -class StatAttributes +namespace LLStatViewer  { -public: -	StatAttributes(const char* name, -				   const BOOL enabled, -				   const BOOL is_timer) -		: mName(name), -		  mEnabled(enabled), -		  mIsTimer(is_timer) -	{ -	} + +LLTrace::CountStatHandle<>	FPS("framesrendered"), +							PACKETS_IN("packetsinstat"), +							PACKETS_LOST("packetsloststat"), +							PACKETS_OUT("packetsoutstat"), +							TEXTURE_PACKETS("texturepacketsstat"), +							TRIANGLES_DRAWN("trianglesdrawnstat"), +							CHAT_COUNT("chatcount", "Chat messages sent"), +							IM_COUNT("imcount", "IMs sent"), +							OBJECT_CREATE("objectcreate"), +							OBJECT_REZ("objectrez", "Object rez count"), +							LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"), +							LSL_SAVES("lslsaves", "Number of times user has saved a script"), +							ANIMATION_UPLOADS("animationuploads", "Animations uploaded"), +							FLY("fly", "Fly count"), +							TELEPORT("teleport", "Teleport count"), +							DELETE_OBJECT("deleteobject", "Objects deleted"), +							SNAPSHOT("snapshot", "Snapshots taken"), +							UPLOAD_SOUND("uploadsound", "Sounds uploaded"), +							UPLOAD_TEXTURE("uploadtexture", "Textures uploaded"), +							EDIT_TEXTURE("edittexture", "Changes to textures on objects"), +							KILLED("killed", "Number of times killed"), +							FRAMETIME_DOUBLED("frametimedoubled", "Ratio of frames 2x longer than previous"), +							TEX_BAKES("texbakes"), +							TEX_REBAKES("texrebakes"), +							NUM_NEW_OBJECTS("numnewobjectsstat"); +LLTrace::CountStatHandle<LLTrace::Kibibits>	KBIT("kbitstat"), +											LAYERS_KBIT("layerskbitstat"), +											OBJECT_KBIT("objectkbitstat"), +											ASSET_KBIT("assetkbitstat"), +											TEXTURE_KBIT("texturekbitstat"), +											ACTUAL_IN_KBIT("actualinkbitstat"), +											ACTUAL_OUT_KBIT("actualoutkbitstat"); + +LLTrace::CountStatHandle<LLTrace::Seconds>	SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), +											SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"), +											LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%"); + +SimMeasurement<>			SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DILATION), +							SIM_FPS("simfps", "", LL_SIM_STAT_FPS), +							SIM_PHYSICS_FPS("simphysicsfps", "", LL_SIM_STAT_PHYSFPS), +							SIM_AGENT_UPS("simagentups", "", LL_SIM_STAT_AGENTUPS), +							SIM_SCRIPT_EPS("simscripteps", "", LL_SIM_STAT_SCRIPT_EPS), +							SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps", "", LL_SIM_STAT_SKIPPEDAISILSTEPS_PS), +							SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters", "", LL_SIM_STAT_PCTSTEPPEDCHARACTERS), +							SIM_MAIN_AGENTS("simmainagents", "", LL_SIM_STAT_NUMAGENTMAIN), +							SIM_CHILD_AGENTS("simchildagents", "", LL_SIM_STAT_NUMAGENTCHILD), +							SIM_OBJECTS("simobjects", "", LL_SIM_STAT_NUMTASKS), +							SIM_ACTIVE_OBJECTS("simactiveobjects", "", LL_SIM_STAT_NUMTASKSACTIVE), +							SIM_ACTIVE_SCRIPTS("simactivescripts", "", LL_SIM_STAT_NUMSCRIPTSACTIVE), +							SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun", "", LL_SIM_STAT_PCTSCRIPTSRUN), +							SIM_IN_PACKETS_PER_SEC("siminpps", "", LL_SIM_STAT_INPPS), +							SIM_OUT_PACKETS_PER_SEC("simoutpps", "", LL_SIM_STAT_OUTPPS), +							SIM_PENDING_DOWNLOADS("simpendingdownloads", "", LL_SIM_STAT_PENDING_DOWNLOADS), +							SIM_PENDING_UPLOADS("simpendinguploads", "", LL_SIM_STAT_PENDING_UPLOADS), +							SIM_PENDING_LOCAL_UPLOADS("simpendinglocaluploads", "", LL_SIM_STAT_PENDING_LOCAL_UPLOADS), +							SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks", "", LL_SIM_STAT_PHYSICS_PINNED_TASKS), +							SIM_PHYSICS_LOD_TASKS("physicslodtasks", "", LL_SIM_STAT_PHYSICS_LOD_TASKS); + +LLTrace::SampleStatHandle<>	FPS_SAMPLE("fpssample"), +							NUM_IMAGES("numimagesstat"), +							NUM_RAW_IMAGES("numrawimagesstat"), +							NUM_OBJECTS("numobjectsstat"), +							NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), +							NUM_SIZE_CULLED("numsizeculledstat"), +							NUM_VIS_CULLED("numvisculledstat"), +							ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), +							LIGHTING_DETAIL("lightingdetail", "Lighting Detail"), +							VISIBLE_AVATARS("visibleavatars", "Visible Avatars"), +							SHADER_OBJECTS("shaderobjects", "Object Shaders"), +							DRAW_DISTANCE("drawdistance", "Draw Distance"), +							PENDING_VFS_OPERATIONS("vfspendingoperations"), +							PACKETS_LOST_PERCENT("packetslostpercentstat"), +							WINDOW_WIDTH("windowwidth", "Window width"), +							WINDOW_HEIGHT("windowheight", "Window height"); -	std::string mName; -	BOOL mEnabled; -	BOOL mIsTimer; -}; +static LLTrace::SampleStatHandle<S64> CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"); -const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] = -{ -	// ST_VERSION -	StatAttributes("Version", TRUE, FALSE), -	// ST_AVATAR_EDIT_SECONDS -	StatAttributes("Seconds in Edit Appearence", FALSE, TRUE), -	// ST_TOOLBOX_SECONDS -	StatAttributes("Seconds using Toolbox", FALSE, TRUE), -	// ST_CHAT_COUNT -	StatAttributes("Chat messages sent", FALSE, FALSE), -	// ST_IM_COUNT -	StatAttributes("IMs sent", FALSE, FALSE), -	// ST_FULLSCREEN_BOOL -	StatAttributes("Fullscreen mode", FALSE, FALSE), -	// ST_RELEASE_COUNT -	StatAttributes("Object release count", FALSE, FALSE), -	// ST_CREATE_COUNT -	StatAttributes("Object create count", FALSE, FALSE), -	// ST_REZ_COUNT -	StatAttributes("Object rez count", FALSE, FALSE), -	// ST_FPS_10_SECONDS -	StatAttributes("Seconds below 10 FPS", FALSE, TRUE), -	// ST_FPS_2_SECONDS -	StatAttributes("Seconds below 2 FPS", FALSE, TRUE), -	// ST_MOUSELOOK_SECONDS -	StatAttributes("Seconds in Mouselook", FALSE, TRUE), -	// ST_FLY_COUNT -	StatAttributes("Fly count", FALSE, FALSE), -	// ST_TELEPORT_COUNT -	StatAttributes("Teleport count", FALSE, FALSE), -	// ST_OBJECT_DELETE_COUNT -	StatAttributes("Objects deleted", FALSE, FALSE), -	// ST_SNAPSHOT_COUNT -	StatAttributes("Snapshots taken", FALSE, FALSE), -	// ST_UPLOAD_SOUND_COUNT -	StatAttributes("Sounds uploaded", FALSE, FALSE), -	// ST_UPLOAD_TEXTURE_COUNT -	StatAttributes("Textures uploaded", FALSE, FALSE), -	// ST_EDIT_TEXTURE_COUNT -	StatAttributes("Changes to textures on objects", FALSE, FALSE), -	// ST_KILLED_COUNT -	StatAttributes("Number of times killed", FALSE, FALSE), -	// ST_FRAMETIME_JITTER -	StatAttributes("Average delta between sucessive frame times", FALSE, FALSE), -	// ST_FRAMETIME_SLEW -	StatAttributes("Average delta between frame time and mean", FALSE, FALSE), -	// ST_INVENTORY_TOO_LONG -	StatAttributes("Inventory took too long to load", FALSE, FALSE), -	// ST_WEARABLES_TOO_LONG -	StatAttributes("Wearables took too long to load", FALSE, FALSE), -	// ST_LOGIN_SECONDS -	StatAttributes("Time between LoginRequest and LoginReply", FALSE, FALSE), -	// ST_LOGIN_TIMEOUT_COUNT -	StatAttributes("Number of login attempts that timed out", FALSE, FALSE), -	// ST_HAS_BAD_TIMER -	StatAttributes("Known bad timer if != 0.0", FALSE, FALSE), -	// ST_DOWNLOAD_FAILED -	StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE, FALSE), -	// ST_LSL_SAVE_COUNT -	StatAttributes("Number of times user has saved a script", FALSE, FALSE), -	// ST_UPLOAD_ANIM_COUNT -	StatAttributes("Animations uploaded", FALSE, FALSE), -	// ST_FPS_8_SECONDS -	StatAttributes("Seconds below 8 FPS", FALSE, TRUE), -	// ST_SIM_FPS_20_SECONDS -	StatAttributes("Seconds with sim FPS below 20", FALSE, TRUE), -	// ST_PHYS_FPS_20_SECONDS -	StatAttributes("Seconds with physics FPS below 20", FALSE, TRUE), -	// ST_LOSS_05_SECONDS -	StatAttributes("Seconds with packet loss > 5%", FALSE, TRUE), -	// ST_FPS_DROP_50_RATIO -	StatAttributes("Ratio of frames 2x longer than previous", FALSE, FALSE), -	// ST_ENABLE_VBO -	StatAttributes("Vertex Buffers Enabled", TRUE, FALSE), -	// ST_DELTA_BANDWIDTH -	StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE, FALSE), -	// ST_MAX_BANDWIDTH -	StatAttributes("Max bandwidth setting", FALSE, FALSE), -	// ST_LIGHTING_DETAIL -	StatAttributes("Lighting Detail", FALSE, FALSE), -	// ST_VISIBLE_AVATARS -	StatAttributes("Visible Avatars", FALSE, FALSE), -	// ST_SHADER_OJECTS -	StatAttributes("Object Shaders", FALSE, FALSE), -	// ST_SHADER_ENVIRONMENT -	StatAttributes("Environment Shaders", FALSE, FALSE), -	// ST_VISIBLE_DRAW_DIST -	StatAttributes("Draw Distance", FALSE, FALSE), -	// ST_VISIBLE_CHAT_BUBBLES -	StatAttributes("Chat Bubbles Enabled", FALSE, FALSE), -	// ST_SHADER_AVATAR -	StatAttributes("Avatar Shaders", FALSE, FALSE), -	// ST_FRAME_SECS -	StatAttributes("FRAME_SECS", FALSE, FALSE), -	// ST_UPDATE_SECS -	StatAttributes("UPDATE_SECS", FALSE, FALSE), -	// ST_NETWORK_SECS -	StatAttributes("NETWORK_SECS", FALSE, FALSE), -	// ST_IMAGE_SECS -	StatAttributes("IMAGE_SECS", FALSE, FALSE), -	// ST_REBUILD_SECS -	StatAttributes("REBUILD_SECS", FALSE, FALSE), -	// ST_RENDER_SECS -	StatAttributes("RENDER_SECS", FALSE, FALSE), -	// ST_CROSSING_AVG -	StatAttributes("CROSSING_AVG", FALSE, FALSE), -	// ST_CROSSING_MAX -	StatAttributes("CROSSING_MAX", FALSE, FALSE), -	// ST_LIBXUL_WIDGET_USED -	StatAttributes("LibXUL Widget used", FALSE, FALSE), // Unused -	// ST_WINDOW_WIDTH -	StatAttributes("Window width", FALSE, FALSE), -	// ST_WINDOW_HEIGHT -	StatAttributes("Window height", FALSE, FALSE), -	// ST_TEX_BAKES -	StatAttributes("Texture Bakes", FALSE, FALSE), -	// ST_TEX_REBAKES -	StatAttributes("Texture Rebakes", FALSE, FALSE) +LLTrace::SampleStatHandle<LLTrace::Bytes>	GL_TEX_MEM("gltexmemstat"), +											GL_BOUND_MEM("glboundmemstat"), +											RAW_MEM("rawmemstat"), +											FORMATTED_MEM("formattedmemstat"), +											DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), +											MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"); -}; +	 +SimMeasurement<LLTrace::Milliseconds>	SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS), +										SIM_NET_TIME("simnetmsec", "", LL_SIM_STAT_NETMS), +										SIM_OTHER_TIME("simsimothermsec", "", LL_SIM_STAT_SIMOTHERMS), +										SIM_PHYSICS_TIME("simsimphysicsmsec", "", LL_SIM_STAT_SIMPHYSICSMS), +										SIM_PHYSICS_STEP_TIME("simsimphysicsstepmsec", "", LL_SIM_STAT_SIMPHYSICSSTEPMS), +										SIM_PHYSICS_SHAPE_UPDATE_TIME("simsimphysicsshapeupdatemsec", "", LL_SIM_STAT_SIMPHYSICSSHAPEMS), +										SIM_PHYSICS_OTHER_TIME("simsimphysicsothermsec", "", LL_SIM_STAT_SIMPHYSICSOTHERMS), +										SIM_AI_TIME("simsimaistepmsec", "", LL_SIM_STAT_SIMAISTEPTIMEMS), +										SIM_AGENTS_TIME("simagentmsec", "", LL_SIM_STAT_AGENTMS), +										SIM_IMAGES_TIME("simimagesmsec", "", LL_SIM_STAT_IMAGESMS), +										SIM_SCRIPTS_TIME("simscriptmsec", "", LL_SIM_STAT_SCRIPTMS), +										SIM_SPARE_TIME("simsparemsec", "", LL_SIM_STAT_SIMSPARETIME), +										SIM_SLEEP_TIME("simsleepmsec", "", LL_SIM_STAT_SIMSLEEPTIME), +										SIM_PUMP_IO_TIME("simpumpiomsec", "", LL_SIM_STAT_IOPUMPTIME); +	 +SimMeasurement<LLTrace::Bytes>	SIM_UNACKED_BYTES("simtotalunackedbytes", "", LL_SIM_STAT_TOTAL_UNACKED_BYTES), +								SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL_SIM_STAT_SIMPHYSICSMEMORY); -LLViewerStats::LLViewerStats() : -	mKBitStat("kbitstat"), -	mLayersKBitStat("layerskbitstat"), -	mObjectKBitStat("objectkbitstat"), -	mAssetKBitStat("assetkbitstat"), -	mTextureKBitStat("texturekbitstat"), -	mVFSPendingOperations("vfspendingoperations"), -	mObjectsDrawnStat("objectsdrawnstat"), -	mObjectsCulledStat("objectsculledstat"), -	mObjectsTestedStat("objectstestedstat"), -	mObjectsComparedStat("objectscomparedstat"), -	mObjectsOccludedStat("objectsoccludedstat"), -	mFPSStat("fpsstat"), -	mPacketsInStat("packetsinstat"), -	mPacketsLostStat("packetsloststat"), -	mPacketsOutStat("packetsoutstat"), -	mPacketsLostPercentStat("packetslostpercentstat", 64), -	mTexturePacketsStat("texturepacketsstat"), -	mActualInKBitStat("actualinkbitstat"), -	mActualOutKBitStat("actualoutkbitstat"), -	mTrianglesDrawnStat("trianglesdrawnstat"), -	mSimTimeDilation("simtimedilation"), -	mSimFPS("simfps"), -	mSimPhysicsFPS("simphysicsfps"), -	mSimAgentUPS("simagentups"), -	mSimScriptEPS("simscripteps"), -	mSimFrameMsec("simframemsec"), -	mSimNetMsec("simnetmsec"), -	mSimSimOtherMsec("simsimothermsec"), -	mSimSimPhysicsMsec("simsimphysicsmsec"), -	mSimSimPhysicsStepMsec("simsimphysicsstepmsec"), -	mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"), -	mSimSimPhysicsOtherMsec("simsimphysicsothermsec"), -	mSimSimAIStepMsec("simsimaistepmsec"), -	mSimSimSkippedSilhouetteSteps("simsimskippedsilhouettesteps"), -	mSimSimPctSteppedCharacters("simsimpctsteppedcharacters"), -	mSimAgentMsec("simagentmsec"), -	mSimImagesMsec("simimagesmsec"), -	mSimScriptMsec("simscriptmsec"), -	mSimSpareMsec("simsparemsec"), -	mSimSleepMsec("simsleepmsec"), -	mSimPumpIOMsec("simpumpiomsec"), -	mSimMainAgents("simmainagents"), -	mSimChildAgents("simchildagents"), -	mSimObjects("simobjects"), -	mSimActiveObjects("simactiveobjects"), -	mSimActiveScripts("simactivescripts"), -	mSimPctScriptsRun("simpctscriptsrun"), -	mSimInPPS("siminpps"), -	mSimOutPPS("simoutpps"), -	mSimPendingDownloads("simpendingdownloads"), -	mSimPendingUploads("simpendinguploads"), -	mSimPendingLocalUploads("simpendinglocaluploads"), -	mSimTotalUnackedBytes("simtotalunackedbytes"), -	mPhysicsPinnedTasks("physicspinnedtasks"), -	mPhysicsLODTasks("physicslodtasks"), -	mPhysicsMemoryAllocated("physicsmemoryallocated"), -	mSimPingStat("simpingstat"), -	mNumImagesStat("numimagesstat", 32, TRUE), -	mNumRawImagesStat("numrawimagesstat", 32, TRUE), -	mGLTexMemStat("gltexmemstat", 32, TRUE), -	mGLBoundMemStat("glboundmemstat", 32, TRUE), -	mRawMemStat("rawmemstat", 32, TRUE), -	mFormattedMemStat("formattedmemstat", 32, TRUE), -	mNumObjectsStat("numobjectsstat"), -	mNumActiveObjectsStat("numactiveobjectsstat"), -	mNumNewObjectsStat("numnewobjectsstat"), -	mNumSizeCulledStat("numsizeculledstat"), -	mNumVisCulledStat("numvisculledstat"), -	mLastTimeDiff(0.0) -{ -	for (S32 i = 0; i < ST_COUNT; i++) -	{ -		mStats[i] = 0.0; -	} +LLTrace::SampleStatHandle<LLTrace::Milliseconds>	FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), +													FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), +													SIM_PING("simpingstat"); + +LLTrace::EventStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); + +LLTrace::EventStatHandle<>	LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"); -	if (LLTimer::knownBadTimer()) -	{ -		mStats[ST_HAS_BAD_TIMER] = 1.0; -	}	 +LLTrace::EventStatHandle<LLTrace::Milliseconds>	REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), +												FRAME_STACKTIME("framestacktime", "FRAME_SECS"), +												UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"), +												NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), +												IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"), +												REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"), +												RENDER_STACKTIME("renderstacktime", "RENDER_SECS"); -	mAgentPositionSnaps.reset(); -} +LLTrace::EventStatHandle<LLTrace::Seconds>	AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearance"), +											TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), +											MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), +											FPS_10_TIME("fps10time", "Seconds below 10 FPS"), +											FPS_8_TIME("fps8time", "Seconds below 8 FPS"), +											FPS_2_TIME("fps2time", "Seconds below 2 FPS"); -LLViewerStats::~LLViewerStats() -{ -} -void LLViewerStats::resetStats() -{ -	LLViewerStats& stats = LLViewerStats::instance(); -	stats.mKBitStat.reset(); -	stats.mLayersKBitStat.reset(); -	stats.mObjectKBitStat.reset(); -	stats.mTextureKBitStat.reset(); -	stats.mVFSPendingOperations.reset(); -	stats.mAssetKBitStat.reset(); -	stats.mPacketsInStat.reset(); -	stats.mPacketsLostStat.reset(); -	stats.mPacketsOutStat.reset(); -	stats.mFPSStat.reset(); -	stats.mTexturePacketsStat.reset(); -	stats.mAgentPositionSnaps.reset();  } - -F64 LLViewerStats::getStat(EStatType type) const +LLViewerStats::LLViewerStats()  +:	mLastTimeDiff(0.0)  { -	return mStats[type]; +	mRecording.start(); +	LLTrace::get_frame_recording().start();  } -F64 LLViewerStats::setStat(EStatType type, F64 value) +LLViewerStats::~LLViewerStats()  { -	mStats[type] = value; -	return mStats[type];  } -F64 LLViewerStats::incStat(EStatType type, F64 value) +void LLViewerStats::resetStats()  { -	mStats[type] += value; -	return mStats[type]; +	LLViewerStats::instance().mRecording.reset();  }  void LLViewerStats::updateFrameStats(const F64 time_diff)  { -	if (mPacketsLostPercentStat.getCurrent() > 5.0) +	LLTrace::Seconds time_diff_seconds(time_diff); +	if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > 5.0)  	{ -		incStat(ST_LOSS_05_SECONDS, time_diff); +		add(LLStatViewer::LOSS_5_PERCENT_TIME, time_diff_seconds);  	} -	if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f) +	F32 sim_fps = getRecording().getLastValue(LLStatViewer::SIM_FPS); +	if (0.f < sim_fps && sim_fps < 20.f)  	{ -		incStat(ST_SIM_FPS_20_SECONDS, time_diff); +		add(LLStatViewer::SIM_20_FPS_TIME, time_diff_seconds);  	} -	if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f) +	F32 sim_physics_fps = getRecording().getLastValue(LLStatViewer::SIM_PHYSICS_FPS); + +	if (0.f < sim_physics_fps && sim_physics_fps < 20.f)  	{ -		incStat(ST_PHYS_FPS_20_SECONDS, time_diff); +		add(LLStatViewer::SIM_PHYSICS_20_FPS_TIME, time_diff_seconds);  	}  	if (time_diff >= 0.5)  	{ -		incStat(ST_FPS_2_SECONDS, time_diff); +		record(LLStatViewer::FPS_2_TIME, time_diff_seconds);  	}  	if (time_diff >= 0.125)  	{ -		incStat(ST_FPS_8_SECONDS, time_diff); +		record(LLStatViewer::FPS_8_TIME, time_diff_seconds);  	}  	if (time_diff >= 0.1)  	{ -		incStat(ST_FPS_10_SECONDS, time_diff); +		record(LLStatViewer::FPS_10_TIME, time_diff_seconds);  	}  	if (gFrameCount && mLastTimeDiff > 0.0)  	{  		// new "stutter" meter -		setStat(ST_FPS_DROP_50_RATIO, -				(getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) +  -				 (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount); -			 +		add(LLStatViewer::FRAMETIME_DOUBLED, time_diff >= 2.0 * mLastTimeDiff ? 1 : 0);  		// old stats that were never really used -		setStat(ST_FRAMETIME_JITTER, -				(getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) +  -				 fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount); +		sample(LLStatViewer::FRAMETIME_JITTER, LLTrace::Milliseconds(mLastTimeDiff - time_diff));  		F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; -		setStat(ST_FRAMETIME_SLEW, -				(getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) +  -				 fabs(average_frametime - time_diff) / average_frametime) / gFrameCount); +		sample(LLStatViewer::FRAMETIME_SLEW, LLTrace::Milliseconds(average_frametime - time_diff));  		F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();  		F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth; -		setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f); - -		setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f); -		 +		sample(LLStatViewer::DELTA_BANDWIDTH, LLTrace::Bits(delta_bandwidth)); +		sample(LLStatViewer::MAX_BANDWIDTH, LLTrace::Bits(max_bandwidth));  	}  	mLastTimeDiff = time_diff; -  } -void LLViewerStats::addToMessage(LLSD &body) const +void LLViewerStats::addToMessage(LLSD &body)  {  	LLSD &misc = body["misc"]; -	for (S32 i = 0; i < ST_COUNT; i++) -	{ -		if (STAT_INFO[i].mEnabled) -		{ -			// TODO: send timer value so dataserver can normalize -			misc[STAT_INFO[i].mName] = mStats[i]; -			llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i] -					<< llendl; -		} -	} +	misc["Version"] = TRUE; +	//TODO RN: get last value, not mean +	misc["Vertex Buffers Enabled"] = getRecording().getMean(LLStatViewer::ENABLE_VBO); -	body["AgentPositionSnaps"] = mAgentPositionSnaps.getData(); -	llinfos << "STAT: AgentPositionSnaps: Mean = " << mAgentPositionSnaps.getMean() << "; StdDev = " << mAgentPositionSnaps.getStdDev()  -			<< "; Count = " << mAgentPositionSnaps.getCount() << llendl; +	body["AgentPositionSnaps"] = getRecording().getSum(LLStatViewer::AGENT_POSITION_SNAP).value(); //mAgentPositionSnaps.asLLSD(); +	llinfos << "STAT: AgentPositionSnaps: Mean = " << getRecording().getMean(LLStatViewer::AGENT_POSITION_SNAP).value() << "; StdDev = " << getRecording().getStandardDeviation(LLStatViewer::AGENT_POSITION_SNAP).value()  +			<< "; Count = " << getRecording().getSampleCount(LLStatViewer::AGENT_POSITION_SNAP) << llendl;  }  // *NOTE:Mani The following methods used to exist in viewer.cpp  // Moving them here, but not merging them into LLViewerStats yet. -U32		gTotalLandIn = 0, gTotalLandOut = 0; -U32		gTotalWaterIn = 0, gTotalWaterOut = 0; - -F32		gAveLandCompression = 0.f, gAveWaterCompression = 0.f; -F32		gBestLandCompression = 1.f, gBestWaterCompression = 1.f; -F32		gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f; - - - -U32		gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0; -U32		gObjectBits = 0; +U32		gTotalLandIn = 0,  +		gTotalLandOut = 0, +		gTotalWaterIn = 0,  +		gTotalWaterOut = 0; + +F32		gAveLandCompression = 0.f,  +		gAveWaterCompression = 0.f, +		gBestLandCompression = 1.f, +		gBestWaterCompression = 1.f, +		gWorstLandCompression = 0.f,  +		gWorstWaterCompression = 0.f; + +LLUnit<LLUnits::Bytes, U32>		gTotalWorldData = 0,  +						gTotalObjectData = 0,  +						gTotalTextureData = 0; +U32						gSimPingCount = 0; +LLUnit<LLUnits::Bits, U32>		gObjectData = 0;  F32		gAvgSimPing = 0.f; -U32     gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0}; +LLUnit<LLUnits::Bytes, U32>		gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0};  extern U32  gVisCompared;  extern U32  gVisTested; @@ -426,59 +305,68 @@ LLFrameTimer gTextureTimer;  void update_statistics()  { -	gTotalWorldBytes += gVLManager.getTotalBytes(); -	gTotalObjectBytes += gObjectBits / 8; - -	LLViewerStats& stats = LLViewerStats::instance(); +	gTotalWorldData += gVLManager.getTotalBytes(); +	gTotalObjectData += gObjectData;  	// make sure we have a valid time delta for this frame  	if (gFrameIntervalSeconds > 0.f)  	{  		if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)  		{ -			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds); +			record(LLStatViewer::MOUSELOOK_TIME, gFrameIntervalSeconds);  		}  		else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)  		{ -			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds); +			record(LLStatViewer::AVATAR_EDIT_TIME, gFrameIntervalSeconds);  		}  		else if (LLFloaterReg::instanceVisible("build"))  		{ -			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); +			record(LLStatViewer::TOOLBOX_TIME, gFrameIntervalSeconds);  		}  	} -	stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); -	stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); -	stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); -	stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); - -	stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); -	F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle"); -	F64 network_secs = gDebugView->mFastTimerView->getTime("Network"); -	stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); -	stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); -	stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); -	stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); -	stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); + +	LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); + +	sample(LLStatViewer::ENABLE_VBO,      (F64)gSavedSettings.getBOOL("RenderVBOEnable")); +	sample(LLStatViewer::LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); +	sample(LLStatViewer::DRAW_DISTANCE,   (F64)gSavedSettings.getF32("RenderFarClip")); +	sample(LLStatViewer::CHAT_BUBBLES,    gSavedSettings.getBOOL("UseChatBubbles")); + +	typedef LLInstanceTracker<LLTrace::TraceType<LLTrace::TimeBlockAccumulator>, std::string> trace_type_t; + +	LLUnit<LLUnits::Seconds, F64> idle_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Idle")); +	LLUnit<LLUnits::Seconds, F64> network_secs = last_frame_recording.getSum(*trace_type_t::getInstance("Network")); + +	record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Frame"))); +	record(LLStatViewer::UPDATE_STACKTIME, idle_secs - network_secs); +	record(LLStatViewer::NETWORK_STACKTIME, network_secs); +	record(LLStatViewer::IMAGE_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Update Images"))); +	record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Sort Draw State"))); +	record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*trace_type_t::getInstance("Render Geometry")));  	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());  	if (cdp)  	{ -		stats.mSimPingStat.addValue(cdp->getPingDelay()); +		sample(LLStatViewer::SIM_PING, LLTrace::Milliseconds(cdp->getPingDelay()));  		gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);  		gSimPingCount++;  	}  	else  	{ -		stats.mSimPingStat.addValue(10000); +		sample(LLStatViewer::SIM_PING, LLTrace::Seconds(10)); +	} + +	if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS)) +	{ +		sample(LLStatViewer::FPS_SAMPLE, LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS));  	} +	add(LLStatViewer::FPS, 1); -	stats.mFPSStat.addValue(1);  	F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); -	stats.mLayersKBitStat.addValue(layer_bits/1024.f); -	stats.mObjectKBitStat.addValue(gObjectBits/1024.f); -	stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); -	stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); +	add(LLStatViewer::LAYERS_KBIT, LLTrace::Bits(layer_bits)); +	add(LLStatViewer::OBJECT_KBIT, gObjectData); +	sample(LLStatViewer::PENDING_VFS_OPERATIONS, LLVFile::getVFSThread()->getPending()); +	add(LLStatViewer::ASSET_KBIT, LLTrace::Bits(gTransferManager.getTransferBitsIn(LLTCT_ASSET)));  	gTransferManager.resetTransferBitsIn(LLTCT_ASSET);  	if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) @@ -499,14 +387,14 @@ void update_statistics()  			visible_avatar_frames = 1.f;  			avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;  		} -		stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); +		sample(LLStatViewer::VISIBLE_AVATARS, (F64)avg_visible_avatars);  	}  	LLWorld::getInstance()->updateNetStats();  	LLWorld::getInstance()->requestCacheMisses();  	// Reset all of these values.  	gVLManager.resetBitCounts(); -	gObjectBits = 0; +	gObjectData = 0;  //	gDecodedBits = 0;  	// Only update texture stats periodically so that they are less noisy @@ -515,11 +403,7 @@ void update_statistics()  		static LLFrameTimer texture_stats_timer;  		if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq)  		{ -			stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); -			stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); -			gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; -			LLViewerTextureList::sTextureBits = 0; -			LLViewerTextureList::sTexturePackets = 0; +			gTotalTextureData = LLTrace::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT));  			texture_stats_timer.reset();  		}  	} @@ -668,9 +552,9 @@ void send_stats()  	LLSD &download = body["downloads"]; -	download["world_kbytes"] = gTotalWorldBytes / 1024.0; -	download["object_kbytes"] = gTotalObjectBytes / 1024.0; -	download["texture_kbytes"] = gTotalTextureBytes / 1024.0; +	download["world_kbytes"] = LLTrace::Kibibytes(gTotalWorldData).value(); +	download["object_kbytes"] = LLTrace::Kibibytes(gTotalObjectData).value(); +	download["texture_kbytes"] = LLTrace::Kibibytes(gTotalTextureData).value();  	download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0;  	LLSD &in = body["stats"]["net"]["in"]; @@ -775,7 +659,7 @@ void LLViewerStats::PhaseMap::clearPhases()  	mPhaseMap.clear();  } -LLSD LLViewerStats::PhaseMap::dumpPhases() +LLSD LLViewerStats::PhaseMap::asLLSD()  {  	LLSD result;  	for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter) diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 6b2461be41..bfba7bca9a 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -1,5 +1,5 @@  /**  - * @file llviewerstats.h + * @file llviewerim_peningtats.h   * @brief LLViewerStats class header file   *   * $LicenseInfo:firstyear=2002&license=viewerlgpl$ @@ -27,171 +27,187 @@  #ifndef LL_LLVIEWERSTATS_H  #define LL_LLVIEWERSTATS_H -#include "llstat.h" +#include "llstatenums.h"  #include "lltextureinfo.h" +#include "lltracerecording.h" +#include "lltrace.h" + +namespace LLStatViewer +{ + +struct SimMeasurementSampler : public LLInstanceTracker<SimMeasurementSampler, ESimStatID> +{ +	SimMeasurementSampler(ESimStatID id) +	:	LLInstanceTracker<SimMeasurementSampler, ESimStatID>(id) +	{} +	virtual ~SimMeasurementSampler() {} + +	virtual void sample(F64 value) = 0; +}; + +template<typename T = F64> +struct SimMeasurement : public LLTrace::SampleStatHandle<T>, public SimMeasurementSampler +{ +	SimMeasurement(const char* name, const char* description, ESimStatID stat_id) +	:	LLTrace::SampleStatHandle<T>(name, description), +		SimMeasurementSampler(stat_id)	 +	{} + +	using SimMeasurementSampler::getInstance; + +	/*virtual*/ void sample(F64 value) +	{ +		LLTrace::sample(*this, value); +	} +}; + +template<typename T, typename VALUE_T> +void sample(SimMeasurement<T>& measurement, VALUE_T value) +{ +	LLTrace::sample(measurement, value); +} + +extern LLTrace::CountStatHandle<>			FPS, +											PACKETS_IN, +											PACKETS_LOST, +											PACKETS_OUT, +											TEXTURE_PACKETS, +											TRIANGLES_DRAWN, +											CHAT_COUNT, +											IM_COUNT, +											OBJECT_CREATE, +											OBJECT_REZ, +											LOGIN_TIMEOUTS, +											LSL_SAVES, +											ANIMATION_UPLOADS, +											FLY, +											TELEPORT, +											DELETE_OBJECT, +											SNAPSHOT, +											UPLOAD_SOUND, +											UPLOAD_TEXTURE, +											EDIT_TEXTURE, +											KILLED, +											FRAMETIME_DOUBLED, +											TEX_BAKES, +											TEX_REBAKES, +											NUM_NEW_OBJECTS; + + +extern LLTrace::CountStatHandle<LLTrace::Kibibits>	KBIT, +											LAYERS_KBIT, +											OBJECT_KBIT, +											ASSET_KBIT, +											TEXTURE_KBIT, +											ACTUAL_IN_KBIT, +											ACTUAL_OUT_KBIT; + +extern LLTrace::CountStatHandle<LLTrace::Seconds>		SIM_20_FPS_TIME, +														SIM_PHYSICS_20_FPS_TIME, +														LOSS_5_PERCENT_TIME; + +extern SimMeasurement<>						SIM_TIME_DILATION, +											SIM_FPS, +											SIM_PHYSICS_FPS, +											SIM_AGENT_UPS, +											SIM_SCRIPT_EPS, +											SIM_SKIPPED_SILHOUETTE, +											SIM_SKIPPED_CHARACTERS_PERCENTAGE, +											SIM_MAIN_AGENTS, +											SIM_CHILD_AGENTS, +											SIM_OBJECTS, +											SIM_ACTIVE_OBJECTS, +											SIM_ACTIVE_SCRIPTS, +											SIM_PERCENTAGE_SCRIPTS_RUN, +											SIM_IN_PACKETS_PER_SEC, +											SIM_OUT_PACKETS_PER_SEC, +											SIM_PENDING_DOWNLOADS, +											SIM_PENDING_UPLOADS, +											SIM_PENDING_LOCAL_UPLOADS, +											SIM_PHYSICS_PINNED_TASKS, +											SIM_PHYSICS_LOD_TASKS; + +extern LLTrace::SampleStatHandle<>		FPS_SAMPLE, +										NUM_IMAGES, +										NUM_RAW_IMAGES, +										NUM_OBJECTS, +										NUM_ACTIVE_OBJECTS, +										NUM_SIZE_CULLED, +										NUM_VIS_CULLED, +										ENABLE_VBO, +										LIGHTING_DETAIL, +										VISIBLE_AVATARS, +										SHADER_OBJECTS, +										DRAW_DISTANCE, +										PENDING_VFS_OPERATIONS, +										PACKETS_LOST_PERCENT, +										WINDOW_WIDTH, +										WINDOW_HEIGHT; + +extern LLTrace::SampleStatHandle<LLTrace::Bytes>	DELTA_BANDWIDTH, +													MAX_BANDWIDTH, +													GL_TEX_MEM, +													GL_BOUND_MEM, +													RAW_MEM, +													FORMATTED_MEM; + +extern SimMeasurement<LLTrace::Milliseconds>	SIM_FRAME_TIME, +												SIM_NET_TIME, +												SIM_OTHER_TIME, +												SIM_PHYSICS_TIME, +												SIM_PHYSICS_STEP_TIME, +												SIM_PHYSICS_SHAPE_UPDATE_TIME, +												SIM_PHYSICS_OTHER_TIME, +												SIM_AI_TIME, +												SIM_AGENTS_TIME, +												SIM_IMAGES_TIME, +												SIM_SCRIPTS_TIME, +												SIM_SPARE_TIME, +												SIM_SLEEP_TIME, +												SIM_PUMP_IO_TIME; + +extern SimMeasurement<LLTrace::Bytes>			SIM_UNACKED_BYTES, +												SIM_PHYSICS_MEM; + + +extern LLTrace::SampleStatHandle<LLTrace::Milliseconds>	FRAMETIME_JITTER, +														FRAMETIME_SLEW, +														SIM_PING; + +extern LLTrace::EventStatHandle<LLTrace::Meters> AGENT_POSITION_SNAP; + +extern LLTrace::EventStatHandle<>	LOADING_WEARABLES_LONG_DELAY; + +extern LLTrace::EventStatHandle<LLTrace::Milliseconds>	REGION_CROSSING_TIME, +														FRAME_STACKTIME, +														UPDATE_STACKTIME, +														NETWORK_STACKTIME, +														IMAGE_STACKTIME, +														REBUILD_STACKTIME, +														RENDER_STACKTIME; + +extern LLTrace::EventStatHandle<LLTrace::Seconds>	AVATAR_EDIT_TIME, +													TOOLBOX_TIME, +													MOUSELOOK_TIME, +													FPS_10_TIME, +													FPS_8_TIME, +													FPS_2_TIME; + +}  class LLViewerStats : public LLSingleton<LLViewerStats>  {  public: -	LLStat	mKBitStat, -			mLayersKBitStat, -			mObjectKBitStat, -			mAssetKBitStat, -			mTextureKBitStat, -			mVFSPendingOperations, -			mObjectsDrawnStat, -			mObjectsCulledStat, -			mObjectsTestedStat, -			mObjectsComparedStat, -			mObjectsOccludedStat, -			mFPSStat, -			mPacketsInStat, -			mPacketsLostStat, -			mPacketsOutStat, -			mPacketsLostPercentStat, -			mTexturePacketsStat, -			mActualInKBitStat,	// From the packet ring (when faking a bad connection) -			mActualOutKBitStat,	// From the packet ring (when faking a bad connection) -			mTrianglesDrawnStat; - -	// Simulator stats -	LLStat	mSimTimeDilation, - -			mSimFPS, -			mSimPhysicsFPS, -			mSimAgentUPS, -			mSimScriptEPS, - -			mSimFrameMsec, -			mSimNetMsec, -			mSimSimOtherMsec, -			mSimSimPhysicsMsec, - -			mSimSimPhysicsStepMsec, -			mSimSimPhysicsShapeUpdateMsec, -			mSimSimPhysicsOtherMsec, -			mSimSimAIStepMsec, -			mSimSimSkippedSilhouetteSteps, -			mSimSimPctSteppedCharacters, - -			mSimAgentMsec, -			mSimImagesMsec, -			mSimScriptMsec, -			mSimSpareMsec, -			mSimSleepMsec, -			mSimPumpIOMsec, - -			mSimMainAgents, -			mSimChildAgents, -			mSimObjects, -			mSimActiveObjects, -			mSimActiveScripts, -			mSimPctScriptsRun, - -			mSimInPPS, -			mSimOutPPS, -			mSimPendingDownloads, -			mSimPendingUploads, -			mSimPendingLocalUploads, -			mSimTotalUnackedBytes, - -			mPhysicsPinnedTasks, -			mPhysicsLODTasks, -			mPhysicsMemoryAllocated, - -			mSimPingStat, - -			mNumImagesStat, -			mNumRawImagesStat, -			mGLTexMemStat, -			mGLBoundMemStat, -			mRawMemStat, -			mFormattedMemStat, - -			mNumObjectsStat, -			mNumActiveObjectsStat, -			mNumNewObjectsStat, -			mNumSizeCulledStat, -			mNumVisCulledStat; -  	void resetStats(); +  public: -	// If you change this, please also add a corresponding text label in llviewerstats.cpp -	enum EStatType -	{ -		ST_VERSION = 0, -		ST_AVATAR_EDIT_SECONDS = 1, -		ST_TOOLBOX_SECONDS = 2, -		ST_CHAT_COUNT = 3, -		ST_IM_COUNT = 4, -		ST_FULLSCREEN_BOOL = 5, -		ST_RELEASE_COUNT= 6, -		ST_CREATE_COUNT = 7, -		ST_REZ_COUNT = 8, -		ST_FPS_10_SECONDS = 9, -		ST_FPS_2_SECONDS = 10, -		ST_MOUSELOOK_SECONDS = 11, -		ST_FLY_COUNT = 12, -		ST_TELEPORT_COUNT = 13, -		ST_OBJECT_DELETE_COUNT = 14, -		ST_SNAPSHOT_COUNT = 15, -		ST_UPLOAD_SOUND_COUNT = 16, -		ST_UPLOAD_TEXTURE_COUNT = 17, -		ST_EDIT_TEXTURE_COUNT = 18, -		ST_KILLED_COUNT = 19, -		ST_FRAMETIME_JITTER = 20, -		ST_FRAMETIME_SLEW = 21, -		ST_INVENTORY_TOO_LONG = 22, -		ST_WEARABLES_TOO_LONG = 23, -		ST_LOGIN_SECONDS = 24, -		ST_LOGIN_TIMEOUT_COUNT = 25, -		ST_HAS_BAD_TIMER = 26, -		ST_DOWNLOAD_FAILED = 27, -		ST_LSL_SAVE_COUNT = 28, -		ST_UPLOAD_ANIM_COUNT = 29, -		ST_FPS_8_SECONDS = 30, -		ST_SIM_FPS_20_SECONDS = 31, -		ST_PHYS_FPS_20_SECONDS = 32, -		ST_LOSS_05_SECONDS = 33, -		ST_FPS_DROP_50_RATIO = 34, -		ST_ENABLE_VBO = 35, -		ST_DELTA_BANDWIDTH = 36, -		ST_MAX_BANDWIDTH = 37, -		ST_LIGHTING_DETAIL = 38, -		ST_VISIBLE_AVATARS = 39, -		ST_SHADER_OBJECTS = 40, -		ST_SHADER_ENVIRONMENT = 41, -		ST_DRAW_DIST = 42, -		ST_CHAT_BUBBLES = 43, -		ST_SHADER_AVATAR = 44, -		ST_FRAME_SECS = 45, -		ST_UPDATE_SECS = 46, -		ST_NETWORK_SECS = 47, -		ST_IMAGE_SECS = 48, -		ST_REBUILD_SECS = 49, -		ST_RENDER_SECS = 50, -		ST_CROSSING_AVG = 51, -		ST_CROSSING_MAX = 52, -		ST_LIBXUL_WIDGET_USED = 53, // Unused -		ST_WINDOW_WIDTH = 54, -		ST_WINDOW_HEIGHT = 55, -		ST_TEX_BAKES = 56, -		ST_TEX_REBAKES = 57, -		 -		ST_COUNT = 58 -	};  	LLViewerStats();  	~LLViewerStats(); -	// all return latest value of given stat -	F64 getStat(EStatType type) const; -	F64 setStat(EStatType type, F64 value);		// set the stat to value -	F64 incStat(EStatType type, F64 value = 1.f);	// add value to the stat -  	void updateFrameStats(const F64 time_diff); -	void addToMessage(LLSD &body) const; +	void addToMessage(LLSD &body);  	struct  StatsAccumulator  	{ @@ -263,7 +279,7 @@ public:  			mCountOfNextUpdatesToIgnore = 0;  		} -		inline LLSD getData() const +		inline LLSD asLLSD() const  		{  			LLSD data;  			data["mean"] = getMean(); @@ -275,8 +291,6 @@ public:  		}  	}; -	StatsAccumulator mAgentPositionSnaps; -  	// Phase tracking (originally put in for avatar rezzing), tracking  	// progress of active/completed phases for activities like outfit changing.  	typedef std::map<std::string,LLFrameTimer>	phase_map_t; @@ -294,16 +308,18 @@ public:  		void			stopPhase(const std::string& phase_name);  		void			stopAllPhases();  		void			clearPhases(); -		LLSD			dumpPhases(); +		LLSD			asLLSD();  		static StatsAccumulator& getPhaseStats(const std::string& phase_name);  		static void recordPhaseStat(const std::string& phase_name, F32 value);  		phase_map_t::iterator begin() { return mPhaseMap.begin(); }  		phase_map_t::iterator end() { return mPhaseMap.end(); }  	}; +	LLTrace::Recording& getRecording() { return mRecording; } +	const LLTrace::Recording& getRecording() const { return mRecording; }  private: -	F64	mStats[ST_COUNT]; +	LLTrace::Recording				mRecording;  	F64 mLastTimeDiff;  // used for time stat updates  }; @@ -315,7 +331,7 @@ void update_statistics();  void send_stats();  extern LLFrameTimer gTextureTimer; -extern U32	gTotalTextureBytes; -extern U32  gTotalObjectBytes; -extern U32  gTotalTextureBytesPerBoostLevel[] ; +extern LLUnit<LLUnits::Bytes, U32>	gTotalTextureData; +extern LLUnit<LLUnits::Bytes, U32>  gTotalObjectData; +extern LLUnit<LLUnits::Bytes, U32>  gTotalTextureBytesPerBoostLevel[] ;  #endif // LL_LLVIEWERSTATS_H diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index f9a725547f..acd8f6a29c 100755 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -224,15 +224,15 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )  			}  		}  		else -		{ -			llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl; +	{ +			//llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl;  			return;  		}  	} -	std::ostringstream data_msg; +		std::ostringstream data_msg; -	data_msg << getTimeSinceStart() +		data_msg << getTimeSinceStart()  		<< "\t " << mObjectCacheHitCount  		<< "\t" << mObjectCacheMissFullCount  		<< "\t" << mObjectCacheMissCrcCount diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index 777e1f9c76..4cd4375146 100755 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp @@ -364,7 +364,7 @@ void LLViewerTexLayerSetBuffer::doUpload()  {  	LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();  	LL_DEBUGS("Avatar") << "Uploading baked " << layer_set->getBodyRegionName() << llendl; -	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); +	add(LLStatViewer::TEX_BAKES, 1);  	// Don't need caches since we're baked now.  (note: we won't *really* be baked   	// until this image is sent to the server and the Avatar Appearance message is received.) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index eb6c453e76..e0a88bfad6 100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -65,6 +65,11 @@  #include "lltexturecache.h"  /////////////////////////////////////////////////////////////////////////////// +// extern +const LLUnit<LLUnits::Mibibytes, S32> gMinVideoRam = 32; +const LLUnit<LLUnits::Mibibytes, S32> gMaxVideoRam = 512; + +  // statics  LLPointer<LLViewerTexture>        LLViewerTexture::sNullImagep = NULL;  LLPointer<LLViewerTexture>        LLViewerTexture::sBlackImagep = NULL; @@ -83,11 +88,11 @@ S32 LLViewerTexture::sAuxCount = 0;  LLFrameTimer LLViewerTexture::sEvaluationTimer;  F32 LLViewerTexture::sDesiredDiscardBias = 0.f;  F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; -S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0; -S32 LLViewerTexture::sTotalTextureMemoryInBytes = 0; -S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0; -S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0; -S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ; +LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sBoundTextureMemory = 0; +LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sTotalTextureMemory = 0; +LLUnit<LLUnits::Mibibytes, S32> LLViewerTexture::sMaxBoundTextureMem = 0; +LLUnit<LLUnits::Mibibytes, S32> LLViewerTexture::sMaxTotalTextureMem = 0; +LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sMaxDesiredTextureMem = 0 ;  S8  LLViewerTexture::sCameraMovingDiscardBias = 0 ;  F32 LLViewerTexture::sCameraMovingBias = 0.0f ;  S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size @@ -277,7 +282,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(  }  LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile( -	                                               const std::string& filename, +	                                               const std::string& filename,												     												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -290,7 +295,7 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(  }  //static  -LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url, +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,									   									 FTType f_type,  									 BOOL usemipmaps,  									 LLViewerTexture::EBoostLevel boost_priority, @@ -397,7 +402,7 @@ void LLViewerTextureManager::init()  	LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);  	LLViewerTexture::initClass() ; -	 +  	// Create a texture manager bridge.  	gTextureManagerBridgep = new LLViewerTextureManagerBridge; @@ -527,17 +532,17 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity  		LLViewerMediaTexture::updateClass() ;  	} -	sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes -	sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes -	sMaxBoundTextureMemInMegaBytes = gTextureList.getMaxResidentTexMem();//in MB	 -	sMaxTotalTextureMemInMegaBytes = gTextureList.getMaxTotalTextureMem() ;//in MB -	sMaxDesiredTextureMemInBytes = MEGA_BYTES_TO_BYTES(sMaxTotalTextureMemInMegaBytes) ; //in Bytes, by default and when total used texture memory is small. +	sBoundTextureMemory = LLImageGL::sBoundTextureMemory;//in bytes +	sTotalTextureMemory = LLImageGL::sGlobalTextureMemory;//in bytes +	sMaxBoundTextureMem = gTextureList.getMaxResidentTexMem();//in MB	 +	sMaxTotalTextureMem = gTextureList.getMaxTotalTextureMem() ;//in MB +	sMaxDesiredTextureMem = sMaxTotalTextureMem ; //in Bytes, by default and when total used texture memory is small. -	if (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) >= sMaxBoundTextureMemInMegaBytes || -		BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) >= sMaxTotalTextureMemInMegaBytes) +	if (sBoundTextureMemory >= sMaxBoundTextureMem || +		sTotalTextureMemory >= sMaxTotalTextureMem)  	{ -		//when texture memory overflows, lower down the threashold to release the textures more aggressively. -		sMaxDesiredTextureMemInBytes = llmin((S32)(sMaxDesiredTextureMemInBytes * 0.75f) , MEGA_BYTES_TO_BYTES(MAX_VIDEO_RAM_IN_MEGA_BYTES)) ;//512 MB +		//when texture memory overflows, lower down the threshold to release the textures more aggressively. +		sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, LLUnit<LLUnits::Bytes, S32>(gMaxVideoRam));  		// If we are using more texture memory than we should,  		// scale up the desired discard level @@ -553,8 +558,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity  		sEvaluationTimer.reset();  	}  	else if (sDesiredDiscardBias > 0.0f && -			 BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < sMaxBoundTextureMemInMegaBytes * texmem_lower_bound_scale && -			 BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < sMaxTotalTextureMemInMegaBytes * texmem_lower_bound_scale) +			 sBoundTextureMemory < sMaxBoundTextureMem * texmem_lower_bound_scale && +			 sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale)  	{			   		// If we are using less texture memory than we should,  		// scale down the desired discard level @@ -572,8 +577,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity  	sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);  	sCameraMovingDiscardBias = (S8)(sCameraMovingBias); -	LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && -				(BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; +	LLViewerTexture::sFreezeImageScalingDown = (sBoundTextureMemory < 0.75f * sMaxBoundTextureMem * texmem_middle_bound_scale) && +				(sTotalTextureMemory < 0.75f * sMaxTotalTextureMem * texmem_middle_bound_scale) ;  }  //end of static functions @@ -676,6 +681,30 @@ void LLViewerTexture::setBoostLevel(S32 level)  	{  		mSelectedTime = gFrameTimeSeconds;  	} + +} + +bool LLViewerTexture::isActiveFetching() +{ +	return false; +} + +bool LLViewerTexture::bindDebugImage(const S32 stage) +{ +	if (stage < 0) return false; + +	bool res = true; +	if (LLViewerTexture::sCheckerBoardImagep.notNull() && (this != LLViewerTexture::sCheckerBoardImagep.get())) +	{ +		res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sCheckerBoardImagep); +	} + +	if(!res) +	{ +		return bindDefaultImage(stage); +	} + +	return res;  }  bool LLViewerTexture::bindDefaultImage(S32 stage)  @@ -1177,7 +1206,7 @@ void LLViewerFetchedTexture::destroyTexture()  	{  		return ;  	} - +	  	//LL_DEBUGS("Avatar") << mID << llendl;  	destroyGLTexture() ;  	mFullyLoaded = FALSE ; @@ -1704,6 +1733,13 @@ bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level)  	return true;  } +bool LLViewerFetchedTexture::isActiveFetching() +{ +	static LLCachedControl<bool> monitor_enabled(gSavedSettings,"DebugShowTextureInfo"); + +	return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE. +} +  bool LLViewerFetchedTexture::updateFetch()  {  	static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); @@ -3064,13 +3100,13 @@ void LLViewerLODTexture::processTextureStats()  				scaleDown() ;  			}  			// Limit the amount of GL memory bound each frame -			else if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale && +			else if ( sBoundTextureMemory > sMaxBoundTextureMem * texmem_middle_bound_scale &&  				(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))  			{  				scaleDown() ;  			}  			// Only allow GL to have 2x the video card memory -			else if ( BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale && +			else if ( sTotalTextureMemory > sMaxTotalTextureMem * texmem_middle_bound_scale &&  				(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))  			{  				scaleDown() ; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f2e1a90713..e939731cf2 100755 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -34,12 +34,13 @@  #include "llgltypes.h"  #include "llrender.h"  #include "llmetricperformancetester.h" +#include "llunit.h"  #include <map>  #include <list> -#define MIN_VIDEO_RAM_IN_MEGA_BYTES    32 -#define MAX_VIDEO_RAM_IN_MEGA_BYTES    512 // 512MB max for performance reasons. +extern const LLUnit<LLUnits::Mibibytes, S32> gMinVideoRam; +extern const LLUnit<LLUnits::Mibibytes, S32> gMaxVideoRam;  class LLFace;  class LLImageGL ; @@ -124,7 +125,9 @@ public:  	virtual void dump();	// debug info to llinfos  	/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; +	/*virtual*/ bool bindDebugImage(const S32 stage = 0) ;  	/*virtual*/ void forceImmediateUpdate() ; +	/*virtual*/ bool isActiveFetching();  	/*virtual*/ const LLUUID& getID() const { return mID; }  	void setBoostLevel(S32 level); @@ -202,11 +205,11 @@ public:  	static LLFrameTimer sEvaluationTimer;  	static F32 sDesiredDiscardBias;  	static F32 sDesiredDiscardScale; -	static S32 sBoundTextureMemoryInBytes; -	static S32 sTotalTextureMemoryInBytes; -	static S32 sMaxBoundTextureMemInMegaBytes; -	static S32 sMaxTotalTextureMemInMegaBytes; -	static S32 sMaxDesiredTextureMemInBytes ; +	static LLUnit<LLUnits::Bytes, S32> sBoundTextureMemory; +	static LLUnit<LLUnits::Bytes, S32> sTotalTextureMemory; +	static LLUnit<LLUnits::Mibibytes, S32> sMaxBoundTextureMem; +	static LLUnit<LLUnits::Mibibytes, S32> sMaxTotalTextureMem; +	static LLUnit<LLUnits::Bytes, S32> sMaxDesiredTextureMem ;  	static S8  sCameraMovingDiscardBias;  	static F32 sCameraMovingBias;  	static S32 sMaxSculptRez ; @@ -395,12 +398,15 @@ public:  	void        loadFromFastCache();  	void        setInFastCacheList(bool in_list) { mInFastCacheList = in_list; }  	bool        isInFastCacheList() { return mInFastCacheList; } + +	/*virtual*/bool  isActiveFetching(); //is actively in fetching by the fetching pipeline. +  protected:  	/*virtual*/ void switchToCachedImage();  	S32 getCurrentDiscardLevelForFetching() ;  private: -	void init(bool firstinit) ;	 +	void init(bool firstinit) ;  	void cleanup() ;  	void saveRawImage() ; @@ -447,7 +453,7 @@ protected:  	S8  mHasFetcher;				// We've made a fecth request  	S8  mIsFetching;				// Fetch request is active  	bool mCanUseHTTP ;              //This texture can be fetched through http if true. - +	  	FTType mFTType; // What category of image is this - map tile, server bake, etc?  	mutable S8 mIsMissingAsset;		// True if we know that there is no image asset with this image id in the database.		 diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index d2af48f528..f3b3a6086d 100755 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,21 +58,14 @@  #include "pipeline.h"  #include "llappviewer.h"  #include "llxuiparser.h" +#include "lltracerecording.h"  #include "llviewerdisplay.h" - +#include "llstartup.h"  ////////////////////////////////////////////////////////////////////////////  void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; -U32 LLViewerTextureList::sTextureBits = 0; -U32 LLViewerTextureList::sTexturePackets = 0;  S32 LLViewerTextureList::sNumImages = 0; -LLStat LLViewerTextureList::sNumImagesStat("Num Images", 32, TRUE); -LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", 32, TRUE); -LLStat LLViewerTextureList::sGLTexMemStat("GL Texture Mem", 32, TRUE); -LLStat LLViewerTextureList::sGLBoundMemStat("GL Bound Mem", 32, TRUE); -LLStat LLViewerTextureList::sRawMemStat("Raw Image Mem", 32, TRUE); -LLStat LLViewerTextureList::sFormattedMemStat("Formatted Image Mem", 32, TRUE);  LLViewerTextureList gTextureList;  static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images"); @@ -324,7 +317,7 @@ void LLViewerTextureList::restoreGL()  /////////////////////////////////////////////////////////////////////////////// -LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename, +LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,												     												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -376,7 +369,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  	}  	LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id); - +	  	if (!imagep.isNull())  	{  		LLViewerFetchedTexture *texture = imagep.get(); @@ -432,7 +425,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&  } -LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, +LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,											         												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -475,7 +468,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  		{  			llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl;  		} -		 +	  	}  	if (imagep.isNull())  	{ @@ -488,7 +481,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  }  //when this function is called, there is no such texture in the gTextureList with image_id. -LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, +LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,											         												   FTType f_type,  												   BOOL usemipmaps,  												   LLViewerTexture::EBoostLevel boost_priority, @@ -649,9 +642,11 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_FETCH("Fetch");  static LLFastTimer::DeclareTimer FTM_FAST_CACHE_IMAGE_FETCH("Fast Cache Fetch");  static LLFastTimer::DeclareTimer FTM_IMAGE_CREATE("Create");  static LLFastTimer::DeclareTimer FTM_IMAGE_STATS("Stats"); +static LLFastTimer::DeclareTimer FTM_UPDATE_IMAGES("Update Images");  void LLViewerTextureList::updateImages(F32 max_time)  { +	LLFastTimer _(FTM_UPDATE_IMAGES);  	static BOOL cleared = FALSE;  	if(gTeleportDisplay)  	{ @@ -665,14 +660,17 @@ void LLViewerTextureList::updateImages(F32 max_time)  	}  	cleared = FALSE; -	LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); +	LLAppViewer::getTextureFetch()->setTextureBandwidth(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::TEXTURE_KBIT)); -	LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); -	LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); -	LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); -	LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); -	LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); -	LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); +	{ +		using namespace LLStatViewer; +		sample(NUM_IMAGES, sNumImages); +		sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount); +		sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory); +		sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory); +		sample(RAW_MEM, LLTrace::Bytes(LLImageRaw::sGlobalRawMemory)); +		sample(FORMATTED_MEM, LLTrace::Bytes(LLImageFormatted::sGlobalFormattedMemory)); +	}  	{  		//loading from fast cache  @@ -753,8 +751,18 @@ void LLViewerTextureList::updateImagesDecodePriorities()  {  	// Update the decode priority for N images each frame  	{ -        static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities");         // default: 32 -		const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds) + 1, MAX_PRIO_UPDATES); +		F32 lazy_flush_timeout = 30.f; // stop decoding +		F32 max_inactive_time  = 20.f; // actually delete +		S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference +		if(LLStartUp::getStartupState() < STATE_STARTED) +		{ +			//do not remove pre-fetched images if viewer does not finish logging in. +			lazy_flush_timeout = 30000.f; +			max_inactive_time = 20000.f; +		} +         +		static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities");         // default: 32 +		const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);  		S32 update_counter = llmin(max_update_count, mUUIDMap.size());  		uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID);  		while ((update_counter-- > 0) && !mUUIDMap.empty()) @@ -776,14 +784,10 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			//  			// Flush formatted images using a lazy flush  			// -			const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding -			const F32 MAX_INACTIVE_TIME  = 20.f; // actually delete -			S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference -			  			S32 num_refs = imagep->getNumRefs();  			if (num_refs == min_refs)  			{ -				if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > LAZY_FLUSH_TIMEOUT) +				if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)  				{  					// Remove the unused image from the image list  					deleteImage(imagep); @@ -795,7 +799,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			{  				if(imagep->hasSavedRawImage())  				{ -					if(imagep->getElapsedLastReferencedSavedRawImageTime() > MAX_INACTIVE_TIME) +					if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)  					{  						imagep->destroySavedRawImage() ;  					} @@ -812,7 +816,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()  				}  				else if(imagep->isInactive())  				{ -					if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) +					if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)  					{  						imagep->setDeletionCandidate() ;  					} @@ -988,11 +992,11 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)  	static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0  	static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority");          // default: false -	size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds)+1, MAX_HIGH_PRIO_COUNT); +	size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds.value())+1, MAX_HIGH_PRIO_COUNT);  	max_priority_count = llmin(max_priority_count, mImageList.size());  	size_t total_update_count = mUUIDMap.size(); -	size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds)+1, MAX_UPDATE_COUNT); +	size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds.value())+1, MAX_UPDATE_COUNT);  	max_update_count = llmin(max_update_count, total_update_count);	  	// MAX_HIGH_PRIO_COUNT high priority entries @@ -1229,7 +1233,7 @@ S32 LLViewerTextureList::getMinVideoRamSetting()  {  	S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped());  	//min texture mem sets to 64M if total physical mem is more than 1.5GB -	return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ; +	return (system_ram > 1500) ? 64 : gMinVideoRam.value() ;  }  //static @@ -1279,7 +1283,7 @@ S32 LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended)  	else  		max_texmem = llmin(max_texmem, (S32)(system_ram)); -	max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES);  +	max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam.value());   	return max_texmem;  } @@ -1367,8 +1371,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d  	{  		received_size = msg->getReceiveSize() ;		  	} -	gTextureList.sTextureBits += received_size * 8; -	gTextureList.sTexturePackets++; +	add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size)); +	add(LLStatViewer::TEXTURE_PACKETS, 1);  	U8 codec;  	U16 packets; @@ -1440,8 +1444,9 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d  	{  		received_size = msg->getReceiveSize() ;		  	} -	gTextureList.sTextureBits += received_size * 8; -	gTextureList.sTexturePackets++; + +	add(LLStatViewer::TEXTURE_KBIT, LLTrace::Bytes(received_size)); +	add(LLStatViewer::TEXTURE_PACKETS, 1);  	//llprintline("Start decode, image header...");  	msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 136042620d..5b6e927e32 100755 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -1,5 +1,5 @@  /**  - * @file llviewertexturelist.h + * @file llviewertexturelinumimagest.h   * @brief Object for managing the list of images within a region   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$ @@ -30,11 +30,11 @@  #include "lluuid.h"  //#include "message.h"  #include "llgl.h" -#include "llstat.h"  #include "llviewertexture.h"  #include "llui.h"  #include <list>  #include <set> +#include "lluiimage.h"  const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128; @@ -204,17 +204,6 @@ private:  	S32 mMaxTotalTextureMemInMegaBytes;  	LLFrameTimer mForceDecodeTimer; -public: -	static U32 sTextureBits; -	static U32 sTexturePackets; - -	static LLStat sNumImagesStat; -	static LLStat sNumRawImagesStat; -	static LLStat sGLTexMemStat; -	static LLStat sGLBoundMemStat; -	static LLStat sRawMemStat; -	static LLStat sFormattedMemStat; -  private:  	static S32 sNumImages;  	static void (*sUUIDCallback)(void**, const LLUUID &); diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp index 5147272122..34f2c8f6e6 100755 --- a/indra/newview/llviewerthrottle.cpp +++ b/indra/newview/llviewerthrottle.cpp @@ -304,7 +304,8 @@ void LLViewerThrottle::updateDynamicThrottle()  	}  	mUpdateTimer.reset(); -	if (LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean() > TIGHTEN_THROTTLE_THRESHOLD) +	F32 mean_packets_lost = LLViewerStats::instance().getRecording().getMean(LLStatViewer::PACKETS_LOST_PERCENT); +	if (mean_packets_lost > TIGHTEN_THROTTLE_THRESHOLD)  	{  		if (mThrottleFrac <= MIN_FRACTIONAL || mCurrentBandwidth / 1024.0f <= MIN_BANDWIDTH)  		{ @@ -317,7 +318,7 @@ void LLViewerThrottle::updateDynamicThrottle()  		mCurrent.sendToSim();  		llinfos << "Tightening network throttle to " << mCurrentBandwidth << llendl;  	} -	else if (LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean() <= EASE_THROTTLE_THRESHOLD) +	else if (mean_packets_lost <= EASE_THROTTLE_THRESHOLD)  	{  		if (mThrottleFrac >= MAX_FRACTIONAL || mCurrentBandwidth / 1024.0f >= MAX_BANDWIDTH)  		{ diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp index e8425dc76a..c7e97cfe94 100644 --- a/indra/newview/llviewerwearable.cpp +++ b/indra/newview/llviewerwearable.cpp @@ -30,6 +30,7 @@  #include "llagentcamera.h"  #include "llagentwearables.h"  #include "llfloatersidepanelcontainer.h" +#include "lllocaltextureobject.h"  #include "llnotificationsutil.h"  #include "llsidepanelappearance.h"  #include "lltextureentry.h" diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index fe4d5b3e4d..349849a267 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -40,6 +40,7 @@  #include "llagentcamera.h"  #include "llcommunicationchannel.h"  #include "llfloaterreg.h" +#include "llhudicon.h"  #include "llmeshrepository.h"  #include "llnotificationhandler.h"  #include "llpanellogin.h" @@ -81,7 +82,6 @@  #include "llmediaentry.h"  #include "llurldispatcher.h"  #include "raytrace.h" -#include "llstat.h"  // newview includes  #include "llagent.h" @@ -253,6 +253,9 @@ std::string	LLViewerWindow::sSnapshotDir;  std::string	LLViewerWindow::sMovieBaseName; +LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); + +  class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole>  {  public: @@ -457,6 +460,8 @@ public:  		if (gSavedSettings.getBOOL("DebugShowRenderInfo"))  		{ +			LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); +  			if (gPipeline.getUseVertexShaders() == 0)  			{  				addText(xpos, ypos, "Shaders Disabled"); @@ -562,7 +567,7 @@ public:  			addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount));  			ypos += y_inc; -			addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount)); +			addText(xpos, ypos, llformat("%d Render Calls", last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize)));              ypos += y_inc;  			addText(xpos, ypos, llformat("%d/%d Objects Active", gObjectList.getNumActiveObjects(), gObjectList.getNumObjects())); @@ -577,15 +582,10 @@ public:  			gPipeline.mTextureMatrixOps = 0;  			gPipeline.mMatrixOpCount = 0; -			if (gPipeline.mBatchCount > 0) -			{ -				addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize,  -					gPipeline.mTrianglesDrawn/gPipeline.mBatchCount)); - -				gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize; -				gPipeline.mMaxBatchSize = 0; -				gPipeline.mBatchCount = 0; -			} + 			if (last_frame_recording.getSampleCount(LLPipeline::sStatBatchSize) > 0) +  			{ + 				addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", last_frame_recording.getMin(LLPipeline::sStatBatchSize), last_frame_recording.getMax(LLPipeline::sStatBatchSize), last_frame_recording.getMean(LLPipeline::sStatBatchSize))); +  			}              ypos += y_inc;  			addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls)); @@ -596,9 +596,9 @@ public:  			ypos += y_inc; -			if (!LLSpatialGroup::sPendingQueries.empty()) +			if (!LLOcclusionCullingGroup::sPendingQueries.empty())  			{ -				addText(xpos,ypos, llformat("%d Queries pending", LLSpatialGroup::sPendingQueries.size())); +				addText(xpos,ypos, llformat("%d Queries pending", LLOcclusionCullingGroup::sPendingQueries.size()));  				ypos += y_inc;  			} @@ -738,7 +738,7 @@ public:  			{  				if(gTotalTextureBytesPerBoostLevel[i] > 0)  				{ -					addText(xpos, ypos, llformat("Boost_Level %d:  %.3f MB", i, (F32)gTotalTextureBytesPerBoostLevel[i] / (1024 * 1024))); +					addText(xpos, ypos, llformat("Boost_Level %d:  %.3f MB", i, LLUnit<LLUnits::Mibibytes, F32>(gTotalTextureBytesPerBoostLevel[i]).value()));  					ypos += y_inc;  				}  			} @@ -1409,10 +1409,11 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window,  S32 x,  S32 y, S32 width,  S  		FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));  		std::string temp_str; +		LLTrace::Recording& recording = LLViewerStats::instance().getRecording();  		temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f",		/* Flawfinder: ignore */ -				LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(), -				LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0), -				LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0)); +				recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(), +				recording.getLastValue(LLStatViewer::SIM_PHYSICS_FPS),  +				recording.getLastValue(LLStatViewer::SIM_TIME_DILATION));  		S32 len = temp_str.length();  		TextOutA(hdc, 0, 0, temp_str.c_str(), len);  @@ -1547,8 +1548,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)  	mResDirty(false),  	mStatesDirty(false),  	mCurrResolutionIndex(0), -	mProgressView(NULL), -	mMouseVelocityStat(new LLStat("Mouse Velocity")) +	mProgressView(NULL)  {  	// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to  	// pass its value right now. Instead, pass it a nullary function that @@ -2089,8 +2089,6 @@ LLViewerWindow::~LLViewerWindow()  	delete mDebugText;  	mDebugText = NULL; - -	delete mMouseVelocityStat;  } @@ -2201,8 +2199,8 @@ void LLViewerWindow::reshape(S32 width, S32 height)  			}  		} -		LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width); -		LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height); +		sample(LLStatViewer::WINDOW_WIDTH, width); +		sample(LLStatViewer::WINDOW_HEIGHT, height);  		LLLayoutStack::updateClass();  	} @@ -2796,11 +2794,12 @@ void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params)  	}  } +static LLFastTimer::DeclareTimer ftm("Update UI"); +  // Update UI based on stored mouse position from mouse-move  // event processing.  void LLViewerWindow::updateUI()  { -	static LLFastTimer::DeclareTimer ftm("Update UI");  	LLFastTimer t(ftm);  	static std::string last_handle_msg; @@ -3268,8 +3267,8 @@ void LLViewerWindow::updateMouseDelta()  		static F32 fdy = 0.f;  		F32 amount = 16.f; -		fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds*amount,1.f); -		fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds*amount,1.f); +		fdx = fdx + ((F32) dx - fdx) * llmin(gFrameIntervalSeconds.value()*amount,1.f); +		fdy = fdy + ((F32) dy - fdy) * llmin(gFrameIntervalSeconds.value()*amount,1.f);  		mCurrentMouseDelta.set(llround(fdx), llround(fdy));  		mouse_vel.setVec(fdx,fdy); @@ -3280,7 +3279,7 @@ void LLViewerWindow::updateMouseDelta()  		mouse_vel.setVec((F32) dx, (F32) dy);  	} -	mMouseVelocityStat->addValue(mouse_vel.magVec()); +	sample(sMouseVelocityStat, mouse_vel.magVec());  }  void LLViewerWindow::updateKeyboardFocus() @@ -4771,7 +4770,7 @@ void LLViewerWindow::stopGL(BOOL save_state)  		gGLManager.mIsDisabled = TRUE;  		stop_glerror(); -		llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemoryInBytes << " bytes" << llendl; +		llinfos << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << llendl;  	}  } @@ -5272,8 +5271,8 @@ void LLPickInfo::getSurfaceInfo()  				LLFace* facep = objectp->mDrawable->getFace(mObjectFace);  				if (facep)  				{ -				mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); -			} +					mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); +				}  			}  			// and XY coords: diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index b33488fd78..e0943d9825 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -45,12 +45,12 @@  #include "llnotifications.h"  #include "llhandle.h"  #include "llinitparam.h" +#include "lltrace.h"  #include <boost/function.hpp>  #include <boost/signals2.hpp>  #include <boost/scoped_ptr.hpp> -class LLStat;  class LLView;  class LLViewerObject;  class LLUUID; @@ -251,7 +251,7 @@ public:  	S32				getCurrentMouseDX()		const	{ return mCurrentMouseDelta.mX; }  	S32				getCurrentMouseDY()		const	{ return mCurrentMouseDelta.mY; }  	LLCoordGL		getCurrentMouseDelta()	const	{ return mCurrentMouseDelta; } -	LLStat*			getMouseVelocityStat()		{ return mMouseVelocityStat; } +	static LLTrace::SampleStatHandle<>*	getMouseVelocityStat()		{ return &sMouseVelocityStat; }  	BOOL			getLeftMouseDown()	const	{ return mLeftMouseDown; }  	BOOL			getMiddleMouseDown()	const	{ return mMiddleMouseDown; }  	BOOL			getRightMouseDown()	const	{ return mRightMouseDown; } @@ -432,7 +432,6 @@ private:  	LLCoordGL		mCurrentMousePoint;			// last mouse position in GL coords  	LLCoordGL		mLastMousePoint;		// Mouse point at last frame.  	LLCoordGL		mCurrentMouseDelta;		//amount mouse moved this frame -	LLStat*			mMouseVelocityStat;  	BOOL			mLeftMouseDown;  	BOOL			mMiddleMouseDown;  	BOOL			mRightMouseDown; @@ -487,6 +486,8 @@ private:  	// Object temporarily hovered over while dragging  	LLPointer<LLViewerObject>	mDragHoveredObject; + +	static LLTrace::SampleStatHandle<>	sMouseVelocityStat;  };  // diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 06fb23b84b..d4c31fd4b0 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -51,7 +51,6 @@  #include "llpolyskeletaldistortion.h"  #include "lleditingmotion.h"  #include "llemote.h" -//#include "llfirstuse.h"  #include "llfloatertools.h"  #include "llheadrotmotion.h"  #include "llhudeffecttrail.h" @@ -81,6 +80,7 @@  #include "llviewermenu.h"  #include "llviewerobjectlist.h"  #include "llviewerparcelmgr.h" +#include "llviewerregion.h"  #include "llviewershadermgr.h"  #include "llviewerstats.h"  #include "llviewerwearable.h" @@ -100,6 +100,7 @@  #include "lldebugmessagebox.h"  #include "llsdutil.h" +#include "llscenemonitor.h"  #include "llsdserialize.h"  extern F32 SPEED_ADJUST_MAX; @@ -250,7 +251,7 @@ struct LLAppearanceMessageContents  	std::vector<F32> mParamWeights;  	std::vector<LLVisualParam*> mParams;  }; - +	  struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>  	{  	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> >	bone; @@ -769,6 +770,11 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mLastPelvisToFoot = 0.0f;  	mPelvisFixup = 0.0f;  	mLastPelvisFixup = 0.0f; + +	if(LLSceneMonitor::getInstance()->isEnabled()) +	{ +		LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this); +	}  }  std::string LLVOAvatar::avString() const @@ -1196,7 +1202,7 @@ void LLVOAvatar::initInstance(void)  		registerMotion( ANIM_AGENT_TARGET,					LLTargetingMotion::create );  		registerMotion( ANIM_AGENT_WALK_ADJUST,				LLWalkAdjustMotion::create );  	} - +	  	LLAvatarAppearance::initInstance();  	// preload specific motions here @@ -1542,7 +1548,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector  	return hit;  } -	 +  LLVOAvatar* LLVOAvatar::asAvatar()  {  	return this; @@ -2446,7 +2452,7 @@ void LLVOAvatar::idleUpdateWindEffect()  		LLVector3 velocity = getVelocity();  		F32 speed = velocity.length();  		//RN: velocity varies too much frame to frame for this to work -		mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLCriticalDamp::getInterpolant(0.02f)); +		mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLSmoothInterpolation::getInterpolant(0.02f));  		mLastVel = velocity;  		LLVector4 wind;  		wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity); @@ -2469,11 +2475,11 @@ void LLVOAvatar::idleUpdateWindEffect()  		F32 interp;  		if (wind.mV[VW] > mWindVec.mV[VW])  		{ -			interp = LLCriticalDamp::getInterpolant(0.2f); +			interp = LLSmoothInterpolation::getInterpolant(0.2f);  		}  		else  		{ -			interp = LLCriticalDamp::getInterpolant(0.4f); +			interp = LLSmoothInterpolation::getInterpolant(0.4f);  		}  		mWindVec = lerp(mWindVec, wind, interp); @@ -2541,7 +2547,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)  		mVisibleChat = visible_chat;  		new_name = TRUE;  	} - +		  	if (sRenderGroupTitles != mRenderGroupTitles)  	{  		mRenderGroupTitles = sRenderGroupTitles; @@ -2746,7 +2752,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)  		mNameText->setFont(LLFontGL::getFontSansSerif());  		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);  		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); - +			  		std::deque<LLChat>::iterator chat_iter = mChats.begin();  		mNameText->clearString(); @@ -2899,7 +2905,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)  		mTargetRootToHeadOffset = head_offset;  	} -	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f)); +	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLSmoothInterpolation::getInterpolant(0.2f));  	LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);  	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	 @@ -3364,7 +3370,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)  			// Set the root rotation, but do so incrementally so that it  			// lags in time by some fixed amount. -			//F32 u = LLCriticalDamp::getInterpolant(PELVIS_LAG); +			//F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG);  			F32 pelvis_lag_time = 0.f;  			if (self_in_mouselook)  			{ @@ -3707,7 +3713,7 @@ bool LLVOAvatar::shouldAlphaMask()  //-----------------------------------------------------------------------------  // renderSkinned()  //----------------------------------------------------------------------------- -U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) +U32 LLVOAvatar::renderSkinned()  {  	U32 num_indices = 0; @@ -3868,75 +3874,62 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  	//--------------------------------------------------------------------  	// render all geometry attached to the skeleton  	//-------------------------------------------------------------------- -	static LLStat render_stat; -	LLViewerJointMesh::sRenderPass = pass; - -	if (pass == AVATAR_RENDER_PASS_SINGLE) +	bool should_alpha_mask = shouldAlphaMask(); +	LLGLState test(GL_ALPHA_TEST, should_alpha_mask); +	 +	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)  	{ - -		bool should_alpha_mask = shouldAlphaMask(); -		LLGLState test(GL_ALPHA_TEST, should_alpha_mask); -		 -		if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) -		{ -			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); -		} -		 -		BOOL first_pass = TRUE; -		if (!LLDrawPoolAvatar::sSkipOpaque) +		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); +	} +	 +	BOOL first_pass = TRUE; +	if (!LLDrawPoolAvatar::sSkipOpaque) +	{ +		if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)  		{ -			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender) +			if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)  			{ -				if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy) +				LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); +				if (head_mesh)  				{ -					LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD); -					if (head_mesh) -					{ -						num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy); -					} -					first_pass = FALSE; -				} -			} -			if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy) -			{ -				LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); -				if (upper_mesh) -				{ -					num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); -				} -				first_pass = FALSE; -			} -			 -			if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy) -			{ -				LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); -				if (lower_mesh) -				{ -					num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +					num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy);  				}  				first_pass = FALSE;  			}  		} - -		if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) +		if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy)  		{ -			gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +			LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY); +			if (upper_mesh) +			{ +				num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +			} +			first_pass = FALSE;  		} - -		if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) +		 +		if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy)  		{ -			LLGLState blend(GL_BLEND, !mIsDummy); -			LLGLState test(GL_ALPHA_TEST, !mIsDummy); -			num_indices += renderTransparent(first_pass); +			LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY); +			if (lower_mesh) +			{ +				num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); +			} +			first_pass = FALSE;  		}  	} -	LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; +	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction) +	{ +		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); +	} -	//llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl; - -	//render_stat.addValue(render_timer.getElapsedTimeF32()*1000.f); +	if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender) +	{ +		LLGLState blend(GL_BLEND, !mIsDummy); +		LLGLState test(GL_ALPHA_TEST, !mIsDummy); +		num_indices += renderTransparent(first_pass); +	}  	return num_indices;  } @@ -5108,7 +5101,7 @@ BOOL LLVOAvatar::loadSkeletonNode ()  	{  		return FALSE;  	} - +	  	// ATTACHMENTS  	{  		LLAvatarXmlInfo::attachment_info_list_t::iterator iter; @@ -6082,7 +6075,7 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse  	record["grid_y"] = LLSD::Integer(grid_y);  	record["is_using_server_bakes"] = ((bool) isUsingServerBakes());  	record["is_self"] = isSelf(); -	 +		  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->addMetricsTimerRecord(record); @@ -6290,11 +6283,11 @@ void LLVOAvatar::updateMeshTextures()  										   use_lkg_baked_layer[i],  										   last_id_string.c_str());  	} -	 +  	for (U32 i=0; i < mBakedTextureDatas.size(); i++)  	{  		debugColorizeSubMeshes(i, LLColor4::white); - +	  		LLViewerTexLayerSet* layerset = getTexLayerSet(i);  		if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )  		{ @@ -6754,7 +6747,7 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)  //					param_location_name(vparam->getParamLocation()).c_str()  		);  } - +	  void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,  	const LLAppearanceMessageContents& contents) @@ -6821,7 +6814,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe  		// For future use:  		//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);  	} - +	  	// Parse visual params, if any.  	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);  	bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing @@ -7245,7 +7238,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu  	LLUUID *avatar_idp = (LLUUID *)userdata;  	LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); - +	  	if (selfp)  	{  		LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL; @@ -7559,14 +7552,14 @@ void LLVOAvatar::cullAvatarsByPixelArea()  		if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame  		{  			sUnbakedUpdateTime = gFrameTimeSeconds; -			sUnbakedTime += gFrameIntervalSeconds; +			sUnbakedTime += gFrameIntervalSeconds.value();  		}  		if (grey_avatars > 0)  		{  			if (gFrameTimeSeconds != sGreyUpdateTime) // only update once per frame  			{  				sGreyUpdateTime = gFrameTimeSeconds; -				sGreyTime += gFrameIntervalSeconds; +				sGreyTime += gFrameIntervalSeconds.value();  			}  		}  	} @@ -7619,7 +7612,7 @@ void LLVOAvatar::setIsUsingServerBakes(BOOL newval)  // virtual  void LLVOAvatar::removeMissingBakedTextures() -{	 +{  }  //virtual diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 85f6f25009..c814d4c129 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -33,7 +33,7 @@  #include <string>  #include <vector> -#include <boost/signals2.hpp> +#include <boost/signals2/trackable.hpp>  #include "imageids.h"			// IMG_INVISIBLE  #include "llavatarappearance.h" @@ -74,6 +74,7 @@ struct LLVOAvatarChildJoint;  //class LLViewerJoint;  struct LLAppearanceMessageContents;  struct LLVOAvatarSkeletonInfo; +class LLViewerJointMesh;  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // LLVOAvatar @@ -372,7 +373,7 @@ public:  	bool		isVisuallyMuted() const;  	U32 		renderRigid(); -	U32 		renderSkinned(EAvatarRenderPass pass); +	U32 		renderSkinned();  	F32			getLastSkinTime() { return mLastSkinTime; }  	U32 		renderTransparent(BOOL first_pass);  	void 		renderCollisionVolumes(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index d54eb5f040..9ab910f7fd 100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -43,6 +43,7 @@  #include "llhudeffecttrail.h"  #include "llhudmanager.h"  #include "llinventoryfunctions.h" +#include "lllocaltextureobject.h"  #include "llnotificationsutil.h"  #include "llselectmgr.h"  #include "lltoolgrab.h"	// for needsRenderBeam @@ -789,7 +790,10 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,  		updateMeshTextures();  		// unpack the texture UUIDs to the texture slots -		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); +		if(mesgsys != NULL) +		{ +			retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num); +		}  		// need to trigger a few operations to get the avatar to use the new bakes  		for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -896,17 +900,11 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)  		if (mLastRegionHandle != 0)  		{  			++mRegionCrossingCount; -			F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32(); -			F64 avg = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_AVG); -			F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount; -			LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg); -			 -			F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX); -			max = llmax(delta, max); -			LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max); +			LLTrace::Seconds delta = mRegionCrossingTimer.getElapsedTimeF32(); +			record(LLStatViewer::REGION_CROSSING_TIME, delta);  			// Diagnostics -			llinfos << "Region crossing took " << (F32)(delta * 1000.0) << " ms " << llendl; +			llinfos << "Region crossing took " << (F32)(delta * 1000.0).value() << " ms " << llendl;  		}  		if (regionp)  		{ @@ -2233,7 +2231,7 @@ LLSD LLVOAvatarSelf::metricsData()  	result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();  	result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32();  	result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32(); -	result["startup"] = LLStartUp::getPhases().dumpPhases(); +	result["startup"] = LLStartUp::getPhases().asLLSD();  	return result;  } @@ -2351,7 +2349,7 @@ LLSD summarize_by_buckets(std::vector<LLSD> in_records,  		 accum_it != accum.end(); ++accum_it)  	{  		LLSD out_record = accum_it->first; -		out_record["stats"] = accum_it->second.getData(); +		out_record["stats"] = accum_it->second.asLLSD();  		result.append(out_record);  	}  	return result; @@ -2586,7 +2584,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  			{  				F32 desired_pixels;  				desired_pixels = llmin(mPixelArea, (F32)getTexImageArea()); -				 +  				imagep->setBoostLevel(getAvatarBoostLevel());  				imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;  				imagep->resetTextureStats(); @@ -2851,7 +2849,7 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)  					llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;  					gAgentAvatarp->invalidateComposite(layer_set, TRUE);  					found = TRUE; -					LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); +					add(LLStatViewer::TEX_REBAKES, 1);  				}  			}  		} @@ -2887,7 +2885,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)  			}  			invalidateComposite(layer_set, TRUE); -			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES); +			add(LLStatViewer::TEX_REBAKES, 1);  		}  		else  		{ @@ -3076,7 +3074,7 @@ void LLVOAvatarSelf::deleteScratchTextures()  		sScratchTexNames.deleteAllData();  		sScratchTexLastBindTime.deleteAllData(); -		LLImageGL::sGlobalTextureMemoryInBytes -= sScratchTexBytes; +		LLImageGL::sGlobalTextureMemory -= sScratchTexBytes;  		sScratchTexBytes = 0;  	}  } diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 7db19c5c1b..5e2d2efc5e 100755 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -29,6 +29,12 @@  #include "llerror.h"  #include "llregionhandle.h"  #include "llviewercontrol.h" +#include "llviewerobjectlist.h" +#include "lldrawable.h" +#include "llviewerregion.h" +#include "pipeline.h" + +LLTrace::MemStatHandle	LLVOCachePartition::sMemStat("LLVOCachePartition");  BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)   { @@ -46,12 +52,18 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)  //---------------------------------------------------------------------------  LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp) -	: +	: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),  	mLocalID(local_id),  	mCRC(crc), +	mUpdateFlags(-1),  	mHitCount(0),  	mDupeCount(0), -	mCRCChangeCount(0) +	mCRCChangeCount(0), +	mState(INACTIVE), +	mMinFrameRange(64), +	mSceneContrib(0.f), +	mTouched(TRUE), +	mParentID(0)  {  	mBuffer = new U8[dp.getBufferSize()];  	mDP.assignBuffer(mBuffer, dp.getBufferSize()); @@ -59,24 +71,39 @@ LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &  }  LLVOCacheEntry::LLVOCacheEntry() -	: +	: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),  	mLocalID(0),  	mCRC(0), +	mUpdateFlags(-1),  	mHitCount(0),  	mDupeCount(0),  	mCRCChangeCount(0), -	mBuffer(NULL) +	mBuffer(NULL), +	mState(INACTIVE), +	mMinFrameRange(64), +	mSceneContrib(0.f), +	mTouched(TRUE), +	mParentID(0)  {  	mDP.assignBuffer(mBuffer, 0);  }  LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) -	: mBuffer(NULL) +	: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLVOCACHEENTRY),  +	mBuffer(NULL), +	mUpdateFlags(-1), +	mState(INACTIVE), +	mMinFrameRange(64), +	mSceneContrib(0.f), +	mTouched(FALSE), +	mParentID(0)  {  	S32 size = -1;  	BOOL success;  	mDP.assignBuffer(mBuffer, 0); +	setOctreeEntry(NULL); +  	success = check_read(apr_file, &mLocalID, sizeof(U32));  	if(success)  	{ @@ -132,32 +159,88 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)  		mDupeCount = 0;  		mCRCChangeCount = 0;  		mBuffer = NULL; +		mEntry = NULL; +		mState = 0;  	}  }  LLVOCacheEntry::~LLVOCacheEntry()  {  	mDP.freeBuffer(); +	//llassert(mState == INACTIVE);  } +//virtual  +void LLVOCacheEntry::setOctreeEntry(LLViewerOctreeEntry* entry) +{ +	if(!entry && mDP.getBufferSize() > 0) +	{ +		LLUUID fullid; +		LLViewerObject::unpackUUID(&mDP, fullid, "ID"); +		 +		LLViewerObject* obj = gObjectList.findObject(fullid); +		if(obj && obj->mDrawable) +		{ +			entry = obj->mDrawable->getEntry(); +		} +	} -// New CRC means the object has changed. -void LLVOCacheEntry::assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp) +	LLViewerOctreeEntryData::setOctreeEntry(entry); +} + +void LLVOCacheEntry::moveTo(LLVOCacheEntry* new_entry)  { -	if (  (mCRC != crc) -		||(mDP.getBufferSize() == 0)) +	//copy LLViewerOctreeEntry +	if(mEntry.notNull())  	{ -		mCRC = crc; -		mHitCount = 0; -		mCRCChangeCount++; +		new_entry->setOctreeEntry(mEntry); +		mEntry = NULL; +	} + +	//copy children +	S32 num_children = getNumOfChildren(); +	for(S32 i = 0; i < num_children; i++) +	{ +		new_entry->addChild(getChild(i)); +	} +	mChildrenList.clear(); +} -		mDP.freeBuffer(); -		mBuffer = new U8[dp.getBufferSize()]; -		mDP.assignBuffer(mBuffer, dp.getBufferSize()); -		mDP = dp; +void LLVOCacheEntry::setState(U32 state) +{ +	mState = state; + +	if(getState() == ACTIVE) +	{ +		const S32 MIN_REAVTIVE_INTERVAL = 32; +		U32 last_visible = getVisible(); +		 +		setVisible(); + +		if(getVisible() - last_visible < MIN_REAVTIVE_INTERVAL + mMinFrameRange) +		{ +			mMinFrameRange = llmin(mMinFrameRange * 2, 2048); +		} +		else +		{ +			mMinFrameRange = 64; //reset +		}  	}  } +//virtual  +S32  LLVOCacheEntry::getMinFrameRange()const +{ +	return mMinFrameRange; +} + +void LLVOCacheEntry::addChild(LLVOCacheEntry* entry) +{ +	llassert(entry != NULL); + +	mChildrenList.push_back(entry); +} +	  LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc)  {  	if (  (mCRC != crc) @@ -170,9 +253,20 @@ LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc)  	return &mDP;  } +LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP() +{ +	if (mDP.getBufferSize() == 0) +	{ +		//llinfos << "Not getting cache entry, invalid!" << llendl; +		return NULL; +	} +	 +	return &mDP; +}  void LLVOCacheEntry::recordHit()  { +	setTouched();  	mHitCount++;  } @@ -189,6 +283,11 @@ void LLVOCacheEntry::dump() const  BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const  { +	if(!mEntry) +	{ +		return FALSE; +	} +  	BOOL success;  	success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));  	if(success) @@ -221,49 +320,183 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const  	return success ;  } +void LLVOCacheEntry::calcSceneContribution(const LLVector3& camera_origin, bool needs_update, U32 last_update) +{ +	if(!needs_update && getVisible() >= last_update) +	{ +		return; //no need to update +	} + +	const LLVector4a& center = getPositionGroup(); +	 +	LLVector4a origin; +	origin.load3(camera_origin.mV); + +	LLVector4a lookAt; +	lookAt.setSub(center, origin); +	F32 squared_dist = lookAt.dot3(lookAt).getF32(); + +	F32 rad = getBinRadius(); +	mSceneContrib = rad * rad / squared_dist; + +	setVisible(); +} + +void LLVOCacheEntry::setBoundingInfo(const LLVector3& pos, const LLVector3& scale) +{ +	LLVector4a center, newMin, newMax; +	center.load3(pos.mV); +	LLVector4a size; +	size.load3(scale.mV); +	newMin.setSub(center, size); +	newMax.setAdd(center, size); +	 +	setPositionGroup(center); +	setSpatialExtents(newMin, newMax); +	setBinRadius(llmin(size.getLength3().getF32() * 4.f, 256.f)); +} +  //------------------------------------------------------------------- -//LLVOCache +//LLVOCachePartition  //------------------------------------------------------------------- -// Format string used to construct filename for the object cache -static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc"; +LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp) +{ +	mLODPeriod = 16; +	mRegionp = regionp; +	mPartitionType = LLViewerRegion::PARTITION_VO_CACHE; +	 +	new LLOcclusionCullingGroup(mOctree, this); +} -const U32 MAX_NUM_OBJECT_ENTRIES = 128 ; -const U32 MIN_ENTRIES_TO_PURGE = 16 ; -const U32 INVALID_TIME = 0 ; -const char* object_cache_dirname = "objectcache"; -const char* header_filename = "object.cache"; +void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry) +{ +	llassert(entry->hasVOCacheEntry()); -LLVOCache* LLVOCache::sInstance = NULL; +	mOctree->insert(entry); +} +	 +void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry) +{ +	entry->getVOCacheEntry()->setGroup(NULL); -//static  -LLVOCache* LLVOCache::getInstance()  -{	 -	if(!sInstance) +	llassert(!entry->getGroup()); +} +	 +class LLVOCacheOctreeCull : public LLViewerOctreeCull +{ +public: +	LLVOCacheOctreeCull(LLCamera* camera, LLViewerRegion* regionp, const LLVector3& shift, bool use_object_cache_occlusion)  +		: LLViewerOctreeCull(camera),  +		  mRegionp(regionp)  	{ -		sInstance = new LLVOCache() ; +		mLocalShift = shift; +		mUseObjectCacheOcclusion = (use_object_cache_occlusion && LLPipeline::sUseOcclusion);  	} -	return sInstance ; -} -//static  -BOOL LLVOCache::hasInstance()  -{ -	return sInstance != NULL ; -} +	virtual bool earlyFail(LLviewerOctreeGroup* base_group) +	{ +		if( mUseObjectCacheOcclusion && +			base_group->getOctreeNode()->getParent()) //never occlusion cull the root node +		{ +			LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; +			if(group->needsUpdate()) +			{ +				return false; //needs to issue new occlusion culling check. +			} + +			group->checkOcclusion(); + +			if (group->isOcclusionState(LLSpatialGroup::OCCLUDED)) +			{ +				return true; +			} +		} + +		return false; +	} + +	virtual S32 frustumCheck(const LLviewerOctreeGroup* group) +	{ +		S32 res = AABBInRegionFrustumGroupBounds(group); +		 +		//S32 res = AABBInRegionFrustumNoFarClipGroupBounds(group); +		if (res != 0) +		{ +			res = llmin(res, AABBRegionSphereIntersectGroupExtents(group, mLocalShift)); +		} +		return res; +	} + +	virtual S32 frustumCheckObjects(const LLviewerOctreeGroup* group) +	{ +		S32 res = AABBInRegionFrustumObjectBounds(group); + +		//S32 res = AABBInRegionFrustumNoFarClipObjectBounds(group); +		if (res != 0) +		{ +			res = llmin(res, AABBRegionSphereIntersectObjectExtents(group, mLocalShift)); +		} +		return res; +	} -//static  -void LLVOCache::destroyClass()  +	virtual void processGroup(LLviewerOctreeGroup* base_group) +	{ +		if(mUseObjectCacheOcclusion && base_group->getOctreeNode()->getParent()) +		{ +			LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group; +			if (group->needsUpdate() || group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1) +			{ +				((LLOcclusionCullingGroup*)group)->doOcclusion(mCamera); +				group->setVisible(); +				return; //wait for occlusion culling results +			} +		} +		mRegionp->addVisibleGroup(base_group); +	} + +private: +	LLViewerRegion* mRegionp; +	LLVector3       mLocalShift; //shift vector from agent space to local region space. +	bool            mUseObjectCacheOcclusion; +}; + +S32 LLVOCachePartition::cull(LLCamera &camera)  { -	if(sInstance) +	static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion"); + +	if(!LLViewerRegion::sVOCacheCullingEnabled)  	{ -		delete sInstance ; -		sInstance = NULL ; +		return 0;  	} + +	((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound(); + +	//localize the camera +	LLVector3 region_agent = mRegionp->getOriginAgent(); +	camera.calcRegionFrustumPlanes(region_agent); + +	LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, use_object_cache_occlusion); +	culler.traverse(mOctree); + +	return 0;  } +//------------------------------------------------------------------- +//LLVOCache +//------------------------------------------------------------------- +// Format string used to construct filename for the object cache +static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc"; + +const U32 MAX_NUM_OBJECT_ENTRIES = 128 ; +const U32 MIN_ENTRIES_TO_PURGE = 16 ; +const U32 INVALID_TIME = 0 ; +const char* object_cache_dirname = "objectcache"; +const char* header_filename = "object.cache"; + +  LLVOCache::LLVOCache(): -	mInitialized(FALSE), -	mReadOnly(TRUE), +	mInitialized(false), +	mReadOnly(true),  	mNumEntries(0),  	mCacheSize(1)  { @@ -300,7 +533,7 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)  		llwarns << "Cache already initialized." << llendl;  		return ;  	} -	mInitialized = TRUE ; +	mInitialized = true;  	setDirNames(location);  	if (!mReadOnly) @@ -325,13 +558,19 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)  	}	  } -void LLVOCache::removeCache(ELLPath location)  +void LLVOCache::removeCache(ELLPath location, bool started)   { +	if(started) +	{ +		removeCache(); +		return; +	} +  	if(mReadOnly)  	{  		llwarns << "Not removing cache at " << location << ": Cache is currently in read-only mode." << llendl;  		return ; -	} +	}	  	llinfos << "about to remove the object cache due to settings." << llendl ; @@ -342,22 +581,25 @@ void LLVOCache::removeCache(ELLPath location)  	LLFile::rmdir(cache_dir);  	clearCacheInMemory(); -	mInitialized = FALSE ; +	mInitialized = false;  }  void LLVOCache::removeCache()   { -	llassert_always(mInitialized) ; +	if(!mInitialized) +	{ +		//OK to remove cache even it is not initialized. +		llwarns << "Object cache is not initialized yet." << llendl; +	} +  	if(mReadOnly)  	{  		llwarns << "Not clearing object cache: Cache is currently in read-only mode." << llendl;  		return ;  	} -	llinfos << "about to remove the object cache due to some error." << llendl ; -  	std::string mask = "*"; -	llinfos << "Removing cache at " << mObjectCacheDirName << llendl; +	llinfos << "Removing object cache at " << mObjectCacheDirName << llendl;  	gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask);   	clearCacheInMemory() ; @@ -366,23 +608,23 @@ void LLVOCache::removeCache()  void LLVOCache::removeEntry(HeaderEntryInfo* entry)   { -	llassert_always(mInitialized) ; +	llassert_always(mInitialized);  	if(mReadOnly)  	{ -		return ; +		return;  	}  	if(!entry)  	{ -		return ; +		return;  	} -	header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry) ; +	header_entry_queue_t::iterator iter = mHeaderEntryQueue.find(entry);  	if(iter != mHeaderEntryQueue.end())  	{		 -		mHandleEntryMap.erase(entry->mHandle) ;		 -		mHeaderEntryQueue.erase(iter) ; -		removeFromCache(entry) ; -		delete entry ; +		mHandleEntryMap.erase(entry->mHandle);		 +		mHeaderEntryQueue.erase(iter); +		removeFromCache(entry); +		delete entry;  		mNumEntries = mHandleEntryMap.size() ;  	} @@ -625,11 +867,10 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca  				{  					for (S32 i = 0; i < num_entries; i++)  					{ -						LLVOCacheEntry* entry = new LLVOCacheEntry(&apr_file); +						LLPointer<LLVOCacheEntry> entry = new LLVOCacheEntry(&apr_file);  						if (!entry->getLocalID())  						{  							llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; -							delete entry ;  							success = false ;  							break ;  						} @@ -665,7 +906,7 @@ void LLVOCache::purgeEntries(U32 size)  	mNumEntries = mHandleEntryMap.size() ;  } -void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache)  +void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled)   {  	if(!mEnabled)  	{ @@ -738,7 +979,10 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:  			for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)  			{ -				success = iter->second->writeToFile(&apr_file) ; +				if(!removal_enabled || iter->second->isTouched()) +				{ +					success = iter->second->writeToFile(&apr_file) ; +				}  			}  		}  	} diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 14e3b4c793..e46fec9dc3 100755 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -29,51 +29,138 @@  #include "lluuid.h"  #include "lldatapacker.h" -#include "lldlinked.h"  #include "lldir.h" - +#include "llvieweroctree.h" +#include "llapr.h"  //---------------------------------------------------------------------------  // Cache entries  class LLVOCacheEntry; +class LLCamera; -class LLVOCacheEntry +class LLVOCacheEntry : public LLViewerOctreeEntryData  {  public: +	enum //low 16-bit state +	{ +		INACTIVE = 0x00000000,     //not visible +		IN_QUEUE = 0x00000001,     //in visible queue, object to be created +		WAITING  = 0x00000002,     //object creation request sent +		ACTIVE   = 0x00000004      //object created, and in rendering pipeline. +	}; + +	struct CompareVOCacheEntry +	{ +		bool operator()(const LLVOCacheEntry* const& lhs, const LLVOCacheEntry* const& rhs) +		{ +			F32 lpa = lhs->getSceneContribution(); +			F32 rpa = rhs->getSceneContribution(); + +			//larger pixel area first +			if(lpa > rpa)		 +			{ +				return true; +			} +			else if(lpa < rpa) +			{ +				return false; +			} +			else +			{ +				return lhs < rhs; +			}			 +		} +	}; +protected: +	~LLVOCacheEntry(); +public:  	LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);  	LLVOCacheEntry(LLAPRFile* apr_file); -	LLVOCacheEntry(); -	~LLVOCacheEntry(); +	LLVOCacheEntry();	 +	void setState(U32 state); +	//void clearState(U32 state) {mState &= ~state;} +	bool isState(U32 state)    {return mState == state;} +	bool hasState(U32 state)   {return mState & state;} +	U32  getState() const      {return mState;} +	  	U32 getLocalID() const			{ return mLocalID; }  	U32 getCRC() const				{ return mCRC; }  	S32 getHitCount() const			{ return mHitCount; }  	S32 getCRCChangeCount() const	{ return mCRCChangeCount; } +	S32 getMinFrameRange()const;	 + +	void calcSceneContribution(const LLVector3& camera_origin, bool needs_update, U32 last_update); +	void setSceneContribution(F32 scene_contrib) {mSceneContrib = scene_contrib;} +	F32 getSceneContribution() const             { return mSceneContrib;}  	void dump() const;  	BOOL writeToFile(LLAPRFile* apr_file) const; -	void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp);  	LLDataPackerBinaryBuffer *getDP(U32 crc); +	LLDataPackerBinaryBuffer *getDP();  	void recordHit();  	void recordDupe() { mDupeCount++; } +	 +	void moveTo(LLVOCacheEntry* new_entry); //copy variables  +	/*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry); + +	void setParentID(U32 id) {mParentID = id;} +	U32  getParentID() const {return mParentID;} + +	void addChild(LLVOCacheEntry* entry); +	LLVOCacheEntry* getChild(S32 i) {return mChildrenList[i];} +	S32  getNumOfChildren()         {return mChildrenList.size();} +	void clearChildrenList()        {mChildrenList.clear();} + +	//called from processing object update message +	void setBoundingInfo(const LLVector3& pos, const LLVector3& scale); +	 +	void setTouched(BOOL touched = TRUE) {mTouched = touched;} +	BOOL isTouched() const {return mTouched;} + +	void setUpdateFlags(U32 flags) {mUpdateFlags = flags;} +	U32  getUpdateFlags() const    {return mUpdateFlags;}  public: -	typedef std::map<U32, LLVOCacheEntry*>	vocache_entry_map_t; +	typedef std::map<U32, LLPointer<LLVOCacheEntry> >	   vocache_entry_map_t; +	typedef std::set<LLVOCacheEntry*>                      vocache_entry_set_t; +	typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t;	  protected:  	U32							mLocalID; +	U32                         mParentID;  	U32							mCRC; +	U32                         mUpdateFlags; //receive from sim  	S32							mHitCount;  	S32							mDupeCount;  	S32							mCRCChangeCount;  	LLDataPackerBinaryBuffer	mDP;  	U8							*mBuffer; + +	F32                         mSceneContrib; //projected scene contributuion of this object. +	S32                         mMinFrameRange; +	U32                         mState; //high 16 bits reserved for special use. +	std::vector<LLVOCacheEntry*> mChildrenList; //children entries in a linked set. + +	BOOL                        mTouched; //if set, this entry is valid, otherwise it is invalid. +}; + +class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTrackable<LLVOCachePartition> +{ +public: +	LLVOCachePartition(LLViewerRegion* regionp); + +	void addEntry(LLViewerOctreeEntry* entry); +	void removeEntry(LLViewerOctreeEntry* entry); +	/*virtual*/ S32 cull(LLCamera &camera); + +	static	LLTrace::MemStatHandle	sMemStat;  };  //  //Note: LLVOCache is not thread-safe  // -class LLVOCache +class LLVOCache : public LLSingleton<LLVOCache>  {  private:  	struct HeaderEntryInfo @@ -106,19 +193,20 @@ private:  	typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;  	typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;  private: +    friend class LLSingleton<LLVOCache>;  	LLVOCache() ;  public:  	~LLVOCache() ;  	void initCache(ELLPath location, U32 size, U32 cache_version) ; -	void removeCache(ELLPath location) ; +	void removeCache(ELLPath location, bool started = false) ;  	void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ; -	void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) ; +	void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled);  	void removeEntry(U64 handle) ; -	void setReadOnly(BOOL read_only) {mReadOnly = read_only;}  +	void setReadOnly(bool read_only) {mReadOnly = read_only;}   private:  	void setDirNames(ELLPath location);	 @@ -134,9 +222,9 @@ private:  	BOOL updateEntry(const HeaderEntryInfo* entry);  private: -	BOOL                 mEnabled; -	BOOL                 mInitialized ; -	BOOL                 mReadOnly ; +	bool                 mEnabled; +	bool                 mInitialized ; +	bool                 mReadOnly ;  	HeaderMetaInfo       mMetaInfo;  	U32                  mCacheSize;  	U32                  mNumEntries; @@ -145,12 +233,6 @@ private:  	LLVolatileAPRPool*   mLocalAPRFilePoolp ; 	  	header_entry_queue_t mHeaderEntryQueue;  	handle_entry_map_t   mHandleEntryMap;	 - -	static LLVOCache* sInstance ; -public: -	static LLVOCache* getInstance() ; -	static BOOL       hasInstance() ;	 -	static void       destroyClass() ;  };  #endif diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 6a25b765cf..e9efc7db9a 100755 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -603,8 +603,8 @@ U32 LLVOGrass::getPartitionType() const  	return LLViewerRegion::PARTITION_GRASS;  } -LLGrassPartition::LLGrassPartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB) +LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)  {  	mDrawableType = LLPipeline::RENDER_TYPE_GRASS;  	mPartitionType = LLViewerRegion::PARTITION_GRASS; @@ -624,9 +624,9 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count  	LLViewerCamera* camera = LLViewerCamera::getInstance();  	for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{ -		LLDrawable* drawablep = *i; +		LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); -		if (drawablep->isDead()) +		if (!drawablep || drawablep->isDead())  		{  			continue;  		} @@ -738,8 +738,10 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)  			LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),   				//facep->getTexture(),  				buffer, fullbright);  -			info->mExtents[0] = group->mObjectExtents[0]; -			info->mExtents[1] = group->mObjectExtents[1]; + +			const LLVector4a* exts = group->getObjectExtents(); +			info->mExtents[0] = exts[0]; +			info->mExtents[1] = exts[1];  			info->mVSize = vsize;  			draw_vec.push_back(info);  			//for alpha sorting diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index ac2a34ba1e..312842a70f 100755 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -28,12 +28,14 @@  #include "llagent.h"  #include "llfloaterreg.h" +#include "llhttpclient.h"  #include "llimview.h"  #include "llnotifications.h"  #include "llnotificationsutil.h"  #include "llpanel.h"  #include "llrecentpeople.h"  #include "llviewercontrol.h" +#include "llviewerregion.h"  #include "llvoicechannel.h" diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 714dd6a9f2..bd9ea029a9 100755 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -34,7 +34,6 @@ class LLVOAvatar;  #include "lliosocket.h"  #include "v3math.h"  #include "llframetimer.h" -#include "llviewerregion.h"  #include "llcallingcard.h"   // for LLFriendObserver  #include "llsecapi.h"  #include "llcontrol.h" diff --git a/indra/newview/llvoinventorylistener.h b/indra/newview/llvoinventorylistener.h index bf14d19b01..c50c475478 100755 --- a/indra/newview/llvoinventorylistener.h +++ b/indra/newview/llvoinventorylistener.h @@ -30,7 +30,9 @@  #ifndef LL_LLVOINVENTORYLISTENER_H  #define LL_LLVOINVENTORYLISTENER_H -#include "llviewerobject.h" +#include "llinventory.h" + +class LLViewerObject;  class LLVOInventoryListener  { diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 0b34bbb90f..41b306007d 100755 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -489,8 +489,8 @@ U32 LLVOPartGroup::getPartitionType() const  	return LLViewerRegion::PARTITION_PARTICLE;   } -LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB) +LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)  {  	mRenderPass = LLRenderPass::PASS_ALPHA;  	mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; @@ -499,8 +499,8 @@ LLParticlePartition::LLParticlePartition()  	mLODPeriod = 1;  } -LLHUDParticlePartition::LLHUDParticlePartition() : -	LLParticlePartition() +LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) : +	LLParticlePartition(regionp)  {  	mDrawableType = LLPipeline::RENDER_TYPE_HUD_PARTICLES;  	mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE; @@ -510,7 +510,7 @@ static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO");  void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)  { -	if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) +	if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))  	{  		return;  	} @@ -558,9 +558,9 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co  	LLViewerCamera* camera = LLViewerCamera::getInstance();  	for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{ -		LLDrawable* drawablep = *i; +		LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); -		if (drawablep->isDead()) +		if (!drawablep || drawablep->isDead())  		{  			continue;  		} @@ -699,8 +699,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)  			LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),   				//facep->getTexture(),  				buffer, fullbright);  -			info->mExtents[0] = group->mObjectExtents[0]; -			info->mExtents[1] = group->mObjectExtents[1]; + +			const LLVector4a* exts = group->getObjectExtents(); +			info->mExtents[0] = exts[0]; +			info->mExtents[1] = exts[1];  			info->mVSize = vsize;  			draw_vec.push_back(info);  			//for alpha sorting diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 36793017ed..0a119e853a 100755 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -2146,7 +2146,7 @@ void LLVOSky::updateFog(const F32 distance)  		// get the water param manager variables  		float water_fog_density = LLWaterParamManager::getInstance()->getFogDensity(); -		LLColor4 water_fog_color = LLDrawPoolWater::sWaterFogColor.mV; +		LLColor4 water_fog_color(LLDrawPoolWater::sWaterFogColor.mV);  		// adjust the color based on depth.  We're doing linear approximations  		float depth_scale = gSavedSettings.getF32("WaterGLFogDepthScale"); diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index de15f0ef43..5b7aee2427 100755 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1052,8 +1052,8 @@ U32 LLVOSurfacePatch::getPartitionType() const  	return LLViewerRegion::PARTITION_TERRAIN;   } -LLTerrainPartition::LLTerrainPartition() -: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB) +LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)  {  	mOcclusionEnabled = FALSE;  	mInfiniteFarClip = TRUE; diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index a15878368e..21693e85e1 100755 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -33,6 +33,8 @@  class LLSurfacePatch;  class LLDrawPool;  class LLVector2; +class LLFacePool; +class LLFace;  class LLVOSurfacePatch : public LLStaticViewerObject  { diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 145a0380d6..9a044968d2 100755 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -1290,8 +1290,8 @@ U32 LLVOTree::getPartitionType() const  	return LLViewerRegion::PARTITION_TREE;   } -LLTreePartition::LLTreePartition() -: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) +LLTreePartition::LLTreePartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)  {  	mDrawableType = LLPipeline::RENDER_TYPE_TREE;  	mPartitionType = LLViewerRegion::PARTITION_TREE; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8730ef66bb..126055c8fb 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -406,7 +406,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,  				dp->dumpBufferToLog();  				llwarns << "Flushing cache files" << llendl; -				if(LLVOCache::hasInstance() && getRegion()) +				if(LLVOCache::instanceExists() && getRegion())  				{  					LLVOCache::getInstance()->removeEntry(getRegion()->getHandle()) ;  				} @@ -1143,7 +1143,7 @@ void LLVOVolume::sculpt()  			{	// Log first time, then every 100 afterwards otherwise this can flood the logs  				llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()   					<< " at " << current_discard  -					<< " is less than -2." << llendl; +				<< " is less than -2." << llendl;  				low_sculpty_discard_warning_count = 0;  			} @@ -1157,7 +1157,7 @@ void LLVOVolume::sculpt()  			{	// Log first time, then every 100 afterwards otherwise this can flood the logs  				llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()   					<< " at " << current_discard  -					<< " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl; +				<< " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl;  				high_sculpty_discard_warning_count = 0;  			} @@ -3945,8 +3945,8 @@ U32 LLVOVolume::getPartitionType() const  	return LLViewerRegion::PARTITION_VOLUME;  } -LLVolumePartition::LLVolumePartition() -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) +LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp)  {  	mLODPeriod = 32;  	mDepthMask = FALSE; @@ -3956,8 +3956,8 @@ LLVolumePartition::LLVolumePartition()  	mBufferUsage = GL_DYNAMIC_DRAW_ARB;  } -LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) -: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK) +LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp) +: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK, regionp)  {  	mDepthMask = FALSE;  	mLODPeriod = 32; @@ -4175,9 +4175,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	group->mLastUpdateViewAngle = group->mViewAngle; -	if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY)) +	if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))  	{ -		if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate) +		if (group->hasState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)  		{  			rebuildMesh(group);  		} @@ -4190,7 +4190,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	LLVOAvatar* pAvatarVO = NULL; -	LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); +	LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();  	if (bridge)  	{  		if (bridge->mAvatar.isNull()) @@ -4215,7 +4215,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	group->mSurfaceArea = 0;  	//cache object box size since it might be used for determining visibility -	group->mObjectBoxSize = group->mObjectBounds[1].getLength3().getF32(); +	const LLVector4a* bounds = group->getObjectBounds(); +	group->mObjectBoxSize = bounds[1].getLength3().getF32();  	group->clearDrawMap(); @@ -4226,10 +4227,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	std::vector<LLFace*> simple_faces;  	std::vector<LLFace*> alpha_faces; -	U32 useage = group->mSpatialPartition->mBufferUsage; +	U32 useage = group->getSpatialPartition()->mBufferUsage; -	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); -	U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); +	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); +	U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);  	max_vertices = llmin(max_vertices, (U32) 65535);  	U32 cur_total = 0; @@ -4242,9 +4243,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		//get all the faces into a list  		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  		{ -			LLDrawable* drawablep = *drawable_iter; +			LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); -			if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) +			if (!drawablep || drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )  			{  				continue;  			} @@ -4648,10 +4649,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		//drawables have been rebuilt, clear rebuild status  		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  		{ -			LLDrawable* drawablep = *drawable_iter; +			LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); +			if(drawablep) +			{  			drawablep->clearState(LLDrawable::REBUILD_ALL);  		}  	} +	}  	group->mLastUpdateTime = gFrameTimeSeconds;  	group->mBuilt = 1.f; @@ -4675,7 +4679,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  {  	llassert(group); -	if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) +	if (group && group->hasState(LLSpatialGroup::MESH_DIRTY) && !group->hasState(LLSpatialGroup::GEOM_DIRTY))  	{  		LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);  		LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers @@ -4688,9 +4692,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  		{ -			LLDrawable* drawablep = *drawable_iter; +			LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); -			if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) +			if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )  			{  				LLVOVolume* vobj = drawablep->getVOVolume();  				vobj->preRebuild(); @@ -4756,7 +4760,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  			llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;   			for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  			{ -				LLDrawable* drawablep = *drawable_iter; +				LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); +				if(!drawablep) +				{ +					continue; +				}  				for (S32 i = 0; i < drawablep->getNumFaces(); ++i)  				{  					LLFace* face = drawablep->getFace(i); @@ -4829,7 +4837,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  #endif  	//calculate maximum number of vertices to store in a single buffer -	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); +	U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);  	max_vertices = llmin(max_vertices, (U32) 65535);  	{ @@ -5220,7 +5228,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)  {	  	//initialize to default usage for this partition -	U32 usage = group->mSpatialPartition->mBufferUsage; +	U32 usage = group->getSpatialPartition()->mBufferUsage;  	//clear off any old faces  	mFaceList.clear(); @@ -5229,9 +5237,9 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun  	for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)  	{ -		LLDrawable* drawablep = *drawable_iter; +		LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); -		if (drawablep->isDead()) +		if (!drawablep || drawablep->isDead())  		{  			continue;  		} @@ -5269,7 +5277,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun  	group->mBufferUsage = usage;  } -LLHUDPartition::LLHUDPartition() +LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp)  {  	mPartitionType = LLViewerRegion::PARTITION_HUD;  	mDrawableType = LLPipeline::RENDER_TYPE_HUD; diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index e8a1c3d1d6..50e7ed7bb5 100755 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -298,15 +298,15 @@ U32 LLVOVoidWater::getPartitionType() const  	return LLViewerRegion::PARTITION_VOIDWATER;  } -LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) +LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)  {  	mInfiniteFarClip = TRUE;  	mDrawableType = LLPipeline::RENDER_TYPE_WATER;  	mPartitionType = LLViewerRegion::PARTITION_WATER;  } -LLVoidWaterPartition::LLVoidWaterPartition() +LLVoidWaterPartition::LLVoidWaterPartition(LLViewerRegion* regionp) : LLWaterPartition(regionp)  {  	mOcclusionEnabled = FALSE;  	mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER; diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 4e26587184..0f2f49a975 100755 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -394,7 +394,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)  			segment->flush();  		} -		llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32()) << "seconds" << llendl; +		llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32().value()) << "seconds" << llendl;  	}  #else  	mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index 4f582fc2db..c852f1869b 100755 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -27,6 +27,7 @@  #include "llviewerprecompiledheaders.h"  #include "llwatchdog.h" +#include "llthread.h"  const U32 WATCHDOG_SLEEP_TIME_USEC = 1000000; diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index ef1a953f59..79c2778253 100755 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -148,7 +148,6 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID  		{  			LLFile::remove(std::string(filename));  		} -		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );  		LL_WARNS("Wearable") << "Wearable download failed: " << LLAssetStorage::getErrorString( status ) << " " << uuid << LL_ENDL;  		switch( status ) diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h index 3837825d31..6f274c6f16 100755 --- a/indra/newview/llwindebug.h +++ b/indra/newview/llwindebug.h @@ -28,6 +28,7 @@  #define LL_LLWINDEBUG_H  #include "stdtypes.h" +#include "llwin32headerslean.h"  #include <dbghelp.h>  class LLWinDebug: diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 793becf0c8..42a0be9e2f 100755 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -55,7 +55,7 @@  #include "message.h"  #include "pipeline.h"  #include "llappviewer.h"		// for do_disconnect() - +#include "llscenemonitor.h"  #include <deque>  #include <queue>  #include <map> @@ -110,6 +110,7 @@ LLWorld::LLWorld() :  	gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);  	mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); +	LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled") && gSavedSettings.getBOOL("ObjectCacheEnabled");  } @@ -122,10 +123,7 @@ void LLWorld::destroyClass()  		LLViewerRegion* region_to_delete = *region_it++;  		removeRegion(region_to_delete->getHost());  	} -	if(LLVOCache::hasInstance()) -	{ -		LLVOCache::getInstance()->destroyClass() ; -	} +	  	LLViewerPartSim::getInstance()->destroyClass();  	mDefaultWaterTexturep = NULL ; @@ -133,6 +131,11 @@ void LLWorld::destroyClass()  	{  		mEdgeWaterObjects[i] = NULL;  	} + +	//make all visible drawbles invisible. +	LLDrawable::incrementVisible(); + +	LLSceneMonitor::deleteSingleton();  } @@ -599,7 +602,8 @@ void LLWorld::updateVisibilities()  		if (part)  		{  			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); -			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1])) +			const LLVector4a* bounds = group->getBounds(); +			if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1]))  			{  				mCulledRegionList.erase(curiter);  				mVisibleRegionList.push_back(regionp); @@ -622,7 +626,8 @@ void LLWorld::updateVisibilities()  		if (part)  		{  			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); -			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1])) +			const LLVector4a* bounds = group->getBounds(); +			if (LLViewerCamera::getInstance()->AABBInFrustum(bounds[0], bounds[1]))  			{  				regionp->calculateCameraDistance();  				regionp->getLand().updatePatchVisibilities(gAgent); @@ -660,6 +665,13 @@ void LLWorld::updateRegions(F32 max_update_time)  			did_one = TRUE;  		}  	} + +	mNumOfActiveCachedObjects = 0; +	for (region_list_t::iterator iter = mRegionList.begin(); +		 iter != mRegionList.end(); ++iter) +	{ +		mNumOfActiveCachedObjects += (*iter)->getNumOfActiveCachedObjects(); +	}  }  void LLWorld::updateParticles() @@ -692,8 +704,10 @@ void LLWorld::updateNetStats()  	{  		LLViewerRegion* regionp = *iter;  		regionp->updateNetStats(); -		bits += regionp->mBitStat.getCurrent(); -		packets += llfloor( regionp->mPacketsStat.getCurrent() ); +		bits += regionp->mBitsReceived; +		packets += llfloor( regionp->mPacketsReceived ); +		regionp->mBitsReceived = 0.f; +		regionp->mPacketsReceived = 0.f;  	}  	S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn; @@ -702,19 +716,17 @@ void LLWorld::updateNetStats()  	S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits();  	S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits(); -	LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f); -	LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f); -	LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f); -	LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in); -	LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out); -	LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets); + +	add(LLStatViewer::ACTUAL_IN_KBIT, LLTrace::Bits(actual_in_bits)); +	add(LLStatViewer::ACTUAL_OUT_KBIT, LLTrace::Bits(actual_out_bits)); +	add(LLStatViewer::KBIT, LLTrace::Bits(bits)); +	add(LLStatViewer::PACKETS_IN, packets_in); +	add(LLStatViewer::PACKETS_OUT, packets_out); +	add(LLStatViewer::PACKETS_LOST, packets_lost);  	if (packets_in)  	{ -		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in)); -	} -	else -	{ -		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f); +		F32 packet_loss = 100.f * ((F32)packets_lost/(F32)packets_in); +		sample(LLStatViewer::PACKETS_LOST_PERCENT, packet_loss);  	}  	mLastPacketsIn = gMessageSystem->mPacketsIn; @@ -1127,6 +1139,7 @@ void send_agent_pause()  	}  	gObjectList.mWasPaused = TRUE; +	LLViewerStats::instance().getRecording().stop();  } @@ -1156,8 +1169,8 @@ void send_agent_resume()  		gMessageSystem->sendReliable(regionp->getHost());  	} -	// Reset the FPS counter to avoid an invalid fps -	LLViewerStats::getInstance()->mFPSStat.start(); +	// Resume data collection to ignore invalid rates +	LLViewerStats::instance().getRecording().resume();  	LLAppViewer::instance()->resumeMainloopTimeout();  } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index f350009d10..8187142b2b 100755 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -144,6 +144,7 @@ public:  	U64 getSpaceTimeUSec() const;  	void getInfo(LLSD& info); +	U32  getNumOfActiveCachedObjects() const {return mNumOfActiveCachedObjects;}  public:  	typedef std::list<LLViewerRegion*> region_list_t; @@ -181,7 +182,7 @@ private:  	S32 mLastPacketsIn;  	S32 mLastPacketsOut;  	S32 mLastPacketsLost; - +	U32 mNumOfActiveCachedObjects;  	U64 mSpaceTimeUSec;  	BOOL mClassicCloudsEnabled; diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h index 12b6ef4792..ac1ea1607c 100755 --- a/indra/newview/llworldmapmessage.h +++ b/indra/newview/llworldmapmessage.h @@ -27,6 +27,8 @@  #ifndef LL_LLWORLDMAPMESSAGE_H  #define LL_LLWORLDMAPMESSAGE_H +#include "boost/function.hpp" +  // Handling of messages (send and process) as well as SLURL callback if necessary  class LLMessageSystem; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 1940cf541e..6759328b84 100755 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -302,8 +302,8 @@ void LLWorldMapView::draw()  	mVisibleRegions.clear();  	// animate pan if necessary -	sPanX = lerp(sPanX, sTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); -	sPanY = lerp(sPanY, sTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); +	sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f)); +	sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f));  	const S32 width = getRect().getWidth();  	const S32 height = getRect().getHeight(); diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 0da70d398b..583196fb7a 100755 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -25,6 +25,8 @@   */  #include "llviewerprecompiledheaders.h" +// include this to get winsock2 because openssl attempts to include winsock1 +#include "llwin32headerslean.h"  #include <openssl/x509_vfy.h>  #include <openssl/ssl.h>  #include "llsecapi.h" diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7eed9acb4b..dd5c153d55 100755 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -87,6 +87,7 @@  #include "llviewerregion.h" // for audio debugging.  #include "llviewerwindow.h" // For getSpinAxis  #include "llvoavatarself.h" +#include "llvocache.h"  #include "llvoground.h"  #include "llvosky.h"  #include "llvotree.h" @@ -112,6 +113,7 @@  #include "llfloaterpathfindingconsole.h"  #include "llfloaterpathfindingcharacters.h"  #include "llpathfindingpathtool.h" +#include "llscenemonitor.h"  #ifdef _DEBUG  // Debug indices is disabled for now for debug performance - djs 4/24/02 @@ -197,6 +199,7 @@ BOOL LLPipeline::CameraOffset;  F32 LLPipeline::CameraMaxCoF;  F32 LLPipeline::CameraDoFResScale;  F32 LLPipeline::RenderAutoHideSurfaceAreaLimit; +LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");  const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;  const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f; @@ -404,17 +407,9 @@ bool addDeferredAttachments(LLRenderTarget& target)  LLPipeline::LLPipeline() :  	mBackfaceCull(FALSE), -	mBatchCount(0),  	mMatrixOpCount(0),  	mTextureMatrixOps(0), -	mMaxBatchSize(0), -	mMinBatchSize(0), -	mMeanBatchSize(0), -	mTrianglesDrawn(0),  	mNumVisibleNodes(0), -	mVerticesRelit(0), -	mLightingChanges(0), -	mGeometryChanges(0),  	mNumVisibleFaces(0),  	mInitialized(FALSE), @@ -491,7 +486,6 @@ void LLPipeline::init()  	getPool(LLDrawPool::POOL_BUMP);  	getPool(LLDrawPool::POOL_GLOW); -	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();  	resetFrameStats();  	if (gSavedSettings.getBOOL("DisableAllRenderFeatures")) @@ -1433,18 +1427,18 @@ S32 LLPipeline::setLightingDetail(S32 level)  	return mLightingDetail;  } -class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable> +class LLOctreeDirtyTexture : public OctreeTraveler  {  public:  	const std::set<LLViewerFetchedTexture*>& mTextures;  	LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { } -	virtual void visit(const LLOctreeNode<LLDrawable>* node) +	virtual void visit(const OctreeNode* node)  	{  		LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); -		if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty()) +		if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())  		{  			for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)  			{ @@ -1633,11 +1627,9 @@ void LLPipeline::addPool(LLDrawPool *new_poolp)  void LLPipeline::allocDrawable(LLViewerObject *vobj)  { -	LLDrawable *drawable = new LLDrawable(); +	LLDrawable *drawable = new LLDrawable(vobj);  	vobj->mDrawable = drawable; -	drawable->mVObjp     = vobj; -	  	//encompass completely sheared objects by taking   	//the most extreme point possible (<1,1,0.5>)  	drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length()); @@ -1677,7 +1669,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)  	if (drawablep->getSpatialGroup())  	{  		LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION); -		if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup())) +		if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup()))  		{  #ifdef LL_RELEASE_FOR_DOWNLOAD  			llwarns << "Couldn't remove object from spatial group!" << llendl; @@ -1823,17 +1815,7 @@ void LLPipeline::resetFrameStats()  {  	assertInitialized(); -	LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); - -	if (mBatchCount > 0) -	{ -		mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount; -	} -	mTrianglesDrawn = 0;  	sCompiles        = 0; -	mVerticesRelit   = 0; -	mLightingChanges = 0; -	mGeometryChanges = 0;  	mNumVisibleFaces = 0;  	if (mOldRenderDebugMask != mRenderDebugMask) @@ -1841,7 +1823,6 @@ void LLPipeline::resetFrameStats()  		gObjectList.clearDebugText();  		mOldRenderDebugMask = mRenderDebugMask;  	} -		  }  //external functions for asynchronous updating @@ -1942,6 +1923,8 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)  static LLFastTimer::DeclareTimer FTM_OCTREE_BALANCE("Balance Octree");  static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move"); +static LLFastTimer::DeclareTimer FTM_RETEXTURE("Retexture"); +static LLFastTimer::DeclareTimer FTM_MOVED_LIST("Moved List");  void LLPipeline::updateMove()  { @@ -1955,8 +1938,7 @@ void LLPipeline::updateMove()  	assertInitialized();  	{ -		static LLFastTimer::DeclareTimer ftm("Retexture"); -		LLFastTimer t(ftm); +		LLFastTimer t(FTM_RETEXTURE);  		for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();  			 iter != mRetexturedList.end(); ++iter) @@ -1971,8 +1953,7 @@ void LLPipeline::updateMove()  	}  	{ -		static LLFastTimer::DeclareTimer ftm("Moved List"); -		LLFastTimer t(ftm); +		LLFastTimer t(FTM_MOVED_LIST);  		updateMovedList(mMovedList);  	} @@ -2061,7 +2042,7 @@ void check_references(LLSpatialGroup* group, LLDrawable* drawable)  {  	for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{ -		if (drawable == *i) +		if (drawable == (LLDrawable*)(*i)->getDrawable())  		{  			llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl;  		} @@ -2083,10 +2064,13 @@ void check_references(LLSpatialGroup* group, LLFace* face)  {  	for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  	{ -		LLDrawable* drawable = *i; +		LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable(); +		if(drawable) +		{  		check_references(drawable, face);  	}			  } +}  void LLPipeline::checkReferences(LLFace* face)  { @@ -2263,7 +2247,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&  	min = LLVector3(X,X,X);  	max = LLVector3(-X,-X,-X); -	U32 saved_camera_id = LLViewerCamera::sCurCameraID; +	LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID;  	LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;  	BOOL res = TRUE; @@ -2408,6 +2392,13 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl  				}  			}  		} + +		//scan the VO Cache tree +		LLVOCachePartition* vo_part = region->getVOCachePartition(); +		if(vo_part) +		{ +			vo_part->cull(camera); +		}  	}  	if (bound_shader) @@ -2475,15 +2466,16 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)  		return;  	} +	const LLVector4a* bounds = group->getBounds();  	if (sMinRenderSize > 0.f &&  -			llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize) +			llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize)  	{  		return;  	}  	assertInitialized(); -	if (!group->mSpatialPartition->mRenderByGroup) +	if (!group->getSpatialPartition()->mRenderByGroup)  	{ //render by drawable  		sCull->pushDrawableGroup(group);  	} @@ -2588,7 +2580,6 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)  	if (update_complete && assertInitialized())  	{  		drawablep->setState(LLDrawable::BUILT); -		mGeometryChanges++;  	}  	return update_complete;  } @@ -2732,7 +2723,7 @@ void LLPipeline::rebuildGroups()  		{  			group->rebuildGeom(); -			if (group->mSpatialPartition->mRenderByGroup) +			if (group->getSpatialPartition()->mRenderByGroup)  			{  				count++;  			} @@ -2801,7 +2792,7 @@ void LLPipeline::updateGeom(F32 max_dtime)  	S32 count = 0; -	max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime); +	max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, LLUnitImplicit<LLUnits::Seconds, F32>(max_dtime));  	LLSpatialGroup* last_group = NULL;  	LLSpatialBridge* last_bridge = NULL; @@ -3055,23 +3046,23 @@ void LLPipeline::markMeshDirty(LLSpatialGroup* group)  void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)  { -	if (group && !group->isDead() && group->mSpatialPartition) +	if (group && !group->isDead() && group->getSpatialPartition())  	{ -		if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD) +		if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD)  		{  			priority = TRUE;  		}  		if (priority)  		{ -			if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) +			if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1))  			{  				llassert_always(!mGroupQ1Locked);  				mGroupQ1.push_back(group);  				group->setState(LLSpatialGroup::IN_BUILD_Q1); -				if (group->isState(LLSpatialGroup::IN_BUILD_Q2)) +				if (group->hasState(LLSpatialGroup::IN_BUILD_Q2))  				{  					LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group);  					if (iter != mGroupQ2.end()) @@ -3082,7 +3073,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)  				}  			}  		} -		else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) +		else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))  		{  			llassert_always(!mGroupQ2Locked);  			mGroupQ2.push_back(group); @@ -3157,7 +3148,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  			group->setVisible();  			for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  			{ -				markVisible(*i, camera); +				markVisible((LLDrawable*)(*i)->getDrawable(), camera);  			}  			if (!sDelayVBUpdate) @@ -3244,8 +3235,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)  	{  		for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)  		{ -			LLDrawable* drawablep = *i; -			stateSort(drawablep, camera); +			stateSort((LLDrawable*)(*i)->getDrawable(), camera);  		}  		if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) @@ -3346,7 +3336,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)  		}  	} -  	mNumVisibleFaces += drawablep->getNumFaces();  } @@ -3359,7 +3348,10 @@ void forAllDrawables(LLCullResult::sg_iterator begin,  	{  		for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)  		{ -			func(*j);	 +			if((*j)->hasDrawable()) +			{ +				func((LLDrawable*)(*j)->getDrawable());	 +			}  		}  	}  } @@ -3587,7 +3579,7 @@ void LLPipeline::postSort(LLCamera& camera)  			continue;  		} -		if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY)) +		if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY))  		{ //no way this group is going to be drawable without a rebuild  			group->rebuildGeom();  		} @@ -3625,7 +3617,7 @@ void LLPipeline::postSort(LLCamera& camera)  			if (alpha != group->mDrawMap.end())  			{ //store alpha groups for sorting -				LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); +				LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();  				if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)  				{  					if (bridge) @@ -3769,33 +3761,6 @@ void LLPipeline::postSort(LLCamera& camera)  		}  	} -	/*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence"); -	static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work"); -	if (use_transform_feedback) -	{ //using transform feedback, wait for transform feedback to complete -		LLFastTimer t(FTM_TRANSFORM_WAIT); - -		S32 done = 0; -		//glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count); -		 -		glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); -		 -		while (!done) -		{  -			{ -				LLFastTimer t(FTM_TRANSFORM_DO_WORK); -				F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f); -				//do some useful work while we wait -				LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread -				LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread -				LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread -			} -			glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done); -		} - -		mTransformFeedbackPrimitives = 0; -	}*/ -						  	//LLSpatialGroup::sNoDelete = FALSE;  	llpushcallstacks ;  } @@ -4539,10 +4504,8 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type)  		count = index_count/3;  	} -	mTrianglesDrawn += count; -	mBatchCount++; -	mMaxBatchSize = llmax(mMaxBatchSize, count); -	mMinBatchSize = llmin(mMinBatchSize, count); +	record(sStatBatchSize, count); +	add(LLStatViewer::TRIANGLES_DRAWN, count);  	if (LLPipeline::sRenderFrameTest)  	{ @@ -4971,7 +4934,7 @@ void LLPipeline::renderDebug()  		{  			DebugBlip& blip = *iter; -			blip.mAge += gFrameIntervalSeconds; +			blip.mAge += gFrameIntervalSeconds.value();  			if (blip.mAge > 2.f)  			{  				mDebugBlips.erase(iter++); @@ -4981,7 +4944,7 @@ void LLPipeline::renderDebug()  				iter++;  			} -			blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f; +			blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f;  			gGL.color4fv(blip.mColor.mV);  			gGL.vertex3fv(blip.mPosition.mV); @@ -5223,7 +5186,7 @@ void LLPipeline::renderDebug()  				continue;  			} -			LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); +			LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();  			if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead()))  			{ @@ -5787,7 +5750,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)  				{  					if (farthest_light->fade >= 0.f)  					{ -						farthest_light->fade = -gFrameIntervalSeconds; +						farthest_light->fade = -(gFrameIntervalSeconds.value());  					}  				}  				else @@ -5883,12 +5846,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  				if (fade >= 0.f)  				{  					fade = fade / LIGHT_FADE_TIME; -					((Light*) (&(*iter)))->fade += gFrameIntervalSeconds; +					((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value();  				}  				else  				{  					fade = 1.f + fade / LIGHT_FADE_TIME; -					((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds; +					((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value();  				}  				fade = llclamp(fade,0.f,1.f);  				light_color *= fade; @@ -6828,7 +6791,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)  }  void LLPipeline::resetVertexBuffers() -{	 +{  	mResetVertexBuffers = true;  } @@ -7218,7 +7181,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  			}  			else if (transition_time < 1.f)  			{ //currently in a transition, continue interpolating -				transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds; +				transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value();  				transition_time = llmin(transition_time, 1.f);  				F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; @@ -9207,7 +9170,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)  	if (!mHighlightSet.empty())  	{ -		F32 transition = gFrameIntervalSeconds/RenderHighlightFadeTime; +		F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime;  		LLGLDisable test(GL_ALPHA_TEST);  		LLGLDepthTest depth(GL_FALSE); @@ -9465,7 +9428,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  				mShadowFrustPoints[j].clear();  			} -			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j; +			LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);  			//restore render matrices  			glh_set_current_modelview(saved_view); @@ -9842,12 +9805,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	if (gen_shadow)  	{ -		F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); +		LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat(); +		F32 fade_amt = gFrameIntervalSeconds.value()  +			* llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);  		//update shadow targets  		for (U32 i = 0; i < 2; i++)  		{ //for each current shadow -			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; +			LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);  			if (mShadowSpotLight[i].notNull() &&   				(mShadowSpotLight[i] == mTargetShadowSpotLight[0] || @@ -9966,7 +9931,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  			static LLCullResult result[2]; -			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; +			LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);  			renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); @@ -10016,7 +9981,7 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu  		LLSpatialGroup* group = *i;  		if (!group->isDead() &&  			(!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && -			gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && +			gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) &&  			group->mDrawMap.find(type) != group->mDrawMap.end())  		{  			pass->renderGroup(group,type,mask,texture); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a8db93585e..530d484dbd 100755 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -29,8 +29,6 @@  #include "llcamera.h"  #include "llerror.h" -#include "lldarrayptr.h" -#include "lldqueueptr.h"  #include "lldrawpool.h"  #include "llspatialpartition.h"  #include "m4math.h" @@ -42,25 +40,13 @@  #include <stack> -#include <stack> - -#include <stack> -  class LLViewerTexture; -class LLEdge;  class LLFace;  class LLViewerObject; -class LLAgent; -class LLDisplayPrimitive;  class LLTextureEntry; -class LLRenderFunc; -class LLCubeMap;  class LLCullResult;  class LLVOAvatar;  class LLGLSLShader; -class LLCurlRequest; - -class LLMeshResponder;  typedef enum e_avatar_skinning_method  { @@ -514,23 +500,14 @@ public:  	LLQuaternion			mFlyCamRotation;  	BOOL					 mBackfaceCull; -	S32						 mBatchCount;  	S32						 mMatrixOpCount;  	S32						 mTextureMatrixOps; -	S32						 mMaxBatchSize; -	S32						 mMinBatchSize; -	S32						 mMeanBatchSize; -	S32						 mTrianglesDrawn;  	S32						 mNumVisibleNodes; -	S32						 mVerticesRelit;  	S32						 mDebugTextureUploadCost;  	S32						 mDebugSculptUploadCost;  	S32						 mDebugMeshUploadCost; -	S32						 mLightingChanges; -	S32						 mGeometryChanges; -  	S32						 mNumVisibleFaces;  	static S32				sCompiles; @@ -564,6 +541,8 @@ public:  	static S32				sVisibleLightCount;  	static F32				sMinRenderSize;	 +	static LLTrace::EventStatHandle<S64> sStatBatchSize; +  	//screen texture  	U32 					mScreenWidth;  	U32 					mScreenHeight; diff --git a/indra/newview/skins/default/xui/da/floater_lagmeter.xml b/indra/newview/skins/default/xui/da/floater_lagmeter.xml deleted file mode 100755 index 149d174c34..0000000000 --- a/indra/newview/skins/default/xui/da/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="LAG METER"> -	<floater.string name="max_title_msg"> -		Lag måler -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		Lag -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		Klient -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		Normal, vindue i baggrund -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		Klients billeder/sek under [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		Klients billeder/sek mellem [CLIENT_FRAME_RATE_CRITICAL] og [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Mulig årsag: 'Vis afstand' sat for højt i grafik indstillinger -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Mulig årsag: Billeder hentes -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Mulig årsag: For mange billeder i hukommelse -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Mulig årsag: For mange komplekse objekter i scenariet -	</floater.string> -	<floater.string name="network_text_msg"> -		Netværk -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		Forbindelsen mister over [NETWORK_PACKET_LOSS_CRITICAL]% pakker -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		Forbindelsen mister [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% pakker -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		Forbindelsens ping tider er over [NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		Forbindelsens ping tider er [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Muligvis dårlig forbindelse eller 'båndbredde' sat for højt i netværksopsætning. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Muligvis dårlig forbindelse eller fil delings program. -	</floater.string> -	<floater.string name="server_text_msg"> -		Server -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Simulator framerate er under [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Simulator framerate er mellem [SERVER_FRAME_RATE_CRITICAL] og [SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Mulig årsag: For mange fysiske objekter -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Mulig årsag: For mange objekter med script -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Mulig årsag: For meget netværks trafik -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Mulig årsag: For mange avatarer i bevægelse i regionen -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Mulig årsag: For mange billed udregninger -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Mulig årsag: Simulator belastning for stor -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button label="" label_selected="" name="client_lagmeter" tool_tip="Status for klient lag"/> -	<text name="client"> -		Klient -	</text> -	<text name="client_text"> -		Normal -	</text> -	<button label="" label_selected="" name="network_lagmeter" tool_tip="Network lag status"/> -	<text name="network"> -		Netværk -	</text> -	<text name="network_text"> -		Normal -	</text> -	<button label="" label_selected="" name="server_lagmeter" tool_tip="Status for server lag"/> -	<text name="server"> -		Server -	</text> -	<text name="server_text"> -		Normal -	</text> -	<button label=">>" name="minimize" tool_tip="Ændre størrelse"/> -</floater> diff --git a/indra/newview/skins/default/xui/de/floater_lagmeter.xml b/indra/newview/skins/default/xui/de/floater_lagmeter.xml deleted file mode 100755 index 45ff37c147..0000000000 --- a/indra/newview/skins/default/xui/de/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="LAG METER"> -	<floater.string name="max_title_msg"> -		Lag-Anzeige -	</floater.string> -	<floater.string name="max_width_px"> -		350 -	</floater.string> -	<floater.string name="min_title_msg"> -		Lag -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		Client -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		Normal, Fenster im Hintergrund -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		Client-Frame-Rate unter [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		Client-Frame-Rate zwischen [CLIENT_FRAME_RATE_CRITICAL] und [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Mögliche Ursache: Sichtweite zu groß -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Mögliche Ursache: Bilder werden geladen -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Mögliche Ursache: Zu viele Bilder im Speicher -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Mögliche Ursache: Zu viele komplexe Objekte in der Szene -	</floater.string> -	<floater.string name="network_text_msg"> -		Netzwerk -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		Paketverlust der Verbindung übersteigt [NETWORK_PACKET_LOSS_CRITICAL]% -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		Paketverlust der Verbindung liegt bei [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		Ping-Zeit der Verbindung übersteigt [NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		Ping-Zeit der Verbindung liegt bei [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Möglicherweise schlechte Verbindung oder zu hoher Wert für „Bandbreite“. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Möglicherweise schlechte Verbindung oder File-Sharing-Anwendung. -	</floater.string> -	<floater.string name="server_text_msg"> -		Server -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Simulator-Frame-Rate liegt unter [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Simulator-Frame-Rate liegt zwischen [SERVER_FRAME_RATE_CRITICAL] und [SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Mögliche Ursache: Zu viele physische Objekte -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Mögliche Ursache: Zu viele geskriptete Objekte -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Mögliche Ursache: Zu viel Netzwerktraffic -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Mögliche Ursache: Zu viele Personen in Bewegung in der Region -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Mögliche Ursache: Zu viele Bildberechnungen -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Mögliche Ursache: Zu hohe Simulator-Last -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button name="client_lagmeter" tool_tip="Client-Lag-Status"/> -	<text name="client"> -		Client -	</text> -	<text name="client_text"> -		Normal -	</text> -	<button name="network_lagmeter" tool_tip="Netzwerk-Lag-Status"/> -	<text name="network"> -		Netzwerk -	</text> -	<text name="network_text"> -		Normal -	</text> -	<button name="server_lagmeter" tool_tip="Server-Lag-Status"/> -	<text name="server"> -		Server -	</text> -	<text name="server_text"> -		Normal -	</text> -	<button label=">> " name="minimize" tool_tip="Fenstergröße ändern"/> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_lagmeter.xml b/indra/newview/skins/default/xui/en/floater_lagmeter.xml deleted file mode 100755 index b24c745bdd..0000000000 --- a/indra/newview/skins/default/xui/en/floater_lagmeter.xml +++ /dev/null @@ -1,336 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - legacy_header_height="18" - height="170" - layout="topleft" - name="floater_lagmeter" - help_topic="floater_lagmeter" - save_rect="true" - title="LAG METER" - width="350"> -    <floater.string -     name="max_title_msg"> -        Lag Meter -    </floater.string> -    <floater.string -     name="max_width_px"> -        360 -    </floater.string> -    <floater.string -     name="min_title_msg"> -        Lag -    </floater.string> -    <floater.string -     name="min_width_px"> -        90 -    </floater.string> -    <floater.string -     name="client_text_msg"> -        Client -    </floater.string> -    <floater.string -     name="client_frame_rate_critical_fps"> -        10 -    </floater.string> -    <floater.string -     name="client_frame_rate_warning_fps"> -        15 -    </floater.string> -    <floater.string -     name="client_frame_time_window_bg_msg"> -        Normal, window in background -    </floater.string> -    <floater.string -     name="client_frame_time_critical_msg"> -        Client frame rate below [CLIENT_FRAME_RATE_CRITICAL] -    </floater.string> -    <floater.string -     name="client_frame_time_warning_msg"> -        Client frame rate between [CLIENT_FRAME_RATE_CRITICAL] and [CLIENT_FRAME_RATE_WARNING] -    </floater.string> -    <floater.string -     name="client_frame_time_normal_msg"> -        Normal -    </floater.string> -    <floater.string -     name="client_draw_distance_cause_msg"> -        Possible cause: Draw distance set too high -    </floater.string> -    <floater.string -     name="client_texture_loading_cause_msg"> -        Possible cause: Images loading -    </floater.string> -    <floater.string -     name="client_texture_memory_cause_msg"> -        Possible cause: Too many images in memory -    </floater.string> -    <floater.string -     name="client_complex_objects_cause_msg"> -        Possible cause: Too many complex objects in scene -    </floater.string> -    <floater.string -     name="network_text_msg"> -        Network -    </floater.string> -    <floater.string -     name="network_packet_loss_critical_pct"> -        10 -    </floater.string> -    <floater.string -     name="network_packet_loss_warning_pct"> -        5 -    </floater.string> -    <floater.string -     name="network_packet_loss_critical_msg"> -        Connection is dropping over [NETWORK_PACKET_LOSS_CRITICAL]% of packets -    </floater.string> -    <floater.string -     name="network_packet_loss_warning_msg"> -        Connection is dropping [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% of packets -    </floater.string> -    <floater.string -     name="network_performance_normal_msg"> -        Normal -    </floater.string> -    <floater.string -     name="network_ping_critical_ms"> -        600 -    </floater.string> -    <floater.string -     name="network_ping_warning_ms"> -        300 -    </floater.string> -    <floater.string -     name="network_ping_critical_msg"> -        Connection ping time is over [NETWORK_PING_CRITICAL] ms -    </floater.string> -    <floater.string -     name="network_ping_warning_msg"> -        Connection ping time is [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms -    </floater.string> -    <floater.string -     name="network_packet_loss_cause_msg"> -        Possible bad connection or 'Bandwidth' pref too high. -    </floater.string> -    <floater.string -     name="network_ping_cause_msg"> -        Possible bad connection or file-sharing app. -    </floater.string> -    <floater.string -     name="server_text_msg"> -        Server -    </floater.string> -    <floater.string -     name="server_frame_rate_critical_fps"> -        20 -    </floater.string> -    <floater.string -     name="server_frame_rate_warning_fps"> -        30 -    </floater.string> -    <floater.string -     name="server_single_process_max_time_ms"> -        20 -    </floater.string> -    <floater.string -     name="server_frame_time_critical_msg"> -        Simulator framerate below [SERVER_FRAME_RATE_CRITICAL] -    </floater.string> -    <floater.string -     name="server_frame_time_warning_msg"> -        Simulator framerate between [SERVER_FRAME_RATE_CRITICAL] and [SERVER_FRAME_RATE_WARNING] -    </floater.string> -    <floater.string -     name="server_frame_time_normal_msg"> -        Normal -    </floater.string> -    <floater.string -     name="server_physics_cause_msg"> -        Possible Cause: Too many physical objects -    </floater.string> -    <floater.string -     name="server_scripts_cause_msg"> -        Possible Cause: Too many scripted objects -    </floater.string> -    <floater.string -     name="server_net_cause_msg"> -        Possible Cause: Too much network traffic -    </floater.string> -    <floater.string -     name="server_agent_cause_msg"> -        Possible Cause: Too many moving people in region -    </floater.string> -    <floater.string -     name="server_images_cause_msg"> -        Possible Cause: Too many image calculations -    </floater.string> -    <floater.string -     name="server_generic_cause_msg"> -        Possible Cause: Simulator load too heavy -    </floater.string> -    <floater.string -     name="smaller_label"> -        >> -    </floater.string> -    <floater.string -     name="bigger_label"> -        << -    </floater.string> -    <button -     follows="top|left" -     height="16" -     image_selected="lag_status_good.tga" -     image_unselected="lag_status_good.tga" -     layout="topleft" -     left="8" -     name="client_lagmeter" -     tab_stop="false" -     tool_tip="Client lag status" -     top="24" -     width="16" /> -    <text -     type="string" -     length="1" -     follows="left|top" -     font="SansSerif" -     height="16" -     layout="topleft" -     left_pad="3" -     name="client" -     top_delta="0" -     width="128"> -        Client -    </text> -    <text -     invisiblity_control="LagMeterShrunk" -     type="string" -     length="1" -     bottom="40" -     follows="left|top" -     font="SansSerif" -     height="16" -     layout="topleft" -     left="110" -     name="client_text" -     right="-10"> -        Normal -    </text> -    <text -     invisiblity_control="LagMeterShrunk" -     bottom="56" -     follows="left|top" -     height="16" -     layout="topleft" -     left="40" -     name="client_lag_cause" -     right="-32" /> -    <button -     follows="top|left" -     height="16" -     image_selected="lag_status_good.tga" -     image_unselected="lag_status_good.tga" -     layout="topleft" -     left="8" -     name="network_lagmeter" -     tab_stop="false" -     tool_tip="Network lag status" -     top="64" -     width="16" /> -    <text -     type="string" -     length="1" -     follows="left|top" -     font="SansSerif" -     height="16" -     layout="topleft" -     left_pad="3" -     name="network" -     top_delta="0" -     width="128"> -        Network -    </text> -    <text -     invisiblity_control="LagMeterShrunk" -     type="string" -     length="1" -     bottom="80" -     follows="left|top" -     font="SansSerif" -     height="16" -     layout="topleft" -     left="110" -     name="network_text" -     right="-10"> -        Normal -    </text> -    <text -     invisiblity_control="LagMeterShrunk" -     bottom="96" -     follows="left|top" -     height="16" -     layout="topleft" -     left="40" -     name="network_lag_cause" -     right="-32" /> -    <button -     follows="top|left" -     height="16" -     image_selected="lag_status_good.tga" -     image_unselected="lag_status_good.tga" -     layout="topleft" -     left="8" -     name="server_lagmeter" -     tab_stop="false" -     tool_tip="Server lag status" -     top="104" -     width="16" /> -    <text -     type="string" -     length="1" -     follows="left|top" -     font="SansSerif" -     height="16" -     layout="topleft" -     left_pad="3" -     name="server" -     top_delta="0" -     width="60"> -        Server -    </text> -    <text -     invisiblity_control="LagMeterShrunk" -     type="string" -     length="1" -     bottom="120" -     follows="left|top" -     font="SansSerif" -     height="16" -     layout="topleft" -     left="110" -     name="server_text" -     right="-10"> -        Normal -    </text> -    <text -     invisiblity_control="LagMeterShrunk" -     bottom="136" -     follows="left|top" -     height="16" -     layout="topleft" -     left="40" -     name="server_lag_cause" -     right="-32" /> -    <button -     follows="left|top" -     height="20" -     label=">>" -     layout="topleft" -     left="10" -     name="minimize" -	 tool_tip="Toggle floater size" -     top_delta="24" -     width="40"> -        <button.commit_callback -         function="LagMeter.ClickShrink" /> -    </button> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml new file mode 100644 index 0000000000..246e8bb256 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml @@ -0,0 +1,446 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater legacy_header_height="18" +         can_resize="true" +         height="400" +         layout="topleft" +         name="Scene Load Statistics" +         save_rect="true" +         save_visibility="true" +         title="SCENE LOAD STATISTICS" +         width="260"> +    <button follows="top|left" +            top="20" +            bottom="60" +            left="10" +            width="100" +            label="Pause" +            name="playpause"/> +    <scroll_container follows="top|left|bottom|right" +                      bottom="400" +                      layout="topleft" +                      left="0" +                      name="statistics_scroll" +                      reserve_scroll_corner="true" +                      top="60" +                      width="260"> +      <container_view follows="top|left|bottom|right" +                      height="378" +                      layout="topleft" +                      left="2" +                      name="statistics_view" +                      top="20" +                      width="245" > +<!--Basic Section--> +		  <stat_view name="basic" +                 label="Basic" +                 show_label="true" +                 setting="OpenDebugStatBasic"> +        <stat_bar name="frame difference" +                  label="Frame Pixel Difference" +                  orientation="horizontal" +                  unit_label="%" +                  stat="FramePixelDifference" +                  bar_max="100" +                  tick_spacing="10" +                  unit_scale="100" +                  precision="0"/> +        <stat_bar name="bandwidth" +                  label="Bandwidth" +                  orientation="horizontal" +                  unit_label="kbps" +                  stat="kbitstat" +                  bar_max="5000" +                  tick_spacing="500" +                  precision="0"/> +			  <stat_bar name="packet_loss" +                  label="Packet Loss" +                  orientation="horizontal" +                  unit_label=" %" +                  stat="packetslostpercentstat" +                  bar_max="5" +                  tick_spacing="0.5" +                  precision="3" +                  show_bar="false" +                  show_mean="true"/> +		  </stat_view> +<!--Advanced Section--> +      <stat_view name="advanced" +                 label="Advanced" +                 show_label="true" +                 setting="OpenDebugStatAdvanced"> +			  <stat_view name="render" +                   label="Render" +                   show_label="true" +                   setting="OpenDebugStatRender"> +          <stat_bar name="objs" +                    label="Total Objects" +                    orientation="horizontal" +                    unit_label="" +                    stat="numobjectsstat" +                    bar_max="50000" +                    tick_spacing="5000" +                    precision="0" +                    show_bar="false"/> +          <stat_bar name="newobjs" +                    label="New Objects" +                    orientation="horizontal" +                    unit_label="/sec" +                    stat="numnewobjectsstat" +                    bar_max="2000" +                    tick_spacing="200" +                    show_bar="false"/> +          <stat_bar name="object_cache_hits" +                    label="Object Cache Hit Rate" +                    orientation="horizontal" +                    stat="object_cache_hits" +                    bar_max="100" +                    unit_label="%" +                    tick_spacing="20" +                    show_history="true" +                    show_bar="false"/> +			  </stat_view> +<!--Texture Stats--> +			  <stat_view name="texture" +                   label="Texture" +                   show_label="true"> +			    <stat_bar name="texture_cache_hits" +                    label="Cache Hit Rate" +                    orientation="horizontal" +                    stat="texture_cache_hits" +                    bar_max="100.f" +                    unit_label="%" +                    tick_spacing="20" +                    show_history="true" +                    show_bar="false"/> +          <stat_bar name="texture_cache_read_latency" +                    label="Cache Read Latency" +                    orientation="horizontal" +                    unit_label="msec" +                    stat="texture_cache_read_latency" +                    bar_max="1000.f" +                    tick_spacing="100" +                    show_history="true" +                    show_bar="false"/> +          <stat_bar name="numimagesstat" +                    label="Count" +                    orientation="horizontal" +                    stat="numimagesstat"  +                    bar_max="8000.f"  +                    tick_spacing="2000.f" +                    show_bar="false"/> +			    <stat_bar name="numrawimagesstat" +                    label="Raw Count" +                    orientation="horizontal" +                    stat="numrawimagesstat" +                    bar_max="8000.f"  +                    tick_spacing="2000.f" +                    show_bar="false"/> +			  </stat_view> +<!--Network Stats--> +			  <stat_view name="network" +                   label="Network" +                   show_label="true" +                   setting="OpenDebugStatNet"> +			    <stat_bar name="packetsinstat" +                    label="Packets In" +                    orientation="horizontal" +                    stat="packetsinstat" +                    unit_label="/sec"  +                    bar_max="1024.f"  +                    tick_spacing="128.f" +                    precision="1" +                    show_bar="false"/> +			    <stat_bar name="packetsoutstat" +                    label="Packets Out" +                    orientation="horizontal" +                    stat="packetsoutstat" +                    unit_label="/sec"   +                    bar_max="1024.f"  +                    tick_spacing="128.f" +                    precision="1" +                    show_bar="false"/> +			    <stat_bar name="objectkbitstat" +                    label="Objects" +                    orientation="horizontal" +                    stat="objectkbitstat" +                    unit_label="kbps" +                    bar_max="1024.f" +                    tick_spacing="128.f" +                    precision="1" +                    show_bar="false"/> +			    <stat_bar name="texturekbitstat" +                    label="Texture" +                    orientation="horizontal" +                    stat="texturekbitstat" +                    unit_label="kbps" +                    bar_max="1024.f" +                    tick_spacing="128.f" +                    precision="1" +                    show_bar="false"/> +			    <stat_bar name="assetkbitstat" +                    label="Asset" +                    orientation="horizontal" +                    stat="assetkbitstat" +                    unit_label="kbps" +                    bar_max="1024.f" +                    tick_spacing="128.f" +                    precision="1" +                    show_bar="false"/> +			    <stat_bar name="layerskbitstat" +                    label="Layers" +                    orientation="horizontal" +                    stat="layerskbitstat" +                    unit_label="kbps" +                    bar_max="1024.f" +                    tick_spacing="128.f" +                    precision="1" +                    show_bar="false"/> +			    <stat_bar name="actualinkbitstat" +                    label="Actual In" +                    orientation="horizontal" +                    stat="actualinkbitstat" +                    unit_label="kbps" +                    bar_max="1024.f" +                    tick_spacing="128.f" +                    precision="1" +                    show_bar="false"/> +			    <stat_bar name="actualoutkbitstat" +                    label="Actual Out" +                    orientation="horizontal" +                    stat="actualoutkbitstat" +                    unit_label="kbps" +                    bar_max="1024.f" +                    tick_spacing="128.f" +                    precision="1" +                    show_bar="false"/> +			    <stat_bar name="vfspendingoperations" +                    label="VFS Pending Operations" +                    orientation="horizontal" +                    stat="vfspendingoperations" +                    unit_label=" Ops." +                    show_bar="false"/> +			  </stat_view> +		  </stat_view> +<!--Sim Stats--> +		  <stat_view name="sim" +                 label="Simulator" +                 show_label="true" +                 setting="OpenDebugStatSim"> +			  <stat_bar name="simobjects" +                  label="Objects" +                  orientation="horizontal" +                  stat="simobjects" +                  precision="0" +                  bar_max="30000.f"  +                  tick_spacing="5000.f" +                  show_bar="false" +                  show_mean="false"/> +			  <stat_bar name="simactiveobjects" +                  label="Active Objects" +                  orientation="horizontal" +                  stat="simactiveobjects" +                  precision="0" +                  bar_max="5000.f"  +                  tick_spacing="750.f" +                  show_bar="false" +                  show_mean="false"/> +			  <stat_bar name="simactivescripts" +                  label="Active Scripts" +                  orientation="horizontal" +                  stat="simactivescripts" +                  precision="0" +                  bar_max="15000.f"  +                  tick_spacing="1875.f" +                  show_bar="false" +                  show_mean="false"/> +			  <stat_bar name="siminpps" +                  label="Packets In" +                  orientation="horizontal" +                  stat="siminpps" +                  unit_label="pps" +                  precision="0" +                  bar_max="2000.f"  +                  tick_spacing="250.f" +                  show_bar="false" +                  show_mean="false"/> +			  <stat_bar name="simoutpps" +                  label="Packets Out" +                  orientation="horizontal" +                  stat="simoutpps" +                  unit_label="pps"  +                  precision="0" +                  bar_max="2000.f"  +                  tick_spacing="250.f" +                  show_bar="false" +                  show_mean="false"/> +			  <stat_bar name="simpendingdownloads" +                  label="Pending Downloads" +                  orientation="horizontal" +                  stat="simpendingdownloads" +                  precision="0" +                  bar_max="800.f"  +                  tick_spacing="100.f" +                  show_bar="false" +                  show_mean="false"/> +			  <stat_bar name="simpendinguploads" +                  label="Pending Uploads" +                  orientation="horizontal" +                  stat="simpendinguploads" +                  precision="0" +                  bar_max="100.f"  +                  tick_spacing="25.f" +                  show_bar="false" +                  show_mean="false"/> +			  <stat_bar name="simtotalunackedbytes" +                  label="Total Unacked Bytes" +                  orientation="horizontal" +                  stat="simtotalunackedbytes" +                  unit_label="kb" +                  precision="1" +                  bar_max="100000.f"  +                  tick_spacing="25000.f" +                  show_bar="false" +                  show_mean="false"/> +			  <stat_view name="simperf" +                   label="Time (ms)" +                   show_label="true"> +			    <stat_bar name="simframemsec" +                    label="Total Frame Time" +                    orientation="horizontal" +                    stat="simframemsec" +                    unit_label="ms" +                    precision="3" +                    bar_max="40.f"  +                    tick_spacing="10.f" +                    show_bar="false" +                    show_mean="false"/> +			    <stat_bar name="simnetmsec" +                    label="Net Time" +                    orientation="horizontal" +                    stat="simnetmsec" +                    unit_label="ms" +                    precision="3" +                    bar_max="40.f"  +                    tick_spacing="10.f" +                    show_bar="false" +                    show_mean="false"/> +			    <stat_bar name="simsimphysicsmsec" +                    label="Physics Time" +                    orientation="horizontal" +                    stat="simsimphysicsmsec" +                    unit_label="ms" +                    precision="3" +                    bar_max="40.f"  +                    tick_spacing="10.f" +                    show_bar="false" +                    show_mean="false"/> +			    <stat_bar name="simsimothermsec" +                    label="Simulation Time" +                    orientation="horizontal" +                    stat="simsimothermsec" +                    unit_label="ms" +                    precision="3" +                    bar_max="40.f"  +                    tick_spacing="10.f" +                    show_bar="false" +                    show_mean="false"/> +			    <stat_bar name="simagentmsec" +                    label="Agent Time" +                    orientation="horizontal" +                    stat="simagentmsec" +                    unit_label="ms" +                    precision="3" +                    bar_max="40.f"  +                    tick_spacing="10.f" +                    show_bar="false" +                    show_mean="false"/> +			    <stat_bar name="simimagesmsec" +                    label="Images Time" +                    orientation="horizontal" +                    stat="simimagesmsec" +                    unit_label="ms" +                    precision="3" +                    bar_max="40.f"  +                    tick_spacing="10.f" +                    show_bar="false" +                    show_mean="false"/> +			    <stat_bar name="simscriptmsec" +                    label="Script Time" +                    orientation="horizontal" +                    stat="simscriptmsec" +                    unit_label="ms" +                    precision="3" +                    bar_max="40.f"  +                    tick_spacing="10.f" +                    show_bar="false" +                    show_mean="false"/> +          <stat_bar name="simsparemsec" +                    label="Spare Time" +                    orientation="horizontal" +                    stat="simsparemsec" +                    unit_label="ms" +                    precision="3" +                    bar_max="40.f" +                    tick_spacing="10.f" +                    show_bar="false" +                    show_mean="false"/> +<!--2nd level time blocks under 'Details' second--> +          <stat_view name="timedetails" +                     label="Time Details (ms)" +                     show_label="true"> +            <stat_bar name="simsimphysicsstepmsec" +                      label="  Physics Step" +                      orientation="horizontal" +                      stat="simsimphysicsstepmsec" +                      unit_label="ms" +                      precision="3" +                      bar_max="40.f" +                      tick_spacing="10.f" +                      show_bar="false" +                      show_mean="false"/> +            <stat_bar name="simsimphysicsshapeupdatemsec" +                      label="  Update Phys Shapes" +                      orientation="horizontal" +                      stat="simsimphysicsshapeupdatemsec" +                      unit_label="ms" +                      precision="3" +                      bar_max="40.f" +                      tick_spacing="10.f" +                      show_bar="false" +                      show_mean="false"/> +            <stat_bar name="simsimphysicsothermsec" +                      label="  Physics Other" +                      orientation="horizontal" +                      stat="simsimphysicsothermsec" +                      unit_label="ms" +                      precision="3" +                      bar_max="40.f" +                      tick_spacing="10.f" +                      show_bar="false" +                      show_mean="false"/> +            <stat_bar name="simsleepmsec" +                      label="  Sleep Time" +                      orientation="horizontal" +                      stat="simsleepmsec" +                      unit_label="ms" +                      precision="3" +                      bar_max="40.f" +                      tick_spacing="10.f" +                      show_bar="false" +                      show_mean="false"/> +            <stat_bar name="simpumpiomsec" +                      label="  Pump IO" +                      orientation="horizontal" +                      stat="simpumpiomsec" +                      unit_label="ms" +                      precision="3" +                      bar_max="40.f" +                      tick_spacing="10.f" +                      show_bar="false" +                      show_mean="false"/> +          </stat_view> +			  </stat_view> +		  </stat_view> +    </container_view> +  </scroll_container> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index f9eb16d224..0493f487d4 100755 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -31,17 +31,17 @@  		  <stat_view  			 name="basic"  			 label="Basic" +       follows="left|top|right"  			 show_label="true"  			 setting="OpenDebugStatBasic">  			<stat_bar  			   name="fps"  			   label="FPS"  			   unit_label="fps" -			   stat="fpsstat" +			   stat="framesrendered"  			   bar_min="0"  			   bar_max="60"  			   tick_spacing="6" -			   label_spacing="12"  			   precision="1"  			   show_bar="true"  			   show_history="true"> @@ -54,7 +54,6 @@  			   bar_min="0"  			   bar_max="5000"  			   tick_spacing="500" -			   label_spacing="1000"  				 precision="0"  			   show_bar="true"  			   show_history="false"> @@ -67,9 +66,7 @@  			   bar_min="0"  			   bar_max="5"  			   tick_spacing="0.5" -			   label_spacing="1"  			   precision="3" -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="true">  			</stat_bar> @@ -81,10 +78,8 @@  			   bar_min="0"  			   bar_max="5000"  			   tick_spacing="500" -			   label_spacing="1000"  				 precision="0"  			   show_bar="false" -			   show_per_sec="false"  			   show_mean="false">  			</stat_bar>  		  </stat_view> @@ -92,11 +87,13 @@        <stat_view  			 name="advanced"  			 label="Advanced" +       follows="left|top|right"         			 show_label="true"  			 setting="OpenDebugStatAdvanced">  			<stat_view  			   name="render"  			   label="Render" +         follows="left|top|right"  			   show_label="true"  			   setting="OpenDebugStatRender">  			  <stat_bar @@ -104,10 +101,10 @@  				 label="KTris Drawn per Frame"  				 unit_label="/fr"  				 stat="trianglesdrawnstat" +         unit_scale="0.001"  				 bar_min="0"  				 bar_max="10000"  				 tick_spacing="1000" -				 label_spacing="2000"  				 precision="0"  				 show_per_sec="false"           show_bar="false"> @@ -116,11 +113,11 @@  				 name="ktrissec"  				 label="KTris Drawn per Sec"  				 unit_label="/sec" +         unit_scale="0.001"  				 stat="trianglesdrawnstat"  				 bar_min="0"  				 bar_max="200000"  				 tick_spacing="25000" -				 label_spacing="50000"  				 precision="0"           show_bar="false">          </stat_bar> @@ -132,9 +129,7 @@  				 bar_min="0"  				 bar_max="50000"  				 tick_spacing="5000" -				 label_spacing="10000"  				 precision="0" -				 show_per_sec="false"  				 show_bar="false">  			  </stat_bar>  			  <stat_bar @@ -145,8 +140,6 @@  				 bar_min="0"  				 bar_max="2000"  				 tick_spacing="200" -				 label_spacing="400" -				 show_per_sec="true"  				 show_bar="false">  			  </stat_bar>         <stat_bar @@ -157,9 +150,7 @@  				 bar_max="100"           unit_label="%"  				 tick_spacing="20" -				 label_spacing="20"  				 show_history="true" -         show_per_sec="false"  				 show_bar="false">          </stat_bar>  			</stat_view> @@ -167,6 +158,7 @@  			<stat_view  			   name="texture"  			   label="Texture" +         follows="left|top|right"  			   show_label="true">  			  <stat_bar  				 name="texture_cache_hits" @@ -176,9 +168,7 @@  				 bar_max="100.f"           unit_label="%"  				 tick_spacing="20" -				 label_spacing="20"  				 show_history="true" -         show_per_sec="false"  				 show_bar="false">          </stat_bar>          <stat_bar @@ -189,9 +179,7 @@  				 bar_min="0.f"  				 bar_max="1000.f"  				 tick_spacing="100" -				 label_spacing="200"  				 show_history="true" -         show_per_sec="false"  				 show_bar="false">          </stat_bar>          <stat_bar @@ -201,8 +189,6 @@  				 bar_min="0.f"  				 bar_max="8000.f"   				 tick_spacing="2000.f" -				 label_spacing="4000.f"  -				 show_per_sec="false"  				 show_bar="false">  			  </stat_bar> @@ -213,8 +199,6 @@  				 bar_min="0.f"  				 bar_max="8000.f"   				 tick_spacing="2000.f" -				 label_spacing="4000.f"  -				 show_per_sec="false"  				 show_bar="false">  			  </stat_bar> @@ -222,12 +206,12 @@  				 name="gltexmemstat"  				 label="GL Mem"  				 stat="gltexmemstat" +         unit_label="MB" +         unit_scale="0.000001"  				 bar_min="0.f"  				 bar_max="400.f"   				 tick_spacing="100.f" -				 label_spacing="200.f"   				 precision="1" -				 show_per_sec="false"            show_bar="false">          </stat_bar> @@ -235,25 +219,25 @@  				 name="formattedmemstat"  				 label="Formatted Mem"  				 stat="formattedmemstat" +         unit_label="MB" +         unit_scale="0.000001"  				 bar_min="0.f"  				 bar_max="400.f"   				 tick_spacing="100.f" -				 label_spacing="200.f"  -				 precision="1" -				 show_per_sec="false"  +				 precision="3"           show_bar="false">          </stat_bar>  			  <stat_bar  				 name="rawmemstat"  				 label="Raw Mem" +         unit_label="MB" +         unit_scale="0.000001"  				 stat="rawmemstat"  				 bar_min="0.f"  				 bar_max="400.f"   				 tick_spacing="100.f" -				 label_spacing="200.f"  -				 precision="1" -				 show_per_sec="false"  +				 precision="3"           show_bar="false">          </stat_bar> @@ -261,12 +245,12 @@  				 name="glboundmemstat"  				 label="Bound Mem"  				 stat="glboundmemstat" +         unit_label="MB" +         unit_scale="0.000001"  				 bar_min="0.f"  				 bar_max="400.f"   				 tick_spacing="100.f" -				 label_spacing="200.f"  -				 precision="1" -				 show_per_sec="false"  +				 precision="3"           show_bar="false">          </stat_bar>  			</stat_view> @@ -274,6 +258,7 @@  			<stat_view  			   name="network"  			   label="Network" +         follows="left|top|right"  			   show_label="true"  			   setting="OpenDebugStatNet">  			  <stat_bar @@ -284,7 +269,6 @@           bar_min="0.f"  				 bar_max="1024.f"   				 tick_spacing="128.f" -				 label_spacing="256.f"   				 precision="1"  				 show_bar="false">  			  </stat_bar> @@ -297,7 +281,6 @@           bar_min="0.f"  				 bar_max="1024.f"   				 tick_spacing="128.f" -				 label_spacing="256.f"   				 precision="1"  				 show_bar="false" >  			  </stat_bar> @@ -310,7 +293,6 @@           bar_min="0.f"           bar_max="1024.f"           tick_spacing="128.f" -         label_spacing="256.f"           precision="1"  				 show_bar="false" >  			  </stat_bar> @@ -323,7 +305,6 @@           bar_min="0.f"           bar_max="1024.f"           tick_spacing="128.f" -         label_spacing="256.f"           precision="1"  				 show_bar="false" >  			  </stat_bar> @@ -336,7 +317,6 @@           bar_min="0.f"           bar_max="1024.f"           tick_spacing="128.f" -         label_spacing="256.f"           precision="1"  				 show_bar="false" >  			  </stat_bar> @@ -349,7 +329,6 @@           bar_min="0.f"           bar_max="1024.f"           tick_spacing="128.f" -         label_spacing="256.f"           precision="1"  				 show_bar="false" >  			  </stat_bar> @@ -362,7 +341,6 @@           bar_min="0.f"           bar_max="1024.f"           tick_spacing="128.f" -         label_spacing="256.f"           precision="1"  				 show_bar="false"  				 show_history="false" > @@ -376,7 +354,6 @@           bar_min="0.f"           bar_max="1024.f"           tick_spacing="128.f" -         label_spacing="256.f"           precision="1"  				 show_bar="false"  				 show_history="false"> @@ -387,7 +364,6 @@  				 label="VFS Pending Operations"  				 stat="vfspendingoperations"  				 unit_label=" Ops." -				 show_per_sec="false"  				 show_bar="false" >  			  </stat_bar>  			</stat_view> @@ -396,6 +372,7 @@  		  <stat_view  			 name="sim"  			 label="Simulator" +       follows="left|top|right"  			 show_label="true"  			 setting="OpenDebugStatSim">  			<stat_bar @@ -406,8 +383,6 @@  			   bar_min="0.f"  			   bar_max="1.f"   			   tick_spacing="0.16666f" -			   label_spacing="0.33333f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -420,8 +395,6 @@  			   bar_min="0.f"  			   bar_max="45.f"   			   tick_spacing="7.5f" -			   label_spacing="15.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -434,8 +407,6 @@  			   bar_min="0.f"  			   bar_max="45.f"   			   tick_spacing="7.5.f" -			   label_spacing="15.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -443,6 +414,7 @@  			<stat_view  			   name="physicsdetail"  			   label="Physics Details" +         follows="left|top|right"  			   show_label="true">  			  <stat_bar  				 name="physicspinnedtasks" @@ -452,8 +424,6 @@  				 bar_min="0.f"  				 bar_max="500.f"   				 tick_spacing="50.f" -				 label_spacing="100.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -466,8 +436,6 @@  				 bar_min="0.f"  				 bar_max="500.f"   				 tick_spacing="50.f" -				 label_spacing="100.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -481,8 +449,6 @@  				 bar_min="0.f"  				 bar_max="1024.f"   				 tick_spacing="128.f" -				 label_spacing="256.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -496,8 +462,6 @@  			   bar_min="0.f"  			   bar_max="100.f"   			   tick_spacing="25.f" -			   label_spacing="50.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -510,8 +474,6 @@  			   bar_min="0.f"  			   bar_max="80.f"   			   tick_spacing="10.f" -			   label_spacing="40.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -524,8 +486,6 @@  			   bar_min="0.f"  			   bar_max="40.f"   			   tick_spacing="5.f" -			   label_spacing="10.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -538,8 +498,6 @@  			   bar_min="0.f"  			   bar_max="30000.f"   			   tick_spacing="5000.f" -			   label_spacing="10000.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -552,8 +510,6 @@  			   bar_min="0.f"  			   bar_max="5000.f"   			   tick_spacing="750.f" -			   label_spacing="1250.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -566,8 +522,6 @@  			   bar_min="0.f"  			   bar_max="15000.f"   			   tick_spacing="1875.f" -			   label_spacing="3750.f"   -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -579,9 +533,7 @@              bar_min="0"              bar_max="100"              tick_spacing="10" -            label_spacing="20"              precision="3" -            show_per_sec="false"              show_bar="false"              show_mean="true">          </stat_bar> @@ -595,8 +547,6 @@  			   bar_min="0.f"  			   bar_max="5000.f"   			   tick_spacing="750.f" -			   label_spacing="1250.f"   -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -604,6 +554,7 @@          <stat_view              name="simpathfinding"              label="Pathfinding" +            follows="left|top|right"              show_label="true">            <stat_bar                name="simsimaistepmsec" @@ -614,8 +565,6 @@                bar_min="0.f"                bar_max="40.f"                tick_spacing="10.f" -              label_spacing="20.f" -              show_per_sec="false"                show_bar="false"                show_mean="false" >            </stat_bar> @@ -628,8 +577,6 @@                bar_min="0"                bar_max="45"                tick_spacing="4" -              label_spacing="8" -              show_per_sec="false"                show_bar="false">            </stat_bar>            <stat_bar @@ -640,9 +587,7 @@                bar_min="0"                bar_max="100"                tick_spacing="10" -              label_spacing="20"                precision="1" -              show_per_sec="false"                show_bar="false"                show_mean="true">            </stat_bar> @@ -657,8 +602,6 @@  			   bar_min="0.f"  			   bar_max="2000.f"   			   tick_spacing="250.f" -			   label_spacing="1000.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -672,8 +615,6 @@  			   bar_min="0.f"  			   bar_max="2000.f"   			   tick_spacing="250.f" -			   label_spacing="1000.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -686,8 +627,6 @@  			   bar_min="0.f"  			   bar_max="800.f"   			   tick_spacing="100.f" -			   label_spacing="200.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -700,8 +639,6 @@  			   bar_min="0.f"  			   bar_max="100.f"   			   tick_spacing="25.f" -			   label_spacing="50.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -715,8 +652,6 @@  			   bar_min="0.f"  			   bar_max="100000.f"   			   tick_spacing="25000.f" -			   label_spacing="50000.f"  -			   show_per_sec="false"  			   show_bar="false"  			   show_mean="false" >  			</stat_bar> @@ -724,6 +659,7 @@  			<stat_view  			   name="simperf"  			   label="Time (ms)" +         follows="left|top|right"  			   show_label="true">  			  <stat_bar  				 name="simframemsec" @@ -734,8 +670,6 @@  				 bar_min="0.f"  				 bar_max="40.f"   				 tick_spacing="10.f" -				 label_spacing="20.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -749,8 +683,6 @@  				 bar_min="0.f"  				 bar_max="40.f"   				 tick_spacing="10.f" -				 label_spacing="20.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -764,8 +696,6 @@  				 bar_min="0.f"  				 bar_max="40.f"   				 tick_spacing="10.f" -				 label_spacing="20.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -779,8 +709,6 @@  				 bar_min="0.f"  				 bar_max="40.f"   				 tick_spacing="10.f" -				 label_spacing="20.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -794,8 +722,6 @@  				 bar_min="0.f"  				 bar_max="40.f"   				 tick_spacing="10.f" -				 label_spacing="20.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -809,8 +735,6 @@  				 bar_min="0.f"  				 bar_max="40.f"   				 tick_spacing="10.f" -				 label_spacing="20.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -824,8 +748,6 @@  				 bar_min="0.f"  				 bar_max="40.f"   				 tick_spacing="10.f" -				 label_spacing="20.f"  -				 show_per_sec="false"  				 show_bar="false"  				 show_mean="false" >  			  </stat_bar> @@ -839,8 +761,6 @@           bar_min="0.f"           bar_max="40.f"           tick_spacing="10.f" -         label_spacing="20.f" -         show_per_sec="false"           show_bar="false"           show_mean="false" >          </stat_bar> @@ -848,6 +768,7 @@            <stat_view   			     name="timedetails"  			     label="Time Details (ms)" +           follows="left|top|right"  			     show_label="true">              <stat_bar               name="simsimphysicsstepmsec" @@ -858,8 +779,6 @@               bar_min="0.f"               bar_max="40.f"               tick_spacing="10.f" -             label_spacing="20.f" -             show_per_sec="false"               show_bar="false"               show_mean="false" >              </stat_bar> @@ -872,8 +791,6 @@               bar_min="0.f"               bar_max="40.f"               tick_spacing="10.f" -             label_spacing="20.f" -             show_per_sec="false"               show_bar="false"               show_mean="false" >              </stat_bar> @@ -886,8 +803,6 @@               bar_min="0.f"               bar_max="40.f"               tick_spacing="10.f" -             label_spacing="20.f" -             show_per_sec="false"               show_bar="false"               show_mean="false" >              </stat_bar> @@ -900,8 +815,6 @@               bar_min="0.f"               bar_max="40.f"               tick_spacing="10.f" -             label_spacing="20.f" -             show_per_sec="false"               show_bar="false"               show_mean="false" >              </stat_bar> @@ -914,8 +827,6 @@               bar_min="0.f"               bar_max="40.f"               tick_spacing="10.f" -             label_spacing="20.f" -             show_per_sec="false"               show_bar="false"               show_mean="false" >              </stat_bar> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index a11cd13fdb..d50b7b18e7 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1300,7 +1300,7 @@               parameter="hud" />          </menu_item_call>-->  		<menu_item_separator/> -		 +  		<menu_item_call               label="User’s guide"               name="User’s guide"> @@ -1475,6 +1475,14 @@                   function="Floater.Toggle"                   parameter="stats" />              </menu_item_check> +            <menu_item_call +             label="Scene Load Statistics" +             name="Scene Load Statistics" +             shortcut="control|shift|2"> +                <on_click +                 function="Floater.Show" +                 parameter="scene_load_stats" /> +            </menu_item_call>        <menu_item_check          label="Show Draw Weight for Avatars"          name="Avatar Rendering Cost"> @@ -2080,6 +2088,16 @@                 function="Advanced.ToggleConsole"                 parameter="scene view" />              </menu_item_check> +            <menu_item_check +                 label="Scene Loading Monitor" +                 name="Scene Loading Monitor"> +              <menu_item_check.on_check +               function="Advanced.CheckConsole" +               parameter="scene monitor" /> +              <menu_item_check.on_click +               function="Advanced.ToggleConsole" +               parameter="scene monitor" /> +            </menu_item_check>              <menu_item_call                enabled="false"                visible="false" @@ -2831,6 +2849,16 @@                   function="ToggleControl"                   parameter="RenderHoverGlowEnable" />              </menu_item_check> +          <menu_item_separator /> +           +          <menu_item_call +            enabled="true" +            label="Clear Cache Immediately" +            name="Cache Clear"> +            <menu_item_call.on_click +             function="Develop.ClearCache" /> +          </menu_item_call> +                    </menu>          <menu diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 970a11c6c4..540618ef9a 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6923,7 +6923,7 @@ Do not allow access if you do not fully understand why it wants access to your a  [FOOTERTEXT]      </footer>    </notification> -	 +  	<notification  	 icon="notify.tga"  	 name="UnknownScriptQuestion" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 3b57ff5fd6..e0a85877eb 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -416,7 +416,7 @@ Please try logging in again in a minute.</string>  	<string name="OverrideYourAnimations">Replace your default animations</string>  	<string name="ScriptReturnObjects">Return objects on your behalf</string>  	<string name="UnknownScriptPermission">(unknown)!</string> -	 +  	<!-- Sim Access labels -->  	<string name="SIM_ACCESS_PG">General</string>  	<string name="SIM_ACCESS_MATURE">Moderate</string> diff --git a/indra/newview/skins/default/xui/es/floater_lagmeter.xml b/indra/newview/skins/default/xui/es/floater_lagmeter.xml deleted file mode 100755 index 227689a194..0000000000 --- a/indra/newview/skins/default/xui/es/floater_lagmeter.xml +++ /dev/null @@ -1,154 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="MEDIDOR DEL LAG"> -	<floater.string name="max_title_msg"> -		Medidor del lag -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		Lag -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		Cliente -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		Normal, ventana en segundo plano -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		Frames del cliente valorados por debajo de [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		Frames del cliente valorados entre [CLIENT_FRAME_RATE_CRITICAL] y [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Posible causa: distancia de dibujo fijada muy alta -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Posible causa: imágenes cargándose -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Posible causa: demasiadas imágenes en la memoria -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Posible causa: demasiados objetos complejos en la escena -	</floater.string> -	<floater.string name="network_text_msg"> -		Red -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		La conexión deja caer más del [NETWORK_PACKET_LOSS_CRITICAL]% de los paquetes -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		La conexión deja caer [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% de los paquetes -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		El tiempo de conexión -ping- supera los [NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		El tiempo de conexión -ping- es de [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Quizá una mala conexión o un ancho de banda fijado demasiado alto. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Quizá una mala conexión o una aplicación de archivos compartidos. -	</floater.string> -	<floater.string name="server_text_msg"> -		Servidor -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Frecuencia (framerate) por debajo de [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Frecuencia (framerate) entre [SERVER_FRAME_RATE_CRITICAL] y [SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Posible causa: demasiados objetos físicos -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Posible causa: demasiados objetos con script -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Posible causa: demasiado tráfico en la red -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Posible causa: demasiada gente moviéndose en la región -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Posible causa: demasiados cálculos de imáganes -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Posible causa: carga del simulador muy pesada -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button label="" label_selected="" name="client_lagmeter" tool_tip="Estado del lag del cliente"/> -	<text name="client"> -		Cliente -	</text> -	<text font="SansSerifSmall" name="client_text"> -		Normal -	</text> -	<text left="30" name="client_lag_cause" right="-10"/> -	<button label="" label_selected="" name="network_lagmeter" tool_tip="Estado del lag de la red"/> -	<text name="network"> -		Red -	</text> -	<text font="SansSerifSmall" name="network_text"> -		Normal -	</text> -	<text left="30" name="network_lag_cause" right="-10"/> -	<button label="" label_selected="" name="server_lagmeter" tool_tip="Estado del lag del servidor"/> -	<text name="server"> -		Servidor -	</text> -	<text font="SansSerifSmall" name="server_text"> -		Normal -	</text> -	<text left="30" name="server_lag_cause" right="-32"/> -	<button label=">>" name="minimize" tool_tip="Cambia el tamaño de la ventana"/> -</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_lagmeter.xml b/indra/newview/skins/default/xui/fr/floater_lagmeter.xml deleted file mode 100755 index 39a861d8bd..0000000000 --- a/indra/newview/skins/default/xui/fr/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="MESURE DU LAG"> -	<floater.string name="max_title_msg"> -		Mesure du lag -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		Lag -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		Client -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		Normal, fenêtre en arrière-plan -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		Taux de défilement [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		Taux de défilement entre [CLIENT_FRAME_RATE_CRITICAL] et [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Cause possible : limite d'affichage trop élevée -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Cause possible : images en cours de chargement -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Cause possible : trop d'images en mémoire -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Cause possible : trop d'objets complexes -	</floater.string> -	<floater.string name="network_text_msg"> -		Réseau -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		La connexion perd plus de [NETWORK_PACKET_LOSS_CRITICAL] % de paquets -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		La connexion perd entre [NETWORK_PACKET_LOSS_WARNING] % et [NETWORK_PACKET_LOSS_CRITICAL] % de paquets -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		Connexion ping > [NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		Connexion ping entre [NETWORK_PING_WARNING] et [NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Mauvaise connexion possible ou réglage de la bande passante trop élevé. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Mauvaise connexion possible ou app. de partage des fichiers -	</floater.string> -	<floater.string name="server_text_msg"> -		Serveur -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Défilement du simulateur < [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Défilement simulateur entre [SERVER_FRAME_RATE_CRITICAL] et [SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Cause possible : trop d'objets physiques -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Cause possible : trop d'objets scriptés -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Cause possible : trop de trafic réseau -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Cause possible : trop de personnes en mouvement -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Cause possible : trop de calculs d'images -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Cause possible : charge simulateur trop lourde -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button name="client_lagmeter" tool_tip="Statut du lag client"/> -	<text name="client"> -		Client -	</text> -	<text name="client_text"> -		Normal -	</text> -	<button name="network_lagmeter" tool_tip="Statut du lag réseau"/> -	<text name="network"> -		Réseau -	</text> -	<text name="network_text"> -		Normal -	</text> -	<button name="server_lagmeter" tool_tip="Statut du lag serveur"/> -	<text name="server"> -		Serveur -	</text> -	<text name="server_text"> -		Normal -	</text> -	<button label=">>" name="minimize" tool_tip="Activer/désactiver la taille du floater"/> -</floater> diff --git a/indra/newview/skins/default/xui/it/floater_lagmeter.xml b/indra/newview/skins/default/xui/it/floater_lagmeter.xml deleted file mode 100755 index f7b2b1ab4a..0000000000 --- a/indra/newview/skins/default/xui/it/floater_lagmeter.xml +++ /dev/null @@ -1,154 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="MISURATORE LAG"> -	<floater.string name="max_title_msg"> -		Misuratore del lag -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		Lag -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		Programma in locale -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		Normale, finestra sullo sfondo -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		Velocità dei frame al di sotto di [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		Velocità dei frame tra [CLIENT_FRAME_RATE_CRITICAL] e [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		Normale -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Possibile causa: Campo visivo impostato troppo alto -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Possibile causa: Caricamento immagini -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Possibile causa: Troppe immagini in memoria -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Possibile causa: Troppi oggetti complessi intorno -	</floater.string> -	<floater.string name="network_text_msg"> -		Network -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		La connessione sta calando al di sotto del [NETWORK_PACKET_LOSS_CRITICAL]% di pacchetti -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		La connessione sta calando tra il [NETWORK_PACKET_LOSS_WARNING]% e il [NETWORK_PACKET_LOSS_CRITICAL]% di pacchetti -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		Normale -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		Il tempo di ping della connessione è al di sopra di [NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		Il tempo di ping della connessione è tra [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Possibile cattiva connessione o la larghezza di banda impostata nelle preferenze troppo alta. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Possibile cattiva connessione o l'apertura di un programma di scambio files. -	</floater.string> -	<floater.string name="server_text_msg"> -		Server -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Velocità dei frame al di sotto di [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Velocità dei frame tra [SERVER_FRAME_RATE_CRITICAL] e [SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		Normale -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Possibile causa: troppi oggetti fisici -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Possibile causa: troppi oggetti scriptati -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Possibile causa: eccessivo traffico sulla rete -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Possibile causa: troppi residenti in movimento nella regione -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Possibile causa: troppe elaborazioni di immagini -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Possibile causa: carico eccessivo del simulatore -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button label="" label_selected="" name="client_lagmeter" tool_tip="Stato del lag del programma in locale"/> -	<text name="client"> -		Client -	</text> -	<text font="SansSerifSmall" left="145" name="client_text"> -		Normale -	</text> -	<text left="30" name="client_lag_cause" right="-10"/> -	<button label="" label_selected="" name="network_lagmeter" tool_tip="Stato del lag del network"/> -	<text name="network"> -		Rete -	</text> -	<text font="SansSerifSmall" name="network_text"> -		Normale -	</text> -	<text left="30" name="network_lag_cause" right="-10"/> -	<button label="" label_selected="" name="server_lagmeter" tool_tip="Stato del lag del server"/> -	<text name="server"> -		Server -	</text> -	<text font="SansSerifSmall" name="server_text"> -		Normale -	</text> -	<text left="30" name="server_lag_cause" right="-32"/> -	<button label=">>" name="minimize" tool_tip="Cambia dimensioni floater"/> -</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml b/indra/newview/skins/default/xui/ja/floater_lagmeter.xml deleted file mode 100755 index e3546cd837..0000000000 --- a/indra/newview/skins/default/xui/ja/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="ラグメーター"> -	<floater.string name="max_title_msg"> -		ラグ メーター -	</floater.string> -	<floater.string name="max_width_px"> -		350 -	</floater.string> -	<floater.string name="min_title_msg"> -		ラグ -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		クライアント -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		ノーマル、ウィンドウは背景に -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		クライアント フレームレート < [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		クライアント フレームレート: [CLIENT_FRAME_RATE_CRITICAL] ~ [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		ノーマル -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		考えられる原因: 描画距離の設定が大きすぎる -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		考えられる原因: 画像のロード中 -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		考えられる原因: メモリ内の画像数が多すぎる -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		考えられる原因: 画面に含まれる複雑なオブジェクトが多すぎる -	</floater.string> -	<floater.string name="network_text_msg"> -		ネットワーク -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		接続でドロップされるパケットの割合: > [NETWORK_PACKET_LOSS_CRITICAL] -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		接続でドロップされるパケットの割合:[NETWORK_PACKET_LOSS_WARNING] ~ [NETWORK_PACKET_LOSS_CRITICAL] -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		ノーマル -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		接続の ping 時間: > [NETWORK_PING_CRITICAL] ミリ秒 -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		接続の ping 時間: [NETWORK_PING_WARNING] ~ [NETWORK_PING_CRITICAL] ミリ秒 -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		接続不良になっているか、帯域幅設定が高すぎます。 -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		接続不良になっているか、ファイル共有アプリケーションに問題があります。 -	</floater.string> -	<floater.string name="server_text_msg"> -		サーバー -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		シミュレーターのフレームレート: < [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		シミュレーターのフレームレート: [SERVER_FRAME_RATE_CRITICAL] ~ [SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		ノーマル -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		考えられる原因: 物理的オブジェクトが多すぎる -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		考えられる原因: スクリプトを含むオブジェクトが多すぎる -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		考えられる原因: ネットワーク トラフィック過大 -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		考えられる原因: 地域内にて動いているアバターが多すぎる -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		考えられる原因: 画像計算が多すぎる -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		考えられる原因: シミュレーターの過負荷 -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button name="client_lagmeter" tool_tip="クライアント ラグ ステータス"/> -	<text name="client"> -		クライアント -	</text> -	<text name="client_text"> -		ノーマル -	</text> -	<button name="network_lagmeter" tool_tip="ネットワーク ラグ ステータス"/> -	<text name="network"> -		ネットワーク -	</text> -	<text name="network_text"> -		ノーマル -	</text> -	<button name="server_lagmeter" tool_tip="サーバー ラグ ステータス"/> -	<text name="server"> -		サーバー -	</text> -	<text name="server_text"> -		ノーマル -	</text> -	<button label=">> " name="minimize" tool_tip="フローターのサイズをトグル"/> -</floater> diff --git a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml b/indra/newview/skins/default/xui/pl/floater_lagmeter.xml deleted file mode 100755 index 8038550bcb..0000000000 --- a/indra/newview/skins/default/xui/pl/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="POMIAR LAGÓW"> -	<floater.string name="max_title_msg"> -		Pomiar lagów -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		Lag -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		Klient -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		W normie, okno w tle -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		Ilość klatek na sekundę klienta poniżej [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		Ilość klatek na sekundę pomiędzy [CLIENT_FRAME_RATE_CRITICAL] i [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		W normie -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Przyczyna: dystans rysowania jest za wysoki -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Przyczyna: ładowanie obrazu -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Przyczyna: za dużo obrazów w pamięci -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Przyczyna: za dużo złożonych obiektów -	</floater.string> -	<floater.string name="network_text_msg"> -		Sieć -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		Utrata pakietów przekracza [NETWORK_PACKET_LOSS_CRITICAL]% -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		Utrata pakietów przekracza [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		W normie -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		Fatalny ping - [NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		Wolny ping - [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Złe połączenie lub przepustowość. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Złe połączenie lub aplikacja współdzieląca pliki. -	</floater.string> -	<floater.string name="server_text_msg"> -		Serwer -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Ilość klatek na sekundę poniżej [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Ilość klatek na sekundę pomiędzy [SERVER_FRAME_RATE_CRITICAL] i [SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		W normie -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Przyczyna: za dużo obiektów fizycznych -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Przyczyna: za dużo obieków skryptowanych -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Przyczyna: za duży ruch w sieci -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Przyczyna: za dużo poruszających się awatarów w regionie -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Przyczyna: za dużo kalkulacji obrazu -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Przyczyna: symulator ładuje się zbyt powoli -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button label="" label_selected="" name="client_lagmeter" tool_tip="Status lagów klienta"/> -	<text name="client"> -		Klient -	</text> -	<text name="client_text"> -		W normie -	</text> -	<button label="" label_selected="" name="network_lagmeter" tool_tip="Network lag status"/> -	<text name="network"> -		Sieć -	</text> -	<text name="network_text"> -		W normie -	</text> -	<button label="" label_selected="" name="server_lagmeter" tool_tip="Server lag status"/> -	<text name="server"> -		Serwer -	</text> -	<text name="server_text"> -		W normie -	</text> -	<button label=">>" name="minimize" tool_tip="Złącz rozmiar pliku xml"/> -</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_lagmeter.xml b/indra/newview/skins/default/xui/pt/floater_lagmeter.xml deleted file mode 100755 index 9932318293..0000000000 --- a/indra/newview/skins/default/xui/pt/floater_lagmeter.xml +++ /dev/null @@ -1,154 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="LAG - Índice"> -	<floater.string name="max_title_msg"> -		Medidor de Atraso -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		Atraso -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		Cliente -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		Normal, janela por baixo -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		Taxa de quadros do Cliente abaixo de [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		Taxa de quadros do Cliente entre [CLIENT_FRAME_RATE_CRITICAL] e [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Causa possível: Distância de desenho ajustada muito alta -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Causa possível: Carregamento de Imagens -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Causa possível: Muitas imagens na memória -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Causa possível: Muitos objetos complexos na cena -	</floater.string> -	<floater.string name="network_text_msg"> -		Rede -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		Conexão está caindo para cerca de [NETWORK_PACKET_LOSS_CRITICAL]% de pacotes -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		Conexão está caindo [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% de pacotes -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		Tempo de conexão de ping é cerca de  [NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		Tempo de conexão de ping é [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Possível conexão ruim ou 'Largura de Banda' escolhida muito alta. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Possível conexão ruim ou aplicativos compartilhando arquivos. -	</floater.string> -	<floater.string name="server_text_msg"> -		Servidor -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Taxa de quadros abaixo de [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Taxa de quadros entre [SERVER_FRAME_RATE_CRITICAL] e [SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Causa possível: Muitos objetos físicos -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Causa possível: Muitos objetos com scripts -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Causa possível: Muito tráfego na rede -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Causa possível: Muitas pessoas se movendo na região -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Causa possível: Muitos cálculos de imagem -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Causa possível: Carga no simulador muito pesada -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button label="" label_selected="" name="client_lagmeter" tool_tip="Status de atraso no Cliente"/> -	<text name="client"> -		Cliente -	</text> -	<text font="SansSerifSmall" name="client_text"> -		Normal -	</text> -	<text left="30" name="client_lag_cause" right="-10"/> -	<button label="" label_selected="" name="network_lagmeter" tool_tip="Status de atraso na rede"/> -	<text name="network"> -		Rede -	</text> -	<text font="SansSerifSmall" name="network_text"> -		Normal -	</text> -	<text left="30" name="network_lag_cause" right="-10"/> -	<button label="" label_selected="" name="server_lagmeter" tool_tip="Status de atraso no servidor"/> -	<text name="server"> -		Servidor -	</text> -	<text font="SansSerifSmall" name="server_text"> -		Normal -	</text> -	<text left="30" name="server_lag_cause" right="-32"/> -	<button label=">>" name="minimize" tool_tip="Alternar o tamanho da janela"/> -</floater> diff --git a/indra/newview/skins/default/xui/ru/floater_lagmeter.xml b/indra/newview/skins/default/xui/ru/floater_lagmeter.xml deleted file mode 100755 index c420006a03..0000000000 --- a/indra/newview/skins/default/xui/ru/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="УРОВЕНЬ ЛАГОВ"> -	<floater.string name="max_title_msg"> -		Уровень лагов -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		Лаг -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		Клиент -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		Нормально, окно в фоне -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		Частота кадров клиента ниже [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		Частота кадров клиента от [CLIENT_FRAME_RATE_CRITICAL] до [CLIENT_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		Нормально -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Возможная причина: дальность отрисовки слишком велика -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Возможная причина: загрузка изображений -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Возможная причина: слишком много изображений в памяти -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Возможная причина: слишком много сложных объектов в сцене -	</floater.string> -	<floater.string name="network_text_msg"> -		Сеть -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		Сеть теряет более [NETWORK_PACKET_LOSS_CRITICAL]% пакетов -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		Сеть теряет [NETWORK_PACKET_LOSS_WARNING]–[NETWORK_PACKET_LOSS_CRITICAL]% пакетов -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		Нормально -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		Пинг соединения более [NETWORK_PING_CRITICAL] мс -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		Пинг соединения [NETWORK_PING_WARNING]–[NETWORK_PING_CRITICAL] мс -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Возможно, плохое соединение, или параметр «Ширина канала» слишком велик. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Возможно, плохое соединение или есть работающие файлообменные программы. -	</floater.string> -	<floater.string name="server_text_msg"> -		Сервер -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Частота кадров сервера ниже [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Частота кадров сервера [SERVER_FRAME_RATE_CRITICAL]–[SERVER_FRAME_RATE_WARNING] -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		Нормально -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Возможная причина: слишком много физических объектов -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Возможная причина: слишком много скриптовых объектов -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Возможная причина: слишком большой сетевой трафик -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Возможная причина: слишком много людей в регионе -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Возможная причина: слишком много изображений -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Возможная причина: сервер сильно загружен -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button name="client_lagmeter" tool_tip="Уровень лагов клиента"/> -	<text name="client"> -		Клиент -	</text> -	<text name="client_text"> -		Нормально -	</text> -	<button name="network_lagmeter" tool_tip="Уровень лагов сети"/> -	<text name="network"> -		Сеть -	</text> -	<text name="network_text"> -		Нормально -	</text> -	<button name="server_lagmeter" tool_tip="Уровень лагов сервера"/> -	<text name="server"> -		Сервер -	</text> -	<text name="server_text"> -		Нормально -	</text> -	<button label=">>" name="minimize" tool_tip="Переключение размера"/> -</floater> diff --git a/indra/newview/skins/default/xui/tr/floater_lagmeter.xml b/indra/newview/skins/default/xui/tr/floater_lagmeter.xml deleted file mode 100755 index 736c50be90..0000000000 --- a/indra/newview/skins/default/xui/tr/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="GECİKME ÖLÇER"> -	<floater.string name="max_title_msg"> -		Gecikme Ölçer -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		Gecikme -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		İstemci -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		Normal, pencere alt zeminde -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		İstemci kare hızı [CLIENT_FRAME_RATE_CRITICAL] altında -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		İstemci kare hızı [CLIENT_FRAME_RATE_CRITICAL] ile [CLIENT_FRAME_RATE_WARNING] arasınad -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		Muhtemel neden: Çizme mesafesi çok yüksek -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		Muhtemel neden: Görüntüler yükleniyor -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		Muhtemel neden: Bellekte çok fazla görüntü -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		Muhtemel neden: Sahnede çok fazla karmaşık nesne -	</floater.string> -	<floater.string name="network_text_msg"> -		Ağ -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		Bağlantı paketlerin % [NETWORK_PACKET_LOSS_CRITICAL]'sinden fazlasını bırakıyor -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		Bağlantı paketlerin % [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]'sini bırakıyor -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		Bağlantı ping süresi [NETWORK_PING_CRITICAL] ms.den fazla -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		Bağlantı ping süresi [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		Muhtemel yetersiz bağlantı veya 'Bant Genişliği' tercihi çok yüksek. -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		Muhtemel yetersiz bağlantı veya dosya paylaşım uygulaması. -	</floater.string> -	<floater.string name="server_text_msg"> -		Sunucu -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		Simülatör kare hızı [SERVER_FRAME_RATE_CRITICAL] altında -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		Simülatör kare hızı [SERVER_FRAME_RATE_CRITICAL] ve [SERVER_FRAME_RATE_WARNING] arasında -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		Normal -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		Muhtemel Neden: Çok fazla fiziki nesne -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		Muhtemel Neden: Çok fazla komut dosyalı nesne -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		Muhtemel Neden: Çok fazla ağ trafiği -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		Muhtemel Neden: Bölgede hareket eden çok fazla insan var -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		Muhtemel Neden: Çok fazla görüntü hesabı -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		Muhtemel Neden: Simülatör yükü çok ağır -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button name="client_lagmeter" tool_tip="İstemci gecikme durumu"/> -	<text name="client"> -		İstemci -	</text> -	<text name="client_text"> -		Normal -	</text> -	<button name="network_lagmeter" tool_tip="Ağ gecikme durumu"/> -	<text name="network"> -		Ağ -	</text> -	<text name="network_text"> -		Normal -	</text> -	<button name="server_lagmeter" tool_tip="Sunucu gecikme durumu"/> -	<text name="server"> -		Sunucu -	</text> -	<text name="server_text"> -		Normal -	</text> -	<button label=">>" name="minimize" tool_tip="Gezdirici büyüklüğünü değiştir"/> -</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml deleted file mode 100755 index e9a082288a..0000000000 --- a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="floater_lagmeter" title="LAG 測量器"> -	<floater.string name="max_title_msg"> -		Lag 測量器 -	</floater.string> -	<floater.string name="max_width_px"> -		360 -	</floater.string> -	<floater.string name="min_title_msg"> -		延遲 -	</floater.string> -	<floater.string name="min_width_px"> -		90 -	</floater.string> -	<floater.string name="client_text_msg"> -		客戶端 -	</floater.string> -	<floater.string name="client_frame_rate_critical_fps"> -		10 -	</floater.string> -	<floater.string name="client_frame_rate_warning_fps"> -		15 -	</floater.string> -	<floater.string name="client_frame_time_window_bg_msg"> -		正常,視窗位於背景 -	</floater.string> -	<floater.string name="client_frame_time_critical_msg"> -		客戶端幀率低於 [CLIENT_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="client_frame_time_warning_msg"> -		客戶端幀率介於 [CLIENT_FRAME_RATE_CRITICAL] 和 [CLIENT_FRAME_RATE_WARNING] 之間 -	</floater.string> -	<floater.string name="client_frame_time_normal_msg"> -		正常 -	</floater.string> -	<floater.string name="client_draw_distance_cause_msg"> -		可能原因:可視距離設得太遠 -	</floater.string> -	<floater.string name="client_texture_loading_cause_msg"> -		可能原因:正在載入圖像 -	</floater.string> -	<floater.string name="client_texture_memory_cause_msg"> -		可能原因:記憶體裡圖像太多 -	</floater.string> -	<floater.string name="client_complex_objects_cause_msg"> -		可能原因:場景內複雜物件太多 -	</floater.string> -	<floater.string name="network_text_msg"> -		網路 -	</floater.string> -	<floater.string name="network_packet_loss_critical_pct"> -		10 -	</floater.string> -	<floater.string name="network_packet_loss_warning_pct"> -		5 -	</floater.string> -	<floater.string name="network_packet_loss_critical_msg"> -		這次連通丟失了至少 [NETWORK_PACKET_LOSS_CRITICAL]% 的封包 -	</floater.string> -	<floater.string name="network_packet_loss_warning_msg"> -		這次連通丟失了 [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% 的封包 -	</floater.string> -	<floater.string name="network_performance_normal_msg"> -		正常 -	</floater.string> -	<floater.string name="network_ping_critical_ms"> -		600 -	</floater.string> -	<floater.string name="network_ping_warning_ms"> -		300 -	</floater.string> -	<floater.string name="network_ping_critical_msg"> -		探測連通回應時間超過 [NETWORK_PING_CRITICAL] 毫秒 -	</floater.string> -	<floater.string name="network_ping_warning_msg"> -		探測連通回應時間為 [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] 毫秒 -	</floater.string> -	<floater.string name="network_packet_loss_cause_msg"> -		可能連通不良,或所設的偏好連通頻寬過高。 -	</floater.string> -	<floater.string name="network_ping_cause_msg"> -		可能連通不良,或使用檔案分享應用程式。 -	</floater.string> -	<floater.string name="server_text_msg"> -		伺服器 -	</floater.string> -	<floater.string name="server_frame_rate_critical_fps"> -		20 -	</floater.string> -	<floater.string name="server_frame_rate_warning_fps"> -		30 -	</floater.string> -	<floater.string name="server_single_process_max_time_ms"> -		20 -	</floater.string> -	<floater.string name="server_frame_time_critical_msg"> -		模擬器 framerate 低於 [SERVER_FRAME_RATE_CRITICAL] -	</floater.string> -	<floater.string name="server_frame_time_warning_msg"> -		模擬器 framerate 介於 [SERVER_FRAME_RATE_CRITICAL] 與 [SERVER_FRAME_RATE_WARNING] 之間 -	</floater.string> -	<floater.string name="server_frame_time_normal_msg"> -		正常 -	</floater.string> -	<floater.string name="server_physics_cause_msg"> -		可能原因:太多物理物件 -	</floater.string> -	<floater.string name="server_scripts_cause_msg"> -		可能原因:太多腳本物件 -	</floater.string> -	<floater.string name="server_net_cause_msg"> -		可能原因:太多網路流量 -	</floater.string> -	<floater.string name="server_agent_cause_msg"> -		可能原因:地區有太多移動的人 -	</floater.string> -	<floater.string name="server_images_cause_msg"> -		可能原因:太多圖像計算 -	</floater.string> -	<floater.string name="server_generic_cause_msg"> -		可能原因:模擬器負載過重 -	</floater.string> -	<floater.string name="smaller_label"> -		>> -	</floater.string> -	<floater.string name="bigger_label"> -		<< -	</floater.string> -	<button name="client_lagmeter" tool_tip="客戶端 lag 狀態"/> -	<text name="client"> -		客戶端 -	</text> -	<text name="client_text"> -		正常 -	</text> -	<button name="network_lagmeter" tool_tip="網路 lag 狀態"/> -	<text name="network"> -		網路 -	</text> -	<text name="network_text"> -		正常 -	</text> -	<button name="server_lagmeter" tool_tip="伺服器 lag 狀態"/> -	<text name="server"> -		伺服器 -	</text> -	<text name="server_text"> -		正常 -	</text> -	<button label=">>" name="minimize" tool_tip="切換浮動視窗尺寸"/> -</floater> diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index a331d9aa9e..561c2bb286 100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -37,6 +37,35 @@  #include "llregionhandle.h"  #include "../llvoavatar.h" +namespace LLStatViewer +{ +	LLTrace::SampleStatHandle<>		FPS_SAMPLE("fpssample"); +} + +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts) +{ +	counts.resize(3); +	counts[0] = 0; +	counts[1] = 0; +	counts[2] = 1; +} + +// static +std::string LLVOAvatar::rezStatusToString(S32 rez_status) +{ +	if (rez_status==0) return "cloud"; +	if (rez_status==1) return "gray"; +	if (rez_status==2) return "textured"; +	return "unknown"; +} + +// static +LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name) +{ +	static LLViewerStats::StatsAccumulator junk; +	return junk; +} +  static const char * all_keys[] =   {  	"duration", @@ -199,7 +228,18 @@ get_region(const LLSD & sd, U64 region_handle1)  namespace tut  {  	struct tst_viewerassetstats_index -	{}; +	{ +		tst_viewerassetstats_index() +		{ +			LLTrace::init(); +		} + +		~tst_viewerassetstats_index() +		{ +			LLTrace::cleanup(); +		} + +	};  	typedef test_group<tst_viewerassetstats_index> tst_viewerassetstats_index_t;  	typedef tst_viewerassetstats_index_t::object tst_viewerassetstats_index_object_t;  	tut::tst_viewerassetstats_index_t tut_tst_viewerassetstats_index("tst_viewerassetstats_test"); @@ -209,24 +249,24 @@ namespace tut  	void tst_viewerassetstats_index_object_t::test<1>()  	{  		// Check that helpers aren't bothered by missing global stats -		ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain)); +		ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats)); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_response_main(LLViewerAssetType::AT_GESTURE, false, false, 12300000ULL); +		LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_GESTURE, false, false, 12300000ULL);  	}  	// Create a non-global instance and check the structure  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<2>()  	{ -		ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain)); +		ensure("Global gViewerAssetStats should be NULL", (NULL == gViewerAssetStats));  		LLViewerAssetStats * it = new LLViewerAssetStats(); -		ensure("Global gViewerAssetStatsMain should still be NULL", (NULL == gViewerAssetStatsMain)); +		ensure("Global gViewerAssetStats should still be NULL", (NULL == gViewerAssetStats));  		LLSD sd_full = it->asLLSD(false); @@ -293,17 +333,18 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<4>()  	{ -		gViewerAssetStatsMain = new LLViewerAssetStats(); -		LLViewerAssetStatsFF::set_region_main(region1_handle); +		gViewerAssetStats = new LLViewerAssetStats(); +		LLViewerAssetStatsFF::set_region(region1_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); +		gViewerAssetStats->updateStats();  		LLSD sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd["regions"][0]; @@ -316,11 +357,11 @@ namespace tut  		// Reset and check zeros...  		// Reset leaves current region in place -		gViewerAssetStatsMain->reset(); -		sd = gViewerAssetStatsMain->asLLSD(false)["regions"][region1_handle_str]; +		gViewerAssetStats->reset(); +		sd = gViewerAssetStats->asLLSD(false)["regions"][region1_handle_str]; -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));  		ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); @@ -330,20 +371,18 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<5>()  	{ -		gViewerAssetStatsThread1 = new LLViewerAssetStats(); -		gViewerAssetStatsMain = new LLViewerAssetStats(); -		LLViewerAssetStatsFF::set_region_main(region1_handle); +		gViewerAssetStats = new LLViewerAssetStats(); +		LLViewerAssetStatsFF::set_region(region1_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); -		LLSD sd = gViewerAssetStatsThread1->asLLSD(false); -		ensure("Other collector is empty", is_no_stats_map(sd)); -		sd = gViewerAssetStatsMain->asLLSD(false); -		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration")); +		gViewerAssetStats->updateStats(); +		LLSD sd = gViewerAssetStatsMain->asLLSD(false); +		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));  		sd = sd["regions"][0]; @@ -356,13 +395,11 @@ namespace tut  		// Reset and check zeros...  		// Reset leaves current region in place -		gViewerAssetStatsMain->reset(); -		sd = gViewerAssetStatsMain->asLLSD(false)["regions"][0]; +		gViewerAssetStats->reset(); +		sd = gViewerAssetStats->asLLSD(false)["regions"][0]; -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; -		delete gViewerAssetStatsThread1; -		gViewerAssetStatsThread1 = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));  		ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger())); @@ -372,24 +409,25 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<6>()  	{ -		gViewerAssetStatsMain = new LLViewerAssetStats(); +		gViewerAssetStats = new LLViewerAssetStats(); -		LLViewerAssetStatsFF::set_region_main(region1_handle); +		LLViewerAssetStatsFF::set_region(region1_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::set_region_main(region2_handle); +		LLViewerAssetStatsFF::set_region(region2_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); -		LLSD sd = gViewerAssetStatsMain->asLLSD(false); +		gViewerAssetStats->updateStats(); +		LLSD sd = gViewerAssetStats->asLLSD(false);  		// std::cout << sd << std::endl; @@ -420,8 +458,8 @@ namespace tut  		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));  		sd2 = sd["regions"][0]; -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure("sd2[get_texture_non_temp_udp][enqueued] is reset", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));  		ensure("sd2[get_gesture_udp][enqueued] is reset", (0 == sd2["get_gesture_udp"]["enqueued"].asInteger())); @@ -431,39 +469,40 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<7>()  	{ -		gViewerAssetStatsMain = new LLViewerAssetStats(); +		gViewerAssetStats = new LLViewerAssetStats(); -		LLViewerAssetStatsFF::set_region_main(region1_handle); +		LLViewerAssetStatsFF::set_region(region1_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::set_region_main(region2_handle); +		LLViewerAssetStatsFF::set_region(region2_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::set_region_main(region1_handle); +		LLViewerAssetStatsFF::set_region(region1_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, true, true); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, true, true); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, true, true); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, true, true); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::set_region_main(region2_handle); +		LLViewerAssetStatsFF::set_region(region2_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_GESTURE, false, false); -		LLSD sd = gViewerAssetStatsMain->asLLSD(false); +		gViewerAssetStats->updateStats(); +		LLSD sd = gViewerAssetStats->asLLSD(false);  		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));  		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle)); @@ -493,8 +532,8 @@ namespace tut  		sd2 = get_region(sd, region2_handle);  		ensure("Region2 is present in results", sd2.isMap()); -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure_equals("sd2[get_texture_non_temp_udp][enqueued] is reset", sd2["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);  		ensure_equals("sd2[get_gesture_udp][enqueued] is reset", sd2["get_gesture_udp"]["enqueued"].asInteger(), 0); @@ -504,35 +543,33 @@ namespace tut  	template<> template<>  	void tst_viewerassetstats_index_object_t::test<8>()  	{ -		gViewerAssetStatsThread1 = new LLViewerAssetStats(); -		gViewerAssetStatsMain = new LLViewerAssetStats(); -		LLViewerAssetStatsFF::set_region_main(region1_handle); +		gViewerAssetStats = new LLViewerAssetStats(); +		LLViewerAssetStatsFF::set_region(region1_handle); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, true); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, true); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, false, true); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, false, true); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, false); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, true, false); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, true, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, true); -		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, true); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_BODYPART, true, true); +		LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_BODYPART, true, true); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, false, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, true); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, false, true); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, false); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, false); -		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, true); +		LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		LLSD sd = gViewerAssetStatsThread1->asLLSD(false); -		ensure("Other collector is empty", is_no_stats_map(sd)); +		gViewerAssetStats->updateStats();  		sd = gViewerAssetStatsMain->asLLSD(false);  		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));  		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle)); @@ -551,445 +588,14 @@ namespace tut  		// Reset and check zeros...  		// Reset leaves current region in place -		gViewerAssetStatsMain->reset(); -		sd = get_region(gViewerAssetStatsMain->asLLSD(false), region1_handle); +		gViewerAssetStats->reset(); +		sd = get_region(gViewerAssetStats->asLLSD(false), region1_handle);  		ensure("Region1 is present in results", sd.isMap()); -		delete gViewerAssetStatsMain; -		gViewerAssetStatsMain = NULL; -		delete gViewerAssetStatsThread1; -		gViewerAssetStatsThread1 = NULL; +		delete gViewerAssetStats; +		gViewerAssetStats = NULL;  		ensure_equals("sd[get_texture_non_temp_udp][enqueued] is reset", sd["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);  		ensure_equals("sd[get_gesture_udp][dequeued] is reset", sd["get_gesture_udp"]["dequeued"].asInteger(), 0);  	} - - -	// LLViewerAssetStats::merge() basic functions work -	template<> template<> -	void tst_viewerassetstats_index_object_t::test<9>() -	{ -		LLViewerAssetStats s1; -		LLViewerAssetStats s2; - -		s1.setRegion(region1_handle); -		s2.setRegion(region1_handle); - -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 5000000); -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 6000000); -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 8000000); -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 7000000); -		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 9000000); -		 -		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 2000000); -		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 3000000); -		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 4000000); - -		s2.merge(s1); - -		LLSD s2_llsd = get_region(s2.asLLSD(false), region1_handle); -		ensure("Region1 is present in results", s2_llsd.isMap()); -		 -		ensure_equals("count after merge", s2_llsd["get_texture_temp_http"]["resp_count"].asInteger(), 8); -		ensure_approximately_equals("min after merge", s2_llsd["get_texture_temp_http"]["resp_min"].asReal(), 2.0, 22); -		ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_max"].asReal(), 9.0, 22); -		ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_mean"].asReal(), 5.5, 22); -	} - -	// LLViewerAssetStats::merge() basic functions work without corrupting source data -	template<> template<> -	void tst_viewerassetstats_index_object_t::test<10>() -	{ -		LLViewerAssetStats s1; -		LLViewerAssetStats s2; - -		s1.setRegion(region1_handle); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900); - -		 -		s2.setRegion(region2_handle); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000); -		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000); - -		{ -			s2.merge(s1); -			 -			LLSD src = s1.asLLSD(false); -			LLSD dst = s2.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has dual regions", dst["regions"].size(), 2); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); -			dst["regions"][1].erase("duration"); - -			LLSD s1_llsd = get_region(src, region1_handle); -			ensure("Region1 is present in src", s1_llsd.isMap()); -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure("result from src is in dst", llsd_equals(s1_llsd, s2_llsd)); -		} - -		s1.setRegion(region1_handle); -		s2.setRegion(region1_handle); -		s1.reset(); -		s2.reset(); -		 -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900); - -		 -		s2.setRegion(region1_handle); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000); -		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000); - -		{ -			s2.merge(s1); -			 -			LLSD src = s1.asLLSD(false); -			LLSD dst = s2.asLLSD(false); - -			ensure_equals("merge src has single region (p2)", src["regions"].size(), 1); -			ensure_equals("merge dst has single region (p2)", dst["regions"].size(), 1); - -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); -			 -			LLSD s1_llsd = get_region(src, region1_handle); -			ensure("Region1 is present in src", s1_llsd.isMap()); -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure_equals("src counts okay (enq)", s1_llsd["get_other"]["enqueued"].asInteger(), 4); -			ensure_equals("src counts okay (deq)", s1_llsd["get_other"]["dequeued"].asInteger(), 4); -			ensure_equals("src resp counts okay", s1_llsd["get_other"]["resp_count"].asInteger(), 2); -			ensure_approximately_equals("src respmin okay", s1_llsd["get_other"]["resp_min"].asReal(), 0.2829, 20); -			ensure_approximately_equals("src respmax okay", s1_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20); -			 -			ensure_equals("dst counts okay (enq)", s2_llsd["get_other"]["enqueued"].asInteger(), 12); -			ensure_equals("src counts okay (deq)", s2_llsd["get_other"]["dequeued"].asInteger(), 11); -			ensure_equals("dst resp counts okay", s2_llsd["get_other"]["resp_count"].asInteger(), 4); -			ensure_approximately_equals("dst respmin okay", s2_llsd["get_other"]["resp_min"].asReal(), 0.010, 20); -			ensure_approximately_equals("dst respmax okay", s2_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20); -		} -	} - - -    // Maximum merges are interesting when one side contributes nothing -	template<> template<> -	void tst_viewerassetstats_index_object_t::test<11>() -	{ -		LLViewerAssetStats s1; -		LLViewerAssetStats s2; - -		s1.setRegion(region1_handle); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		// Want to test negative numbers here but have to work in U64 -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - -		s2.setRegion(region1_handle); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		{ -			s2.merge(s1); -			 -			LLSD src = s1.asLLSD(false); -			LLSD dst = s2.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has single region", dst["regions"].size(), 1); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); - -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); -			 -			ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - -			ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum", -										s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20); -		} - -		// Other way around -		s1.setRegion(region1_handle); -		s2.setRegion(region1_handle); -		s1.reset(); -		s2.reset(); - -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		// Want to test negative numbers here but have to work in U64 -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0); - -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		{ -			s1.merge(s2); -			 -			LLSD src = s2.asLLSD(false); -			LLSD dst = s1.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has single region", dst["regions"].size(), 1); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); - -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - -			ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum (flipped)", -										s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20); -		} -	} - -    // Minimum merges are interesting when one side contributes nothing -	template<> template<> -	void tst_viewerassetstats_index_object_t::test<12>() -	{ -		LLViewerAssetStats s1; -		LLViewerAssetStats s2; - -		s1.setRegion(region1_handle); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000); - -		s2.setRegion(region1_handle); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		{ -			s2.merge(s1); -			 -			LLSD src = s1.asLLSD(false); -			LLSD dst = s2.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has single region", dst["regions"].size(), 1); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); - -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - -			ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum", -										s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20); -		} - -		// Other way around -		s1.setRegion(region1_handle); -		s2.setRegion(region1_handle); -		s1.reset(); -		s2.reset(); - -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000); -		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000); - -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); -		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true); - -		{ -			s1.merge(s2); -			 -			LLSD src = s2.asLLSD(false); -			LLSD dst = s1.asLLSD(false); - -			ensure_equals("merge src has single region", src["regions"].size(), 1); -			ensure_equals("merge dst has single region", dst["regions"].size(), 1); -			 -			// Remove time stamps, they're a problem -			src.erase("duration"); -			src["regions"][0].erase("duration"); -			dst.erase("duration"); -			dst["regions"][0].erase("duration"); - -			LLSD s2_llsd = get_region(dst, region1_handle); -			ensure("Region1 is present in dst", s2_llsd.isMap()); - -			ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3); - -			ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum (flipped)", -										s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20); -		} -	} -  } diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 31e1d89c68..62b1d9db62 100755 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -56,7 +56,6 @@ set(test_SOURCE_FILES      llstreamtools_tut.cpp      lltemplatemessagebuilder_tut.cpp      lltut.cpp -    lluuidhashmap_tut.cpp      message_tut.cpp      test.cpp      ) diff --git a/indra/test/io.cpp b/indra/test/io.cpp index e776a2a3be..261422e9fc 100755 --- a/indra/test/io.cpp +++ b/indra/test/io.cpp @@ -44,6 +44,7 @@  #include "llsdrpcclient.h"  #include "llsdrpcserver.h"  #include "llsdserialize.h" +#include "llcommon.h"  #include "lluuid.h"  #include "llinstantmessage.h" @@ -1187,7 +1188,9 @@ namespace tut  				mResponsePtr(response)  			{  			} -			~LLSimpleRPCResponse() {} +			~LLSimpleRPCResponse()  +			{ +			}  			virtual bool response(LLPumpIO* pump)  			{  				*mResponsePtr = mReturnValue; diff --git a/indra/test/llhttpdate_tut.cpp b/indra/test/llhttpdate_tut.cpp index 46684bb9dc..ecf734ee90 100755 --- a/indra/test/llhttpdate_tut.cpp +++ b/indra/test/llhttpdate_tut.cpp @@ -29,6 +29,7 @@  #include "lltut.h"  #include "lldate.h" +#include "llcommon.h"  #include "llframetimer.h"  #include <time.h> @@ -38,6 +39,12 @@ namespace tut  {      struct httpdate_data      { +		httpdate_data()  +		{  +		} +		~httpdate_data()  +		{  +		}          LLDate some_date;      };      typedef test_group<httpdate_data> httpdate_test; diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/test/lliohttpserver_tut.cpp index 2fdc455f45..3fa5c8dd42 100755 --- a/indra/test/lliohttpserver_tut.cpp +++ b/indra/test/lliohttpserver_tut.cpp @@ -31,6 +31,7 @@  #include "lliohttpserver.h"  #include "llsdhttpserver.h"  #include "llsdserialize.h" +#include "llcommon.h"  #include "llpipeutil.h" @@ -81,6 +82,10 @@ namespace tut  			mRoot.addNode("/delayed/echo", new DelayedEcho(this));  			mRoot.addNode("/wire/hello", new LLHTTPNodeForPipe<WireHello>);  		} + +		~HTTPServiceTestData() +		{ +		}  		LLHTTPNode mRoot;  		LLHTTPNode::ResponsePtr mResponse; diff --git a/indra/test/lluuidhashmap_tut.cpp b/indra/test/lluuidhashmap_tut.cpp deleted file mode 100755 index 9712a613f4..0000000000 --- a/indra/test/lluuidhashmap_tut.cpp +++ /dev/null @@ -1,455 +0,0 @@ -/**  - * @file lluuidhashmap_tut.cpp - * @author Adroit - * @date 2007-02 - * @brief Test cases for LLUUIDHashMap - * - * $LicenseInfo:firstyear=2007&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 <tut/tut.hpp> -#include "linden_common.h" -#include "lluuidhashmap.h" -#include "llsdserialize.h" -#include "lldir.h" -#include "stringize.h" -#include <iostream> -#include <fstream> - -namespace tut -{ -	class UUIDTableEntry -	{ -	public: -		UUIDTableEntry() -		{ -			mID.setNull(); -			mValue = 0; -		} -		 -		UUIDTableEntry(const LLUUID& id, U32 value) -		{ -			mID = id; -			mValue = value; -		} - -		~UUIDTableEntry(){}; - -		static BOOL uuidEq(const LLUUID &uuid, const UUIDTableEntry &id_pair) -		{ -			if (uuid == id_pair.mID) -			{ -				return TRUE; -			} -			return FALSE; -		} - -		const LLUUID& getID() { return mID; } -		const U32& getValue() { return mValue; } - -	protected: -		LLUUID	mID; -		U32  mValue; -	}; - -	struct hashmap_test -	{ -	}; - -	typedef test_group<hashmap_test> hash_index_t; -	typedef hash_index_t::object hash_index_object_t; -	tut::hash_index_t tut_hash_index("hashmap_test"); - -	// stress test -	template<> template<> -	void hash_index_object_t::test<1>() -	{ -		set_test_name("stress test"); -		// As of 2012-10-10, I (nat) have observed sporadic failures of this -		// test: "set/get did not work." The trouble is that since test data -		// are randomly generated with every run, it is impossible to debug a -		// test failure. One is left with the uneasy suspicion that -		// LLUUID::generate() can sometimes produce duplicates even within the -		// moderately small number requested here. Since rerunning the test -		// generally allows it to pass, it's too easy to shrug and forget it. -		// The following code is intended to support reproducing such test -		// failures. The idea is that, on test failure, we save the generated -		// data to a canonical filename in a temp directory. Then on every -		// subsequent run, we check for that filename. If it exists, we reload -		// that specific data rather than generating fresh data -- which -		// should presumably reproduce the same test failure. But we inform -		// the user that to resume normal (random) test runs, s/he need only -		// delete that file. And since it's in a temp directory, sooner or -		// later the system will clean it up anyway. -		const char* tempvar = "TEMP"; -		const char* tempdir = getenv(tempvar); // Windows convention -		if (! tempdir) -		{ -			tempvar = "TMPDIR"; -			tempdir = getenv(tempvar); // Mac convention -		} -		if (! tempdir) -		{ -			// reset tempvar to the first var we check; it's just a -			// recommendation -			tempvar = "TEMP"; -			tempdir = "/tmp";		// Posix in general -		} -		std::string savefile(gDirUtilp->add(tempdir, "lluuidhashmap_tut.save.txt")); -		const int numElementsToCheck = 32*256*32; -		std::vector<LLUUID> idList; -		if ((! getenv("TEAMCITY_PROJECT_NAME")) && gDirUtilp->fileExists(savefile)) -		{ -			// This is not a TeamCity build, and we have saved data from a -			// previous failed run. Reload that data. -			std::ifstream inf(savefile.c_str()); -			if (! inf.is_open()) -			{ -				fail(STRINGIZE("Although save file '" << savefile << "' exists, it cannot be opened")); -			} -			std::string item; -			while (std::getline(inf, item)) -			{ -				idList.push_back(LLUUID(item)); -			} -			std::cout << "Reloaded " << idList.size() << " items from '" << savefile << "'"; -			if (idList.size() != numElementsToCheck) -			{ -				std::cout << " (expected " << numElementsToCheck << ")"; -			} -			std::cout << " -- delete this file to generate new data" << std::endl; -		} -		else -		{ -			// This is a TeamCity build, or (normal case) savefile does not -			// exist: regenerate idList from scratch. -			for (int i = 0; i < numElementsToCheck; ++i) -			{ -				LLUUID id; -				id.generate(); -				idList.push_back(id); -			} -		} - -		LLUUIDHashMap<UUIDTableEntry, 32>	hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); -		int i; -		 -		for (i = 0; i < idList.size(); ++i) -		{ -			UUIDTableEntry entry(idList[i], i); -			hashTable.set(idList[i], entry); -		} - -		try -		{ -			for (i = 0; i < idList.size(); i++) -			{ -				LLUUID idToCheck = idList[i]; -				UUIDTableEntry entryToCheck = hashTable.get(idToCheck); -				ensure_equals(STRINGIZE("set/get ID (entry " << i << ")").c_str(), -							  entryToCheck.getID(), idToCheck); -				ensure_equals(STRINGIZE("set/get value (ID " << idToCheck << ")").c_str(), -							  entryToCheck.getValue(), (size_t)i); -			} - -			for (i = 0; i < idList.size(); i++) -			{ -				LLUUID idToCheck = idList[i]; -				if (i % 2 != 0) -				{ -					hashTable.remove(idToCheck); -				} -			} - -			for (i = 0; i < idList.size(); i++) -			{ -				LLUUID idToCheck = idList[i]; -				ensure("remove or check did not work", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck))); -			} -		} -		catch (const failure&) -		{ -			// One of the above tests failed. Try to save idList to repro with -			// a later run. -			std::ofstream outf(savefile.c_str()); -			if (! outf.is_open()) -			{ -				// Sigh, don't use fail() here because we want to preserve -				// the original test failure. -				std::cout << "Cannot open file '" << savefile -						  << "' to save data -- check and fix " << tempvar << std::endl; -			} -			else -			{ -				// outf.is_open() -				for (int i = 0; i < idList.size(); ++i) -				{ -					outf << idList[i] << std::endl; -				} -				std::cout << "Saved " << idList.size() << " entries to '" << savefile -						  << "' -- rerun test to debug with these" << std::endl; -			} -			// re-raise the same exception -- we WANT this test failure to -			// be reported! We just needed to save the data on the way out. -			throw; -		} -	} - -	// test removing all but one element.  -	template<> template<> -	void hash_index_object_t::test<2>() -	{ -		LLUUIDHashMap<UUIDTableEntry, 2>	hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); -		const int numElementsToCheck = 5; -		std::vector<LLUUID> idList(numElementsToCheck*10); -		int i; -		 -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID id; -			id.generate(); -			UUIDTableEntry entry(id, i); -			hashTable.set(id, entry); -			idList[i] = id; -		} - -		ensure("getLength failed", hashTable.getLength() == numElementsToCheck); - -		// remove all but the last element -		for (i = 0; i < numElementsToCheck-1; i++) -		{ -			LLUUID idToCheck = idList[i]; -			hashTable.remove(idToCheck); -		} - -		// there should only be one element left now. -		ensure("getLength failed", hashTable.getLength() == 1); - -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID idToCheck = idList[i]; -			if (i != numElementsToCheck - 1) -			{ -				ensure("remove did not work", hashTable.check(idToCheck)  == FALSE); -			} -			else -			{ -				UUIDTableEntry entryToCheck = hashTable.get(idToCheck); -				ensure("remove did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i); -			} -		} -	} - -	// test overriding of value already set.  -	template<> template<> -	void hash_index_object_t::test<3>() -	{ -		LLUUIDHashMap<UUIDTableEntry, 5>	hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); -		const int numElementsToCheck = 10; -		std::vector<LLUUID> idList(numElementsToCheck); -		int i; -		 -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID id; -			id.generate(); -			UUIDTableEntry entry(id, i); -			hashTable.set(id, entry); -			idList[i] = id; -		} - -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID id = idList[i]; -			// set new entry with value = i+numElementsToCheck -			UUIDTableEntry entry(id, i+numElementsToCheck); -			hashTable.set(id, entry); -		} - -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID idToCheck = idList[i]; -			UUIDTableEntry entryToCheck = hashTable.get(idToCheck); -			ensure("set/get did not work", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)(i+numElementsToCheck)); -		} -	} - -	// test removeAll()  -	template<> template<> -	void hash_index_object_t::test<4>() -	{ -		LLUUIDHashMap<UUIDTableEntry, 5>	hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); -		const int numElementsToCheck = 10; -		std::vector<LLUUID> idList(numElementsToCheck); -		int i; -		 -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID id; -			id.generate(); -			UUIDTableEntry entry(id, i); -			hashTable.set(id, entry); -			idList[i] = id; -		} - -		hashTable.removeAll(); -		ensure("removeAll failed", hashTable.getLength() == 0); -	} - - -	// test sparse map - force it by creating 256 entries that fall into 256 different nodes  -	template<> template<> -	void hash_index_object_t::test<5>() -	{ -		LLUUIDHashMap<UUIDTableEntry, 2>	hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); -		const int numElementsToCheck = 256; -		std::vector<LLUUID> idList(numElementsToCheck); -		int i; -		 -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID id; -			id.generate(); -			// LLUUIDHashMap uses mData[0] to pick the bucket -			// overwrite mData[0] so that it ranges from 0 to 255 -			id.mData[0] = i;  -			UUIDTableEntry entry(id, i); -			hashTable.set(id, entry); -			idList[i] = id; -		} - -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID idToCheck = idList[i]; -			UUIDTableEntry entryToCheck = hashTable.get(idToCheck); -			ensure("set/get did not work for sparse map", entryToCheck.getID() == idToCheck && entryToCheck.getValue() == (size_t)i); -		} - -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID idToCheck = idList[i]; -			if (i % 2 != 0) -			{ -				hashTable.remove(idToCheck); -			} -		} - -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID idToCheck = idList[i]; -			ensure("remove or check did not work for sparse map", (i % 2 == 0 && hashTable.check(idToCheck)) || (i % 2 != 0 && !hashTable.check(idToCheck))); -		} -	} - -	// iterator -	template<> template<> -	void hash_index_object_t::test<6>() -	{ -		LLUUIDHashMap<UUIDTableEntry, 2>	hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); -		LLUUIDHashMapIter<UUIDTableEntry, 2> hashIter(&hashTable); -		const int numElementsToCheck = 256; -		std::vector<LLUUID> idList(numElementsToCheck); -		int i; -		 -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID id; -			id.generate(); -			// LLUUIDHashMap uses mData[0] to pick the bucket -			// overwrite mData[0] so that it ranges from 0 to 255 -			// to create a sparse map -			id.mData[0] = i;  -			UUIDTableEntry entry(id, i); -			hashTable.set(id, entry); -			idList[i] = id; -		} - -		hashIter.first(); -		int numElementsIterated = 0; -		while(!hashIter.done()) -		{ -			numElementsIterated++; -			UUIDTableEntry tableEntry = *hashIter; -			LLUUID id = tableEntry.getID(); -			hashIter.next(); -			ensure("Iteration failed for sparse map", tableEntry.getValue() < (size_t)numElementsToCheck && idList[tableEntry.getValue()] ==  tableEntry.getID()); -		} - -		ensure("iteration count failed", numElementsIterated == numElementsToCheck); -	} - -	// remove after middle of iteration -	template<> template<> -	void hash_index_object_t::test<7>() -	{ -		LLUUIDHashMap<UUIDTableEntry, 2>	hashTable(UUIDTableEntry::uuidEq, UUIDTableEntry()); -		LLUUIDHashMapIter<UUIDTableEntry, 2> hashIter(&hashTable); -		const int numElementsToCheck = 256; -		std::vector<LLUUID> idList(numElementsToCheck); -		int i; -		 -		LLUUID uuidtoSearch; -		for (i = 0; i < numElementsToCheck; i++) -		{ -			LLUUID id; -			id.generate(); -			// LLUUIDHashMap uses mData[0] to pick the bucket -			// overwrite mData[0] so that it ranges from 0 to 255 -			// to create a sparse map -			id.mData[0] = i;  -			UUIDTableEntry entry(id, i); -			hashTable.set(id, entry); -			idList[i] = id; - -			// pick uuid somewhere in the middle -			if (i == 5) -			{ -				uuidtoSearch = id; -			} -		} - -		hashIter.first(); -		int numElementsIterated = 0; -		while(!hashIter.done()) -		{ -			numElementsIterated++; -			UUIDTableEntry tableEntry = *hashIter; -			LLUUID id = tableEntry.getID(); -			if (uuidtoSearch == id) -			{ -				break; -			} -			hashIter.next(); -		} - -		// current iterator implementation will not allow any remove operations -		// until ALL elements have been iterated over. this seems to be  -		// an unnecessary restriction. Iterator should have a method to -		// reset() its state so that further operations (inckuding remove) -		// can be performed on the HashMap without having to iterate thru  -		// all the remaining nodes.  -		 -//		 hashIter.reset(); -//		 hashTable.remove(uuidtoSearch); -//		 ensure("remove after iteration reset failed", hashTable.check(uuidtoSearch) == FALSE); -	} -} diff --git a/indra/test/test.cpp b/indra/test/test.cpp index dc8580fe69..28de88201c 100755 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -40,6 +40,7 @@  #include "tests/wrapllerrs.h"             // RecorderProxy  #include "stringize.h"  #include "namedtempfile.h" +#include "lltrace.h"  #include "apr_pools.h"  #include "apr_getopt.h" @@ -512,15 +513,11 @@ int main(int argc, char **argv)  	ctype_workaround();  #endif -	apr_initialize(); -	apr_pool_t* pool = NULL; -	if(APR_SUCCESS != apr_pool_create(&pool, NULL)) -	{ -		std::cerr << "Unable to initialize pool" << std::endl; -		return 1; -	} +	ll_init_apr(); +	 +	LLTrace::init();  	apr_getopt_t* os = NULL; -	if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv)) +	if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, argc, argv))  	{  		std::cerr << "apr_getopt_init() failed" << std::endl;  		return 1; @@ -602,7 +599,7 @@ int main(int argc, char **argv)  	if (LOGFAIL)  	{  		LLError::ELevel level = LLError::decodeLevel(LOGFAIL); -		replayer.reset(new LLReplayLogReal(level, pool)); +		replayer.reset(new LLReplayLogReal(level, gAPRPoolp));  	}  	else  	{ @@ -646,7 +643,7 @@ int main(int argc, char **argv)  		s.close();  	} -	apr_terminate(); +	ll_cleanup_apr();  	int retval = (success ? 0 : 1);  	return retval; diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index 884b00f0cc..fa4f5abd28 100755 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -37,6 +37,12 @@  #include "llmediaplugintest.h" + +#if LL_WINDOWS +#pragma warning(disable: 4263) +#pragma warning(disable: 4264) +#endif +  #if __APPLE__  	#include <GLUT/glut.h>  	#include <CoreFoundation/CoreFoundation.h> @@ -46,10 +52,6 @@  	#define GLUI_FREEGLUT  #endif -#if LL_WINDOWS -#pragma warning(disable: 4263) -#pragma warning(disable: 4264) -#endif  #include "glui.h"  | 
