diff options
Diffstat (limited to 'indra/newview')
58 files changed, 2103 insertions, 436 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 753dbd7438..2c9952cbc8 100644..100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -437,6 +437,7 @@ set(viewer_SOURCE_FILES      llpathfindingpathtool.cpp      llphysicsmotion.cpp      llphysicsshapebuilderutil.cpp +    llpipelinelistener.cpp      llplacesinventorybridge.cpp      llplacesinventorypanel.cpp      llpopupview.cpp @@ -1002,6 +1003,7 @@ set(viewer_HEADER_FILES      llpathfindingpathtool.h      llphysicsmotion.h      llphysicsshapebuilderutil.h +    llpipelinelistener.h      llplacesinventorybridge.h      llplacesinventorypanel.h      llpolymesh.h diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 64122bbb6c..64122bbb6c 100644..100755 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9e2c529eb3..53d0926224 100644..100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -71,6 +71,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>AgentAppearanceServiceURL</key> +    <map> +      <key>Comment</key> +      <string>Current Session Agent Appearance Service URL</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string></string> +    </map>      <key>AlertedUnsupportedHardware</key>      <map>        <key>Comment</key> @@ -3270,6 +3281,17 @@          <key>Value</key>          <integer>0</integer>      </map> +    <key>FastCacheFetchEnabled</key> +    <map> +      <key>Comment</key> +      <string>Enable texture fast cache fetching if set</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <string>1</string> +    </map>  	<key>FeatureManagerHTTPTable</key>        <map>          <key>Comment</key> @@ -8705,6 +8727,28 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>DisableAllRenderTypes</key> +    <map> +      <key>Comment</key> +      <string>Disables all rendering types.</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>DisableAllRenderFeatures</key> +    <map> +      <key>Comment</key> +      <string>Disables all rendering features.</string> +      <key>Persist</key> +      <integer>0</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>RenderHUDInSnapshot</key>      <map>        <key>Comment</key> @@ -10789,6 +10833,83 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>TextureFetchSource</key> +    <map> +      <key>Comment</key> +      <string>Debug use: Source to fetch textures</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>TextureFetchUpdateHighPriority</key> +    <map> +      <key>Comment</key> +      <string>Number of high priority textures to update per frame</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>32</integer> +    </map> +    <key>TextureFetchUpdateMaxMediumPriority</key> +    <map> +      <key>Comment</key> +      <string>Maximum number of medium priority textures to update per frame</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>256</integer> +    </map> +    <key>TextureFetchUpdateMinMediumPriority</key> +    <map> +      <key>Comment</key> +      <string>Minimum number of medium priority textures to update per frame</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>32</integer> +    </map> +    <key>TextureFetchUpdatePriorityThreshold</key> +    <map> +      <key>Comment</key> +      <string>Threshold under which textures will be considered too low priority and skipped for update</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>0.0</integer> +    </map> +    <key>TextureFetchUpdateSkipLowPriority</key> +    <map> +      <key>Comment</key> +      <string>Flag indicating if we want to skip textures with too low of a priority</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>TextureFetchUpdatePriorities</key> +    <map> +      <key>Comment</key> +      <string>Number of priority texture to update per frame</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>32</integer> +    </map>      <key>TextureLoadFullRes</key>      <map>        <key>Comment</key> @@ -12263,6 +12384,17 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>UseServerTextureBaking</key> +    <map> +      <key>Comment</key> +      <string>Update appearance via the ServerTextureBaking cap, if available</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> @@ -13010,6 +13142,28 @@        <key>Value</key>        <integer>-1</integer>      </map> +    <key>MaxFPS</key> +    <map> +      <key>Comment</key> +      <string>Yield some time to the local host if we reach a threshold framerate.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>-1.0</integer> +    </map> +    <key>ForcePeriodicRenderingTime</key> +    <map> +      <key>Comment</key> +      <string>Periodically enable all rendering masks for a single frame.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <integer>-1.0</integer> +    </map>      <key>ZoomDirect</key>      <map>        <key>Comment</key> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 99dbfcae51..2b090c4fa4 100644..100755 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -12291,6 +12291,17 @@ render_pass="bump">  	 <param_driver />      </param> +    <param +     id="11000" +     group="0" +     name="AppearanceMessage_Version" +     label="AppearanceMessage Version" +     value_default="0" +     value_min="0" +     value_max="255"> +	 <param_driver /> +    </param> +    </driver_parameters>    <morph_masks> diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 20936c6460..fa9ce703a8 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -117,18 +117,32 @@ export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"  # Simply embedding $(<etc/gridargs.dat) into a command line treats each of  # Second, Life and Developer as separate args -- no good. We need bash to  # process quotes using eval. -# First read it without scanning, then scan that string. Break quoted words +# First, check if we have been instructed to skip reading in gridargs.dat: +skip_gridargs=false +argnum=0 +for ARG in "$@"; do +    if [ "--skip-gridargs" == "$ARG" ]; then +        skip_gridargs=true +    else +        ARGS[$argnum]="$ARG" +        argnum=$(($argnum+1)) +    fi +done + +# Second, read it without scanning, then scan that string. Break quoted words  # into a bash array. Note that if gridargs.dat is empty, or contains only  # whitespace, the resulting gridargs array will be empty -- zero entries --  # therefore "${gridargs[@]}" entirely vanishes from the command line below,  # just as we want. -eval gridargs=("$(<etc/gridargs.dat)") +if ! $skip_gridargs ; then +    eval gridargs=("$(<etc/gridargs.dat)") +fi  # Run the program.  # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the  # command line. But DO quote "$@": preserve separate args as individually  # quoted. Similar remarks about the contents of gridargs. -$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "$@" +$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}"  LL_RUN_ERR=$?  # Handle any resulting errors diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 447836910d..698f89ef26 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -35,6 +35,7 @@  #include "llagentlistener.h"  #include "llagentwearables.h"  #include "llagentui.h" +#include "llappearancemgr.h"  #include "llanimationstates.h"  #include "llcallingcard.h"  #include "llcapabilitylistener.h" @@ -4259,7 +4260,7 @@ void LLAgent::requestLeaveGodMode()  //-----------------------------------------------------------------------------  void LLAgent::sendAgentSetAppearance()  { -	if (!isAgentAvatarValid()) return; +	if (!isAgentAvatarValid() || LLAppearanceMgr::instance().useServerTextureBaking()) return;  	if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))   	{ diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 751b73e1eb..a544909e66 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2251,7 +2251,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)  //-----------------------------------------------------------------------------  void LLAgentCamera::changeCameraToCustomizeAvatar()  { -	if (LLViewerJoystick::getInstance()->getOverrideCamera()) +	if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid())  	{  		return;  	} @@ -2275,29 +2275,21 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()  		gFocusMgr.setKeyboardFocus( NULL );  		gFocusMgr.setMouseCapture( NULL ); -		LLVOAvatarSelf::onCustomizeStart(); - -		if (isAgentAvatarValid()) -		{ -			// Remove any pitch or rotation from the avatar -			LLVector3 at = gAgent.getAtAxis(); -			at.mV[VZ] = 0.f; -			at.normalize(); -			gAgent.resetAxes(at); - -			gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); -			gAgent.setCustomAnim(TRUE); -			gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); -			LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); +		// Remove any pitch or rotation from the avatar +		LLVector3 at = gAgent.getAtAxis(); +		at.mV[VZ] = 0.f; +		at.normalize(); +		gAgent.resetAxes(at); -			if (turn_motion) -			{ -				// delay camera animation long enough to play through turn animation -				setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); -			} +		gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); +		gAgent.setCustomAnim(TRUE); +		gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE); +		LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE); -			gAgentAvatarp->invalidateAll(); -			gAgentAvatarp->updateMeshTextures(); +		if (turn_motion) +		{ +			// delay camera animation long enough to play through turn animation +			setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);  		}  	} diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index e441f21f90..0a721312f3 100644..100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1597,7 +1597,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n  void LLAgentWearables::queryWearableCache()  { -	if (!areWearablesLoaded()) +	if (!areWearablesLoaded() || LLAppearanceMgr::instance().useServerTextureBaking())  	{  		return;  	} diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 5932be21c6..5932be21c6 100644..100755 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 6d67e098a6..0c7f89203e 100644..100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -926,6 +926,18 @@ const LLUUID LLAppearanceMgr::getCOF() const  	return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);  } +S32 LLAppearanceMgr::getCOFVersion() const +{ +	LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF()); +	if (cof) +	{ +		return cof->getVersion(); +	} +	else +	{ +		return LLViewerInventoryCategory::VERSION_UNKNOWN; +	} +}  const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()  { @@ -1731,6 +1743,12 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)  	// the saved outfit stored as a folder link  	updateIsDirty(); +	// Send server request for appearance update +	if (useServerTextureBaking()) +	{ +		requestServerAppearanceUpdate(); +	} +	  	//dumpCat(getCOF(),"COF, start");  	bool follow_folder_links = true; @@ -2582,8 +2600,43 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base  	if (inventory_changed) gInventory.notifyObservers();  } +// Should be true iff both the appropriate debug setting is enabled +// and the corresponding cap has been found. +bool LLAppearanceMgr::useServerTextureBaking() +{ +	// TODO: add cap check. +	return gSavedSettings.getBOOL("UseServerTextureBaking"); +} +class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder +{ +public: +	RequestAgentUpdateAppearanceResponder() {} +	/*virtual*/ void error(U32 status, const std::string& reason) +	{ +		llwarns << "appearance update request failed, reason: " << reason << llendl; +	}	 +}; +void LLAppearanceMgr::requestServerAppearanceUpdate() +{ +	if (!gAgent.getRegion()) +	{ +		llwarns << "Region not set, cannot request server appearance update" << llendl; +	} +	std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");	 +	if (url.empty()) +	{ +		llwarns << "no cap for UpdateAvatarAppearance" << llendl; +	} +	 +	LLSD body; +	S32 cof_version = getCOFVersion(); +	body["cof_version"] = cof_version; +	LLHTTPClient::post(url, body, new RequestAgentUpdateAppearanceResponder); +	llassert(cof_version >= mLastUpdateRequestCOFVersion); +	mLastUpdateRequestCOFVersion = cof_version; +}  class LLShowCreatedOutfit: public LLInventoryCallback  { @@ -2795,7 +2848,8 @@ LLAppearanceMgr::LLAppearanceMgr():  	mAttachmentInvLinkEnabled(false),  	mOutfitIsDirty(false),  	mOutfitLocked(false), -	mIsInUpdateAppearanceFromCOF(false) +	mIsInUpdateAppearanceFromCOF(false), +	mLastUpdateRequestCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)  {  	LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index c1d561781d..45291419c7 100644..100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -93,6 +93,9 @@ public:  	// Find the Current Outfit folder.  	const LLUUID getCOF() const; +	S32 getCOFVersion() const; + +	S32 mLastUpdateRequestCOFVersion;  	// Finds the folder link to the currently worn outfit  	const LLViewerInventoryItem *getBaseOutfitLink(); @@ -182,6 +185,10 @@ public:  	bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; } +	bool useServerTextureBaking(); + +	void requestServerAppearanceUpdate(); +  protected:  	LLAppearanceMgr();  	~LLAppearanceMgr(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 63737c78d0..5d5528cac7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -633,7 +633,6 @@ LLAppViewer::LLAppViewer() :  	mForceGraphicsDetail(false),  	mQuitRequested(false),  	mLogoutRequestSent(false), -	mYieldTime(-1),  	mMainloopTimeout(NULL),  	mAgentRegionLastAlive(false),  	mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)), @@ -1204,7 +1203,7 @@ bool LLAppViewer::mainLoop()  	LLVoiceChannel::initClass();  	LLVoiceClient::getInstance()->init(gServicePump);  	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1), true); -	LLTimer frameTimer,idleTimer; +	LLTimer frameTimer,idleTimer,periodicRenderingTimer;  	LLTimer debugTime;  	LLViewerJoystick* joystick(LLViewerJoystick::getInstance());  	joystick->setNeedsReset(true); @@ -1216,6 +1215,8 @@ bool LLAppViewer::mainLoop()      // point of posting.      LLSD newFrame; +	BOOL restore_rendering_masks = FALSE; +  	//LLPrivateMemoryPoolTester::getInstance()->run(false) ;  	//LLPrivateMemoryPoolTester::getInstance()->run(true) ;  	//LLPrivateMemoryPoolTester::destroy() ; @@ -1233,6 +1234,28 @@ bool LLAppViewer::mainLoop()  		try  		{ +			// Check if we need to restore rendering masks. +			if (restore_rendering_masks) +			{ +				gPipeline.popRenderDebugFeatureMask(); +				gPipeline.popRenderTypeMask(); +			} +			// Check if we need to temporarily enable rendering. +			F32 periodic_rendering = gSavedSettings.getF32("ForcePeriodicRenderingTime"); +			if (periodic_rendering > F_APPROXIMATELY_ZERO && periodicRenderingTimer.getElapsedTimeF64() > periodic_rendering) +			{ +				periodicRenderingTimer.reset(); +				restore_rendering_masks = TRUE; +				gPipeline.pushRenderTypeMask(); +				gPipeline.pushRenderDebugFeatureMask(); +				gPipeline.setAllRenderTypes(); +				gPipeline.setAllRenderDebugFeatures(); +			} +			else +			{ +				restore_rendering_masks = FALSE; +			} +  			pingMainloopTimeout("Main:MiscNativeWindowEvents");  			if (gViewerWindow) @@ -1355,10 +1378,11 @@ bool LLAppViewer::mainLoop()  				LLFastTimer t2(FTM_SLEEP);  				// yield some time to the os based on command line option -				if(mYieldTime >= 0) +				S32 yield_time = gSavedSettings.getS32("YieldTime"); +				if(yield_time >= 0)  				{  					LLFastTimer t(FTM_YIELD); -					ms_sleep(mYieldTime); +					ms_sleep(yield_time);  				}  				// yield cooperatively when not running as foreground window @@ -1470,6 +1494,26 @@ bool LLAppViewer::mainLoop()  				{  					gFrameStalls++;  				} + +				// Limit FPS +				F32 max_fps = gSavedSettings.getF32("MaxFPS"); +				// Only limit FPS when we are actually rendering something.  Otherwise +				// logins, logouts and teleports take much longer to complete. +				if (max_fps > F_APPROXIMATELY_ZERO &&  +					LLStartUp::getStartupState() == STATE_STARTED && +					!gTeleportDisplay && +					!logoutRequestSent()) +				{ +					// Sleep a while to limit frame rate. +					F32 min_frame_time = 1.f / max_fps; +					S32 milliseconds_to_sleep = llclamp((S32)((min_frame_time - frameTimer.getElapsedTimeF64()) * 1000.f), 0, 1000); +					if (milliseconds_to_sleep > 0) +					{ +						LLFastTimer t(FTM_YIELD); +						ms_sleep(milliseconds_to_sleep); +					} +				} +  				frameTimer.reset();  				resumeMainloopTimeout(); @@ -2584,8 +2628,6 @@ bool LLAppViewer::initConfiguration()  		}  	} -    mYieldTime = gSavedSettings.getS32("YieldTime"); -  	// Read skin/branding settings if specified.  	//if (! gDirUtilp->getSkinDir().empty() )  	//{ @@ -4346,6 +4388,10 @@ void LLAppViewer::idle()      {  		return;      } +	if (gTeleportDisplay) +    { +		return; +    }  	gViewerWindow->updateUI(); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index ae3c795d1e..043893020b 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -253,7 +253,6 @@ private:      bool mQuitRequested;				// User wants to quit, may have modified documents open.      bool mLogoutRequestSent;			// Disconnect message sent to simulator, no longer safe to send messages to the sim. -    S32 mYieldTime;  	struct SettingsFiles* mSettingsLocationList;  	LLWatchdogTimeout* mMainloopTimeout; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index fa42b157a7..fa42b157a7 100644..100755 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 8d0664770b..4a0c94df33 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2167,6 +2167,12 @@ BOOL LLFace::hasMedia() const  const F32 LEAST_IMPORTANCE = 0.05f ;  const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ; +void LLFace::resetVirtualSize() +{ +	setVirtualSize(0.f); +	mImportanceToCamera = 0.f; +} +  F32 LLFace::getTextureVirtualSize()  {  	F32 radius; @@ -2232,8 +2238,17 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)  	LLVector4a t;  	t.load3(camera->getOrigin().mV);  	lookAt.setSub(center, t); +	  	F32 dist = lookAt.getLength3().getF32(); -	dist = llmax(dist-size.getLength3().getF32(), 0.f); +	dist = llmax(dist-size.getLength3().getF32(), 0.001f); +	//ramp down distance for nearby objects +	if (dist < 16.f) +	{ +		dist /= 16.f; +		dist *= dist; +		dist *= 16.f; +	} +  	lookAt.normalize3fast() ;	  	//get area of circle around node diff --git a/indra/newview/llface.h b/indra/newview/llface.h index efc3424858..de4d03351c 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -218,6 +218,7 @@ public:  	F32         getTextureVirtualSize() ;  	F32         getImportanceToCamera()const {return mImportanceToCamera ;} +	void        resetVirtualSize();  	void        setHasMedia(bool has_media)  { mHasMedia = has_media ;}  	BOOL        hasMedia() const ; diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp index 2b34b72055..9157389187 100644 --- a/indra/newview/llfloatertexturefetchdebugger.cpp +++ b/indra/newview/llfloatertexturefetchdebugger.cpp @@ -59,12 +59,15 @@ LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key)  	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this));  	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this));  }  //----------------------------------------------  BOOL LLFloaterTextureFetchDebugger::postBuild(void)   {	  	mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); +	mStartStatus = (S32)LLTextureFetchDebugger::IDLE;  	//set states for buttons  	mButtonStateMap["start_btn"] = true; @@ -76,8 +79,10 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void)  	mButtonStateMap["decode_btn"] = false;  	mButtonStateMap["gl_btn"] = false; -	mButtonStateMap["refetchviscache_btn"] = true; -	mButtonStateMap["refetchvishttp_btn"] = true; +	mButtonStateMap["refetchviscache_btn"] = false; +	mButtonStateMap["refetchvishttp_btn"] = false; +	mButtonStateMap["refetchallcache_btn"] = false; +	mButtonStateMap["refetchallhttp_btn"] = false;  	updateButtons(); @@ -89,7 +94,7 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void)  LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger()  {  	//stop everything -	mDebugger->stopDebug(); +	mDebugger->setStopDebug();  }  void LLFloaterTextureFetchDebugger::updateButtons() @@ -118,47 +123,81 @@ void LLFloaterTextureFetchDebugger::disableButtons()  	childDisable("gl_btn");  	childDisable("refetchviscache_btn");  	childDisable("refetchvishttp_btn"); +	childDisable("refetchallcache_btn"); +	childDisable("refetchallhttp_btn"); +} +void LLFloaterTextureFetchDebugger::setStartStatus(S32 status) +{ +	llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ; +	mStartStatus = status; +} +	 +bool LLFloaterTextureFetchDebugger::idleStart() +{ +	if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE) +	{ +		mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus); +		mStartStatus = (S32)LLTextureFetchDebugger::IDLE; +		return true; +	} + +	return false;  }  void LLFloaterTextureFetchDebugger::idle()  {	 -	LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); -	 -	if(mDebugger->update()) +	if(idleStart()) +	{ +		return; +	} + +	const F32 max_time = 0.005f; //5ms +	LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();	 +	if(mDebugger->update(max_time))  	{  		switch(state)  		{  		case LLTextureFetchDebugger::IDLE:  			break; -		case LLTextureFetchDebugger::READ_CACHE: -			mButtonStateMap["cachewrite_btn"] = true; -			mButtonStateMap["decode_btn"] = true; -			updateButtons(); +		case LLTextureFetchDebugger::START_DEBUG: +			mButtonStateMap["cacheread_btn"] = true; +			mButtonStateMap["http_btn"] = true; +			mButtonStateMap["refetchviscache_btn"] = true; +			mButtonStateMap["refetchvishttp_btn"] = true; +			mButtonStateMap["refetchallcache_btn"] = true; +			mButtonStateMap["refetchallhttp_btn"] = true;  			break; -		case LLTextureFetchDebugger::WRITE_CACHE: -			updateButtons(); +		case LLTextureFetchDebugger::READ_CACHE:			 +			mButtonStateMap["decode_btn"] = true;			 +			break; +		case LLTextureFetchDebugger::WRITE_CACHE:			  			break;  		case LLTextureFetchDebugger::DECODING: -			mButtonStateMap["gl_btn"] = true; -			updateButtons(); +			mButtonStateMap["gl_btn"] = true;			  			break;  		case LLTextureFetchDebugger::HTTP_FETCHING:  			mButtonStateMap["cacheread_btn"] = true;  			mButtonStateMap["cachewrite_btn"] = true; -			mButtonStateMap["decode_btn"] = true; -			updateButtons(); +			mButtonStateMap["decode_btn"] = true;			  			break; -		case LLTextureFetchDebugger::GL_TEX: -			updateButtons(); +		case LLTextureFetchDebugger::GL_TEX:			  			break; -		case LLTextureFetchDebugger::REFETCH_VIS_CACHE: -			updateButtons(); -		case LLTextureFetchDebugger::REFETCH_VIS_HTTP: -			updateButtons(); +		case LLTextureFetchDebugger::REFETCH_VIS_CACHE:			 +			break; +		case LLTextureFetchDebugger::REFETCH_VIS_HTTP:			 +			break; +		case LLTextureFetchDebugger::REFETCH_ALL_CACHE:			 +			break; +		case LLTextureFetchDebugger::REFETCH_ALL_HTTP:  			break;  		default:  			break;  		} + +		if(state != LLTextureFetchDebugger::IDLE) +		{ +			updateButtons(); +		}  	}  } @@ -172,11 +211,10 @@ void LLFloaterTextureFetchDebugger::onClickStart()  {  	disableButtons(); -	mDebugger->startDebug(); +	setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG);	  	mButtonStateMap["start_btn"] = false; -	mButtonStateMap["cacheread_btn"] = true; -	mButtonStateMap["http_btn"] = true; +  	updateButtons();  } @@ -185,7 +223,9 @@ void LLFloaterTextureFetchDebugger::onClickClose()  	setVisible(FALSE);  	//stop everything -	mDebugger->stopDebug(); +	mDebugger->setStopDebug(); + +	delete this;  }  void LLFloaterTextureFetchDebugger::onClickClear() @@ -203,7 +243,7 @@ void LLFloaterTextureFetchDebugger::onClickClear()  	updateButtons();  	//stop everything -	mDebugger->stopDebug(); +	mDebugger->setStopDebug();  	mDebugger->clearHistory();  } @@ -211,49 +251,63 @@ void LLFloaterTextureFetchDebugger::onClickCacheRead()  {  	disableButtons(); -	mDebugger->debugCacheRead(); +	setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE);  }  void LLFloaterTextureFetchDebugger::onClickCacheWrite()  {  	disableButtons(); -	mDebugger->debugCacheWrite(); +	setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE);  }  void LLFloaterTextureFetchDebugger::onClickHTTPLoad()  {  	disableButtons(); -	mDebugger->debugHTTP(); +	setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING);  }  void LLFloaterTextureFetchDebugger::onClickDecode()  {  	disableButtons(); -	mDebugger->debugDecoder(); +	setStartStatus((S32)LLTextureFetchDebugger::DECODING);  }  void LLFloaterTextureFetchDebugger::onClickGLTexture()  {  	disableButtons(); -	mDebugger->debugGLTextureCreation(); +	setStartStatus((S32)LLTextureFetchDebugger::GL_TEX);	  }  void LLFloaterTextureFetchDebugger::onClickRefetchVisCache()  {  	disableButtons(); -	mDebugger->debugRefetchVisibleFromCache(); +	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE);  }  void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP()  {  	disableButtons(); -	mDebugger->debugRefetchVisibleFromHTTP(); +	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP);	 +} + +void LLFloaterTextureFetchDebugger::onClickRefetchAllCache() +{ +	disableButtons(); + +	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP() +{ +	disableButtons(); + +	setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP);	  }  void LLFloaterTextureFetchDebugger::draw() @@ -368,8 +422,22 @@ void LLFloaterTextureFetchDebugger::draw()  	else  	{  		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime())); -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); -		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); +	} + +	//total time on refetching all textures from cache +	if(mDebugger->getRefetchAllCacheTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime())); +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));  	}  	//total time on refetching visible textures from http @@ -382,8 +450,22 @@ void LLFloaterTextureFetchDebugger::draw()  	else  	{  		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime())); -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10)); -		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f)); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f)); +	} + +	//total time on refetching all textures from http +	if(mDebugger->getRefetchAllHTTPTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime())); +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10)); +		getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));  	}  	LLFloater::draw(); diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h index 33012c6a3d..096ad88e07 100644 --- a/indra/newview/llfloatertexturefetchdebugger.h +++ b/indra/newview/llfloatertexturefetchdebugger.h @@ -53,6 +53,8 @@ public:  	void onClickRefetchVisCache();  	void onClickRefetchVisHTTP(); +	void onClickRefetchAllCache(); +	void onClickRefetchAllHTTP();  public:  	void idle() ; @@ -63,9 +65,12 @@ private:  	void updateButtons();  	void disableButtons(); +	void setStartStatus(S32 status); +	bool idleStart();  private:	  	LLTextureFetchDebugger* mDebugger;  	std::map<std::string, bool> mButtonStateMap; +	S32 mStartStatus;  };  #endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 6e23d7c701..6e23d7c701 100644..100755 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index eaa044cb59..252d1b78ea 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -99,8 +99,6 @@ void	LLMorphView::initialize()  //-----------------------------------------------------------------------------  void	LLMorphView::shutdown()  { -	LLVOAvatarSelf::onCustomizeEnd(); -  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE ); diff --git a/indra/newview/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp new file mode 100644 index 0000000000..20759239bf --- /dev/null +++ b/indra/newview/llpipelinelistener.cpp @@ -0,0 +1,216 @@ +/** + * @file   llpipelinelistener.h + * @author Don Kjer + * @date   2012-07-09 + * @brief  Implementation for LLPipelineListener + *  + * $LicenseInfo:firstyear=2012&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$ + */ + +// Precompiled header +#include "llviewerprecompiledheaders.h" + +#include "llpipelinelistener.h" + +#include "pipeline.h" +#include "stringize.h" +#include <sstream> +#include "llviewermenu.h" + + +namespace { +	// Render Types +	void toggle_render_types_wrapper(LLSD const& request) +	{ +		for (LLSD::array_const_iterator iter = request["types"].beginArray(); +			iter != request["types"].endArray(); +			++iter) +		{ +			U32 render_type = render_type_from_string( iter->asString() ); +			if ( render_type != 0 ) +			{ +				LLPipeline::toggleRenderTypeControl( (void*) render_type ); +			} +		} +	} + +	void has_render_type_wrapper(LLSD const& request) +	{ +		LLEventAPI::Response response(LLSD(), request); +		U32 render_type = render_type_from_string( request["type"].asString() ); +		if ( render_type != 0 ) +		{ +			response["value"] = LLPipeline::hasRenderTypeControl( (void*) render_type ); +		} +		else +		{ +			response.error(STRINGIZE("unknown type '" << request["type"].asString() << "'")); +		} +	} + +	void disable_all_render_types_wrapper(LLSD const& request) +	{ +		gPipeline.clearAllRenderTypes(); +	} + +	void enable_all_render_types_wrapper(LLSD const& request) +	{ +		gPipeline.setAllRenderTypes(); +	} + +	// Render Features +	void toggle_render_features_wrapper(LLSD const& request) +	{ +		for (LLSD::array_const_iterator iter = request["features"].beginArray(); +			iter != request["features"].endArray(); +			++iter) +		{ +			U32 render_feature = feature_from_string( iter->asString() ); +			if ( render_feature != 0 ) +			{ +				LLPipeline::toggleRenderDebugControl( (void*) render_feature ); +			} +		} +	} + +	void has_render_feature_wrapper(LLSD const& request) +	{ +		LLEventAPI::Response response(LLSD(), request); +		U32 render_feature = feature_from_string( request["feature"].asString() ); +		if ( render_feature != 0 ) +		{ +			response["value"] = gPipeline.hasRenderDebugFeatureMask(render_feature); +		} +		else +		{ +			response.error(STRINGIZE("unknown feature '" << request["feature"].asString() << "'")); +		} +	} + +	void disable_all_render_features_wrapper(LLSD const& request) +	{ +		gPipeline.clearAllRenderDebugFeatures(); +	} + +	void enable_all_render_features_wrapper(LLSD const& request) +	{ +		gPipeline.setAllRenderDebugFeatures(); +	} + +	// Render Info Displays +	void toggle_info_displays_wrapper(LLSD const& request) +	{ +		for (LLSD::array_const_iterator iter = request["displays"].beginArray(); +			iter != request["displays"].endArray(); +			++iter) +		{ +			U32 info_display = info_display_from_string( iter->asString() ); +			if ( info_display != 0 ) +			{ +				LLPipeline::toggleRenderDebug( (void*) info_display ); +			} +		} +	} + +	void has_info_display_wrapper(LLSD const& request) +	{ +		LLEventAPI::Response response(LLSD(), request); +		U32 info_display = info_display_from_string( request["display"].asString() ); +		if ( info_display != 0 ) +		{ +			response["value"] = gPipeline.hasRenderDebugMask(info_display); +		} +		else +		{ +			response.error(STRINGIZE("unknown display '" << request["display"].asString() << "'")); +		} +	} + +	void disable_all_info_displays_wrapper(LLSD const& request) +	{ +		gPipeline.clearAllRenderDebugDisplays(); +	} + +	void enable_all_info_displays_wrapper(LLSD const& request) +	{ +		gPipeline.setAllRenderDebugDisplays(); +	} + +} + + +LLPipelineListener::LLPipelineListener(): +	LLEventAPI("LLPipeline", +			   "API to te rendering pipeline.") +{ +	// Render Types +	add("toggleRenderTypes", +		"Toggle rendering [\"types\"]:\n" +		"See: llviewermenu.cpp:render_type_from_string for list of available types.", +		&toggle_render_types_wrapper); +	add("hasRenderType", +		"Check if rendering [\"type\"] is enabled:\n" +		"See: llviewermenu.cpp:render_type_from_string for list of available types.", +		&has_render_type_wrapper, +		LLSDMap("reply", LLSD())); +	add("disableAllRenderTypes", +		"Turn off all rendering types.", +		&disable_all_render_types_wrapper); +	add("enableAllRenderTypes", +		"Turn on all rendering types.", +		&enable_all_render_types_wrapper); + +	// Render Features +	add("toggleRenderFeatures", +		"Toggle rendering [\"features\"]:\n" +		"See: llviewermenu.cpp:feature_from_string for list of available features.", +		&toggle_render_features_wrapper); +	add("hasRenderFeature", +		"Check if rendering [\"feature\"] is enabled:\n" +		"See: llviewermenu.cpp:render_feature_from_string for list of available features.", +		&has_render_feature_wrapper, +		LLSDMap("reply", LLSD())); +	add("disableAllRenderFeatures", +		"Turn off all rendering features.", +		&disable_all_render_features_wrapper); +	add("enableAllRenderFeatures", +		"Turn on all rendering features.", +		&enable_all_render_features_wrapper); + +	// Render Info Displays +	add("toggleRenderInfoDisplays", +		"Toggle info [\"displays\"]:\n" +		"See: llviewermenu.cpp:info_display_from_string for list of available displays.", +		&toggle_info_displays_wrapper); +	add("hasRenderInfoDisplay", +		"Check if info [\"display\"] is enabled:\n" +		"See: llviewermenu.cpp:info_display_from_string for list of available displays.", +		&has_info_display_wrapper, +		LLSDMap("reply", LLSD())); +	add("disableAllRenderInfoDisplays", +		"Turn off all info displays.", +		&disable_all_info_displays_wrapper); +	add("enableAllRenderInfoDisplays", +		"Turn on all info displays.", +		&enable_all_info_displays_wrapper); +} + diff --git a/indra/newview/llpipelinelistener.h b/indra/newview/llpipelinelistener.h new file mode 100644 index 0000000000..da1898e57b --- /dev/null +++ b/indra/newview/llpipelinelistener.h @@ -0,0 +1,41 @@ +/** + * @file   llpipelinelistener.h + * @author Don Kjer + * @date   2012-07-09 + * @brief  Wrap subset of LLPipeline API in event API + *  + * $LicenseInfo:firstyear=2012&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_LLPIPELINELISTENER_H) +#define LL_LLPIPELINELISTENER_H + +#include "lleventapi.h" + +/// Listen on an LLEventPump with specified name for LLPipeline request events. +class LLPipelineListener: public LLEventAPI +{ +public: +	LLPipelineListener(); +}; + +#endif /* ! defined(LL_LLPIPELINELISTENER_H) */ diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 853656905c..9267444534 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -206,12 +206,9 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)  			}  			// Disable camera switch is currently just for WT_PHYSICS type since we don't want to freeze the avatar  			// when editing its physics. -			const BOOL disable_camera_motion = LLWearableType::getDisableCameraSwitch(wearable_ptr->getType()); -			if (!gAgentCamera.cameraCustomizeAvatar() &&  -				!disable_camera_motion && -				gSavedSettings.getBOOL("AppearanceCameraMovement")) +			if (!gAgentCamera.cameraCustomizeAvatar())  			{ -				gAgentCamera.changeCameraToCustomizeAvatar(); +				LLVOAvatarSelf::onCustomizeStart(LLWearableType::getDisableCameraSwitch(wearable_ptr->getType()));  			}  			if (is_wearable_edit_visible)  			{ @@ -283,7 +280,7 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked()  {  	if (gAgentWearables.areWearablesLoaded())  	{ -		gAgentCamera.changeCameraToCustomizeAvatar(); +		LLVOAvatarSelf::onCustomizeStart();  	}  } @@ -371,15 +368,14 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam  	if (visible)  	{  		mOutfitEdit->onOpen(LLSD()); -		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) -		{ -			gAgentCamera.changeCameraToCustomizeAvatar(); -		} +		LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);  	} -	else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) +	else   	{ -		gAgentCamera.changeCameraToDefault(); -		gAgentCamera.resetView(); +		if (!disable_camera_switch)   // if we're just switching between outfit and wearable editing, don't end customization. +		{ +			LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch); +		}  	}  } @@ -405,10 +401,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we  	if (visible)  	{ -		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) -		{ -			gAgentCamera.changeCameraToCustomizeAvatar(); -		} +		LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);  		mEditWearable->setWearable(wearable, disable_camera_switch);  		mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency  	} @@ -416,10 +409,9 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we  	{  		// Save changes if closing.  		mEditWearable->saveChanges(); -		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") ) +		if (!disable_camera_switch)   // if we're just switching between outfit and wearable editing, don't end customization.  		{ -			gAgentCamera.changeCameraToDefault(); -			gAgentCamera.resetView(); +			LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch);  		}  	}  } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a28d8d3546..b56f2d8f0a 100644..100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -362,6 +362,15 @@ bool idle_startup()  	if ( STATE_FIRST == LLStartUp::getStartupState() )  	{ +		static bool first_call = true; +		if (first_call) +		{ +			// Other phases get handled when startup state changes, +			// need to capture the initial state as well. +			LLStartUp::getPhases().startPhase(LLStartUp::getStartupStateString()); +			first_call = false; +		} +  		gViewerWindow->showCursor();   		gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT); @@ -2704,9 +2713,10 @@ void LLStartUp::setStartupState( EStartupState state )  		getStartupStateString() << " to " <<    		startupStateToString(state) << LL_ENDL; -	sPhases->stopPhase(getStartupStateString()); +	getPhases().stopPhase(getStartupStateString());  	gStartupState = state; -	sPhases->startPhase(getStartupStateString()); +	getPhases().startPhase(getStartupStateString()); +  	postStartupState();  } @@ -3415,6 +3425,14 @@ bool process_login_success_response()  	} +	// set the location of the Agent Appearance service, from which we can request +	// avatar baked textures if they are supported by the current region +	std::string agent_appearance_url = response["agent_appearance_service"]; +	if (!agent_appearance_url.empty()) +	{ +		gSavedSettings.setString("AgentAppearanceServiceURL", agent_appearance_url); +	} +  	// Set the location of the snapshot sharing config endpoint  	std::string snapshot_config_url = response["snapshot_config_url"];  	if(!snapshot_config_url.empty()) diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 3754aaf966..3754aaf966 100644..100755 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 8632890bbb..a61e2d5c86 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -50,6 +50,8 @@  const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024;  const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit  const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) +const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level +const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;  class LLTextureCacheWorker : public LLWorkerClass  { @@ -283,9 +285,12 @@ public:  	LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,  						 U8* data, S32 datasize, S32 offset,  						 S32 imagesize, // for writes +						 LLPointer<LLImageRaw> raw, S32 discardlevel,  						 LLTextureCache::Responder* responder)   			: LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder), -			mState(INIT) +			mState(INIT), +			mRawImage(raw), +			mRawDiscardLevel(discardlevel)  	{  	} @@ -303,6 +308,8 @@ private:  	};  	e_state mState; +	LLPointer<LLImageRaw> mRawImage; +	S32 mRawDiscardLevel;  }; @@ -559,6 +566,11 @@ bool LLTextureCacheRemoteWorker::doWrite()  		if(idx < 0)  		{  			idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry. +			if(idx >= 0) +			{ +				//write to the fast cache. +				llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)); +			}  		}  		else  		{ @@ -658,6 +670,7 @@ bool LLTextureCacheRemoteWorker::doWrite()  		// Nothing else to do at that point...  		done = true;  	} +	mRawImage = NULL;  	// Clean up and exit  	return done; @@ -744,10 +757,14 @@ LLTextureCache::LLTextureCache(bool threaded)  	  mWorkersMutex(NULL),  	  mHeaderMutex(NULL),  	  mListMutex(NULL), +	  mFastCacheMutex(NULL),  	  mHeaderAPRFile(NULL),  	  mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called.  	  mTexturesSizeTotal(0), -	  mDoPurge(FALSE) +	  mDoPurge(FALSE), +	  mFastCachep(NULL), +	  mFastCachePoolp(NULL), +	  mFastCachePadBuffer(NULL)  {  } @@ -755,6 +772,9 @@ LLTextureCache::~LLTextureCache()  {  	clearDeleteList() ;  	writeUpdatedEntries() ; +	delete mFastCachep; +	delete mFastCachePoolp; +	FREE_MEM(LLImageBase::getPrivatePool(), mFastCachePadBuffer);  }  ////////////////////////////////////////////////////////////////////////////// @@ -879,15 +899,15 @@ BOOL LLTextureCache::isInLocal(const LLUUID& id)  //////////////////////////////////////////////////////////////////////////////  //static -const S32 MAX_REASONABLE_FILE_SIZE = 512*1024*1024; // 512 MB -F32 LLTextureCache::sHeaderCacheVersion = 1.4f; -U32 LLTextureCache::sCacheMaxEntries = MAX_REASONABLE_FILE_SIZE / TEXTURE_CACHE_ENTRY_SIZE; +F32 LLTextureCache::sHeaderCacheVersion = 1.7f; +U32 LLTextureCache::sCacheMaxEntries = 1024 * 1024; //~1 million textures.  S64 LLTextureCache::sCacheMaxTexturesSize = 0; // no limit  const char* entries_filename = "texture.entries";  const char* cache_filename = "texture.cache";  const char* old_textures_dirname = "textures";  //change the location of the texture cache to prevent from being deleted by old version viewers.  const char* textures_dirname = "texturecache"; +const char* fast_cache_filename = "FastCache.cache";  void LLTextureCache::setDirNames(ELLPath location)  { @@ -896,6 +916,7 @@ void LLTextureCache::setDirNames(ELLPath location)  	mHeaderEntriesFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, entries_filename);  	mHeaderDataFileName = gDirUtilp->getExpandedFilename(location, textures_dirname, cache_filename);  	mTexturesDirName = gDirUtilp->getExpandedFilename(location, textures_dirname); +	mFastCacheFileName =  gDirUtilp->getExpandedFilename(location, textures_dirname, fast_cache_filename);  }  void LLTextureCache::purgeCache(ELLPath location) @@ -938,8 +959,8 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache  {  	llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. -	S64 header_size = (max_size * 2) / 10; -	S64 max_entries = header_size / TEXTURE_CACHE_ENTRY_SIZE; +	S64 header_size = (max_size / 100) * 36; //0.36 * max_size +	S64 max_entries = header_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);  	sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries));  	header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE;  	max_size -= header_size; @@ -981,6 +1002,7 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache  	purgeTextures(true); // calc mTexturesSize and make some room in the texture cache if we need it  	llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. +	openFastCache(true);  	return max_size; // unused cache space  } @@ -1751,7 +1773,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri  	LLMutexLock lock(&mWorkersMutex);  	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,  																  NULL, size, offset, -																  0, responder); +																  0, NULL, 0, responder);  	handle_t handle = worker->read();  	mReaders[handle] = worker;  	return handle; @@ -1789,6 +1811,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)  LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority,  													  U8* data, S32 datasize, S32 imagesize, +													  LLPointer<LLImageRaw> rawimage, S32 discardlevel,  													  WriteResponder* responder)  {  	if (mReadOnly) @@ -1807,12 +1830,159 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio  	LLMutexLock lock(&mWorkersMutex);  	LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,  																  data, datasize, 0, -																  imagesize, responder); +																  imagesize, rawimage, discardlevel, responder);  	handle_t handle = worker->write();  	mWriters[handle] = worker;  	return handle;  } +//called in the main thread +LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& discardlevel) +{ +	U32 offset; +	{ +		LLMutexLock lock(&mHeaderMutex); +		id_map_t::const_iterator iter = mHeaderIDMap.find(id); +		if(iter == mHeaderIDMap.end()) +		{ +			return NULL; //not in the cache +		} + +		offset = iter->second; +	} +	offset *= TEXTURE_FAST_CACHE_ENTRY_SIZE; + +	U8* data; +	S32 head[4]; +	{ +		LLMutexLock lock(&mFastCacheMutex); + +		openFastCache(); + +		mFastCachep->seek(APR_SET, offset);		 +	 +		llassert_always(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) == TEXTURE_FAST_CACHE_ENTRY_OVERHEAD); +		 +		S32 image_size = head[0] * head[1] * head[2]; +		if(!image_size) //invalid +		{ +			closeFastCache(); +			return NULL; +		} +		discardlevel = head[3]; +		 +		data =  (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size); +		llassert_always(mFastCachep->read(data, image_size) == image_size); +		closeFastCache(); +	} +	LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true); + +	return raw; +} + +//return the fast cache location +bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel) +{ +	//rescale image if needed +	S32 w, h, c; +	w = raw->getWidth(); +	h = raw->getHeight(); +	c = raw->getComponents(); +	S32 i = 0 ; +	 +	while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) +	{ +		++i ; +	} +		 +	if(i) +	{ +		w >>= i; +		h >>= i; +		if(w * h *c > 0) //valid +		{ +			LLPointer<LLImageRaw> newraw = new LLImageRaw(raw->getData(), raw->getWidth(), raw->getHeight(), raw->getComponents()); +			newraw->scale(w, h) ; +			raw = newraw; + +			discardlevel += i ; +		} +	} +	 +	//copy data +	memcpy(mFastCachePadBuffer, &w, sizeof(S32)); +	memcpy(mFastCachePadBuffer + sizeof(S32), &h, sizeof(S32)); +	memcpy(mFastCachePadBuffer + sizeof(S32) * 2, &c, sizeof(S32)); +	memcpy(mFastCachePadBuffer + sizeof(S32) * 3, &discardlevel, sizeof(S32)); +	if(w * h * c > 0) //valid +	{ +		memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), w * h * c); +	} +	S32 offset = id * TEXTURE_FAST_CACHE_ENTRY_SIZE; + +	{ +		LLMutexLock lock(&mFastCacheMutex); + +		openFastCache(); + +		mFastCachep->seek(APR_SET, offset);	 +		llassert_always(mFastCachep->write(mFastCachePadBuffer, TEXTURE_FAST_CACHE_ENTRY_SIZE) == TEXTURE_FAST_CACHE_ENTRY_SIZE); + +		closeFastCache(true); +	} + +	return true; +} + +void LLTextureCache::openFastCache(bool first_time) +{ +	if(!mFastCachep) +	{ +		if(first_time) +		{ +			if(!mFastCachePadBuffer) +			{ +				mFastCachePadBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), TEXTURE_FAST_CACHE_ENTRY_SIZE); +			} +			mFastCachePoolp = new LLVolatileAPRPool(); +			if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp)) +			{ +				mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;				 +			} +			else +			{ +				mFastCachep = new LLAPRFile(mFastCacheFileName, APR_CREATE|APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; +			} +		} +		else +		{ +			mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ; +		} + +		mFastCacheTimer.reset(); +	} +	return; +} +	 +void LLTextureCache::closeFastCache(bool forced) +{	 +	static const F32 timeout = 10.f ; //seconds + +	if(!mFastCachep) +	{ +		return ; +	} + +	if(!forced && mFastCacheTimer.getElapsedTimeF32() < timeout) +	{ +		return ; +	} + +	delete mFastCachep; +	mFastCachep = NULL; +	return; +} +	  bool LLTextureCache::writeComplete(handle_t handle, bool abort)  {  	lockWorkers(); diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index dd0cc9b4bd..e3fc957fd2 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -36,6 +36,7 @@  class LLImageFormatted;  class LLTextureCacheWorker; +class LLImageRaw;  class LLTextureCache : public LLWorkerThread  { @@ -113,8 +114,9 @@ public:  	handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size,  						   ReadResponder* responder);  	bool readComplete(handle_t handle, bool abort); -	handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, +	handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,  						  WriteResponder* responder); +	LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel);  	bool writeComplete(handle_t handle, bool abort = false);  	void prioritizeWrite(handle_t handle); @@ -171,12 +173,18 @@ private:  	void lockHeaders() { mHeaderMutex.lock(); }  	void unlockHeaders() { mHeaderMutex.unlock(); } +	void openFastCache(bool first_time = false); +	void closeFastCache(bool forced = false); +	bool writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel);	 +  private:  	// Internal  	LLMutex mWorkersMutex;  	LLMutex mHeaderMutex;  	LLMutex mListMutex; +	LLMutex mFastCacheMutex;  	LLAPRFile* mHeaderAPRFile; +	LLVolatileAPRPool* mFastCachePoolp;  	typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;  	handle_map_t mReaders; @@ -193,12 +201,17 @@ private:  	// HEADERS (Include first mip)  	std::string mHeaderEntriesFileName;  	std::string mHeaderDataFileName; +	std::string mFastCacheFileName;  	EntriesInfo mHeaderEntriesInfo;  	std::set<S32> mFreeList; // deleted entries  	std::set<LLUUID> mLRU; -	typedef std::map<LLUUID,S32> id_map_t; +	typedef std::map<LLUUID, S32> id_map_t;  	id_map_t mHeaderIDMap; +	LLAPRFile*   mFastCachep; +	LLFrameTimer mFastCacheTimer; +	U8*          mFastCachePadBuffer; +  	// BODIES (TEXTURES minus headers)  	std::string mTexturesDirName;  	typedef std::map<LLUUID,S32> size_map_t; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2ed7488b85..7adf5212c2 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -151,7 +151,7 @@ public:  	/*virtual*/ bool doWork(S32 param); // Called from LLWorkerThread::processRequest()  	/*virtual*/ void finishWork(S32 param, bool completed); // called from finishRequest() (WORK THREAD)  	/*virtual*/ bool deleteOK(); // called from update() (WORK THREAD) - +	  	~LLTextureFetchWorker();  	// void relese() { --mActiveCount; } @@ -196,6 +196,8 @@ private:  	bool processSimulatorPackets();  	bool writeToCacheComplete(); +	void removeFromHTTPQueue(); +  	void lockWorkMutex() { mWorkMutex.lock(); }  	void unlockWorkMutex() { mWorkMutex.unlock(); } @@ -275,6 +277,8 @@ private:  	S32 mRetryAttempt;  	S32 mActiveCount;  	U32 mGetStatus; +	U32 mHTTPHandle; +	F32 mDelay;  	std::string mGetReason;  	// Work Data @@ -328,6 +332,7 @@ public:  			mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow);  		} +		S32 data_size = 0;  		lldebugs << "HTTP COMPLETE: " << mID << llendl;  		LLTextureFetchWorker* worker = mFetcher->getWorker(mID);  		if (worker) @@ -349,7 +354,7 @@ public:  // 				llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl;  			} -			S32 data_size = worker->callbackHttpGet(channels, buffer, partial, success); +			data_size = worker->callbackHttpGet(channels, buffer, partial, success);  			if(log_texture_traffic && data_size > 0)  			{ @@ -359,9 +364,7 @@ public:  					gTotalTextureBytesPerBoostLevel[tex->getBoostLevel()] += data_size ;  				}  			} - -			mFetcher->removeFromHTTPQueue(mID, data_size); - +		  			if (worker->mMetricsStartTime)  			{  				LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, @@ -376,9 +379,10 @@ public:  		}  		else  		{ -			mFetcher->removeFromHTTPQueue(mID); - 			llwarns << "Worker not found: " << mID << llendl; +			llwarns << "Worker not found: " << mID << llendl;  		} + +		mFetcher->getCurlRequest().completeRequest(data_size);  	}  	virtual bool followRedir() @@ -692,10 +696,12 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mLastPacket(-1),  	  mTotalPackets(0),  	  mImageCodec(IMG_CODEC_INVALID), -	  mMetricsStartTime(0) +	  mMetricsStartTime(0), +	  mHTTPHandle(0), +	  mDelay(-1.f)  {  	mCanUseNET = mUrl.empty() ; - +	  	calcWorkPriority();  	mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;  // 	llinfos << "Create: " << mID << " mHost:" << host << " Discard=" << discard << llendl; @@ -726,7 +732,19 @@ LLTextureFetchWorker::~LLTextureFetchWorker()  	mFormattedImage = NULL;  	clearPackets();  	unlockWorkMutex(); -	mFetcher->removeFromHTTPQueue(mID); +	 +	removeFromHTTPQueue(); +} + +void LLTextureFetchWorker::removeFromHTTPQueue() +{ +	if(mHTTPHandle > 0) +	{ +		llassert_always(mState == WAIT_HTTP_REQ); + +		mFetcher->getCurlRequest().removeRequest(mHTTPHandle); +		mHTTPHandle = 0; +	}  }  void LLTextureFetchWorker::clearPackets() @@ -824,6 +842,7 @@ void LLTextureFetchWorker::setImagePriority(F32 priority)  		mImagePriority = priority;  		calcWorkPriority();  		U32 work_priority = mWorkPriority | (getPriority() & LLWorkerThread::PRIORITY_HIGHBITS); +		mFetcher->getCurlRequest().updatePriority(mHTTPHandle, mWorkPriority);  		setPriority(work_priority);  	}  } @@ -851,8 +870,6 @@ void LLTextureFetchWorker::startWork(S32 param)  // Called from LLWorkerThread::processRequest()  bool LLTextureFetchWorker::doWork(S32 param)  { -	static const F32 FETCHING_TIMEOUT = 120.f;//seconds -  	LLMutexLock lock(&mWorkMutex);  	if ((mFetcher->isQuitting() || getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) @@ -912,6 +929,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		mCacheWriteHandle = LLTextureCache::nullHandle();  		mState = LOAD_FROM_TEXTURE_CACHE;  		mInCache = FALSE; +		mDelay = -1.f;  		mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE  		LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority)  							 << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; @@ -927,7 +945,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			S32 size = mDesiredSize - offset;  			if (size <= 0)  			{ -				mState = CACHE_POST; +				mState = CACHE_POST; //have enough data, will fall to decode  				return false;  			}  			mFileSize = 0; @@ -944,7 +962,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  																		  offset, size, responder);  				mCacheReadTimer.reset();  			} -			else if (mUrl.empty()) +			else if (mUrl.empty() && mFetcher->canLoadFromCache())  			{  				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it @@ -953,7 +971,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  																		  offset, size, responder);  				mCacheReadTimer.reset();  			} -			else if(mCanUseHTTP) +			else if(!mUrl.empty() && mCanUseHTTP)  			{  				if (!(mUrl.compare(0, 7, "http://") == 0))  				{ @@ -981,6 +999,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  			}  			else  			{ +				// +				//This should never happen +				//  				return false;  			}  		} @@ -1020,6 +1041,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL;  				mState = LOAD_FROM_NETWORK;  			} +			  			// fall through  			LLTextureFetch::sCacheHitRate.addValue(0.f);  		} @@ -1060,7 +1082,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		}  		if (mCanUseHTTP && !mUrl.empty())  		{ -			mState = LLTextureFetchWorker::SEND_HTTP_REQ; +			mState = SEND_HTTP_REQ;  			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  			if(mWriteToCacheState != NOT_WRITE)  			{ @@ -1156,17 +1178,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  	{  		if(mCanUseHTTP)  		{ -			//NOTE: -			//control the number of the http requests issued for: -			//1, not openning too many file descriptors at the same time; -			//2, control the traffic of http so udp gets bandwidth. -			// -			static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 8 ; -			if(mFetcher->getNumHTTPRequests() > MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE) -			{ -				return false ; //wait. -			} -  			mFetcher->removeFromNetworkQueue(this, false);  			S32 cur_size = 0; @@ -1179,6 +1190,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  					{  						// We already have all the data, just decode it  						mLoadedDiscard = mFormattedImage->getDiscardLevel(); +						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  						mState = DECODE_IMAGE;  						return false;  					} @@ -1209,7 +1221,6 @@ bool LLTextureFetchWorker::doWork(S32 param)  				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  				mState = WAIT_HTTP_REQ;	 -				mFetcher->addToHTTPQueue(mID);  				if (! mMetricsStartTime)  				{  					mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); @@ -1221,8 +1232,16 @@ bool LLTextureFetchWorker::doWork(S32 param)  				// Will call callbackHttpGet when curl request completes  				std::vector<std::string> headers;  				headers.push_back("Accept: image/x-j2c"); -				res = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, -															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true)); +				// If we try to fetch the whole file, we set the size to 0 so that we generate the correct curl range request +				// Note: it looks a bit hacky but we need to limit this (size==0) to mean "whole file" to HTTP only as it messes up UDP fetching +				if ((offset+mRequestedSize) == MAX_IMAGE_DATA_SIZE) +				{ +					mRequestedSize = 0; +				} +				mHTTPHandle = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, mWorkPriority, +															  new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true), mDelay); +				mDelay = -1.f; //reset +				res = true;  			}  			if (!res)  			{ @@ -1263,6 +1282,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  					{  						mState = INIT ;  						mCanUseHTTP = false ; +						mUrl.clear();  						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  						return false ;  					} @@ -1275,12 +1295,15 @@ bool LLTextureFetchWorker::doWork(S32 param)  					++mHTTPFailCount;  					max_attempts = mHTTPFailCount+1; // Keep retrying  					LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL; +					mDelay = 2.0f; //delay 2 second to re-issue the http request  				}  				else  				{  					const S32 HTTP_MAX_RETRY_COUNT = 3;  					max_attempts = HTTP_MAX_RETRY_COUNT + 1;  					++mHTTPFailCount; +					mDelay = 2.0f; //delay 2 second to re-issue the http request +  					llinfos << "HTTP GET failed for: " << mUrl  							<< " Status: " << mGetStatus << " Reason: '" << mGetReason << "'"  							<< " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl; @@ -1288,10 +1311,12 @@ bool LLTextureFetchWorker::doWork(S32 param)  				if (mHTTPFailCount >= max_attempts)  				{ +					mUrl.clear();  					if (cur_size > 0)  					{  						// Use available data  						mLoadedDiscard = mFormattedImage->getDiscardLevel(); +						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  						mState = DECODE_IMAGE;  						return false;   					} @@ -1304,11 +1329,20 @@ bool LLTextureFetchWorker::doWork(S32 param)  				}  				else  				{ +					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);  					mState = SEND_HTTP_REQ;  					return false; // retry  				}  			} +			// Clear the url since we're done with the fetch +			// Note: mUrl is used to check is fetching is required so failure to clear it will force an http fetch +			// next time the texture is requested, even if the data have already been fetched. +			if(mWriteToCacheState != NOT_WRITE) +			{ +				mUrl.clear(); +			} +  			llassert_always(mBufferSize == cur_size + mRequestedSize);  			if(!mBufferSize)//no data received.  			{ @@ -1363,13 +1397,9 @@ bool LLTextureFetchWorker::doWork(S32 param)  		}  		else  		{ -			if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32()) -			{ -				//timeout, abort. -				mState = DONE; -				return true; -			} - +			// +			//No need to timeout, the responder should be triggered automatically. +			//  			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);  			return false;  		} @@ -1501,7 +1531,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);  		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,  																  mFormattedImage->getData(), datasize, -																  mFileSize, responder); +																  mFileSize, mRawImage, mDecodedDiscard, responder);  		// fall through  	} @@ -1689,7 +1719,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,  	S32 data_size = 0 ;  	LLMutexLock lock(&mWorkMutex); - +	mHTTPHandle = 0;  	if (mState != WAIT_HTTP_REQ)  	{  		llwarns << "callbackHttpGet for unrequested fetch worker: " << mID @@ -1713,7 +1743,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,  			mBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);  			buffer->readAfter(channels.in(), NULL, mBuffer, data_size);  			mBufferSize += data_size; -			if (data_size < mRequestedSize && mRequestedDiscard == 0) +			if (mRequestedSize == 0)  			{  				mHaveAllData = TRUE;  			} @@ -1739,6 +1769,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,  	{  		mRequestedSize = -1; // error  	} +	  	mLoaded = TRUE;  	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); @@ -1862,11 +1893,11 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	  mTextureCache(cache),  	  mImageDecodeThread(imagedecodethread),  	  mTextureBandwidth(0), -	  mHTTPTextureBits(0), -	  mTotalHTTPRequests(0),  	  mCurlGetRequest(NULL),  	  mQAMode(qa_mode),  	  mFetchDebugger(NULL), +	  mFetchSource(LLTextureFetch::FROM_ALL), +	  mOriginFetchSource(LLTextureFetch::FROM_ALL),  	  mFetcherLocked(FALSE)  {  	mCurlPOSTRequestCount = 0; @@ -1877,6 +1908,13 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	if(LLTextureFetchDebugger::isEnabled())  	{  		mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; +		mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource"); +		if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE) +		{ +			mFetchSource = LLTextureFetch::FROM_ALL; +			gSavedSettings.setS32("TextureFetchSource", 0); +		} +		mOriginFetchSource = mFetchSource;  	}  } @@ -1946,6 +1984,8 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con  	}  	else  	{ +		// If the requester knows nothing about the file, we fetch the smallest +		// amount of data at the lowest resolution (highest discard level) possible.  		desired_size = TEXTURE_CACHE_ENTRY_SIZE;  		desired_discard = MAX_DISCARD_LEVEL;  	} @@ -2024,45 +2064,22 @@ void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool c  	}  } -// protected -void LLTextureFetch::addToHTTPQueue(const LLUUID& id) -{ -	LLMutexLock lock(&mNetworkQueueMutex); -	mHTTPTextureQueue.insert(id); -	mTotalHTTPRequests++; -} - -void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size) -{ -	LLMutexLock lock(&mNetworkQueueMutex); -	mHTTPTextureQueue.erase(id); -	mHTTPTextureBits += received_size * 8; // Approximate - does not include header bits	 -} -  void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)  {  	lockQueue() ;  	LLTextureFetchWorker* worker = getWorkerAfterLock(id); -	if (worker) -	{		 -		size_t erased_1 = mRequestMap.erase(worker->mID); -		unlockQueue() ; - -		llassert_always(erased_1 > 0) ; - -		removeFromNetworkQueue(worker, cancel); -		llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; +	unlockQueue() ; -		worker->scheduleDelete();	 -	} -	else -	{ -		unlockQueue() ; -	} +	removeRequest(worker, cancel);  }  void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)  { +	if(!worker) +	{ +		return; +	} +  	lockQueue() ;  	size_t erased_1 = mRequestMap.erase(worker->mID);  	unlockQueue() ; @@ -2071,9 +2088,28 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)  	removeFromNetworkQueue(worker, cancel);  	llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; +	worker->removeFromHTTPQueue();  	worker->scheduleDelete();	  } +void LLTextureFetch::deleteAllRequests() +{ +	while(1) +	{ +		lockQueue(); +		if(mRequestMap.empty()) +		{ +			unlockQueue() ; +			break; +		} + +		LLTextureFetchWorker* worker = mRequestMap.begin()->second; +		unlockQueue() ; + +		removeRequest(worker, true); +	} +} +  S32 LLTextureFetch::getNumRequests()   {   	lockQueue() ; @@ -2083,24 +2119,6 @@ S32 LLTextureFetch::getNumRequests()  	return size ;  } -S32 LLTextureFetch::getNumHTTPRequests()  -{  -	mNetworkQueueMutex.lock() ; -	S32 size = (S32)mHTTPTextureQueue.size();  -	mNetworkQueueMutex.unlock() ; - -	return size ; -} - -U32 LLTextureFetch::getTotalNumHTTPRequests() -{ -	mNetworkQueueMutex.lock() ; -	U32 size = mTotalHTTPRequests ; -	mNetworkQueueMutex.unlock() ; - -	return size ; -} -  // call lockQueue() first!  LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)  { @@ -2186,7 +2204,7 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)  	{  		worker->lockWorkMutex();  		worker->setImagePriority(priority); -		worker->unlockWorkMutex(); +		worker->unlockWorkMutex();		  		res = true;  	}  	return res; @@ -2268,15 +2286,7 @@ S32 LLTextureFetch::update(F32 max_time_ms)  {  	static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS"); -	{ -		mNetworkQueueMutex.lock() ; -		mMaxBandwidth = band_width ; - -		gTextureList.sTextureBits += mHTTPTextureBits ; -		mHTTPTextureBits = 0 ; - -		mNetworkQueueMutex.unlock() ; -	} +	mMaxBandwidth = band_width ;  	S32 res = LLWorkerThread::update(max_time_ms); @@ -2287,13 +2297,28 @@ S32 LLTextureFetch::update(F32 max_time_ms)  		// won't work so don't bother trying  		if (LLStartUp::getStartupState() > STATE_AGENT_SEND)  		{ -			sendRequestListToSimulators(); +			sendRequestListToSimulators();			  		}  	}  	if (!mThreaded)  	{  		commonUpdate(); +		 +		if(mCurlGetRequest) +		{ +			mCurlGetRequest->nextRequests(); +		} +	} + +	if(mCurlGetRequest) +	{ +		gTextureList.sTextureBits += mCurlGetRequest->getTotalReceivedBits(); +	} + +	if(mFetchDebugger) +	{ +		mFetchDebugger->tryToStopDebug(); //check if need to stop debugger.  	}  	return res; @@ -2323,7 +2348,7 @@ void LLTextureFetch::shutDownImageDecodeThread()  void LLTextureFetch::startThread()  {  	// Construct mCurlGetRequest from Worker Thread -	mCurlGetRequest = new LLCurlRequest(); +	mCurlGetRequest = new LLCurlTextureRequest(8);  	if(mFetchDebugger)  	{ @@ -2348,6 +2373,8 @@ void LLTextureFetch::threadedUpdate()  {  	llassert_always(mCurlGetRequest); +	mCurlGetRequest->nextRequests(); +  	// Limit update frequency  	const F32 PROCESS_TIME = 0.05f;   	static LLFrameTimer process_timer; @@ -3160,6 +3187,7 @@ public:  			llinfos << "Fetch Debugger : CURL GET FAILED, index = " << mIndex << ", status:" << status << " reason:" << reason << llendl;  		}  		mDebugger->callbackHTTP(mIndex, channels, buffer, partial, success); +		mDebugger->getCurlGetRequest()->completeRequest(0);  	}  	virtual bool followRedir()  	{ @@ -3182,7 +3210,8 @@ LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextur  LLTextureFetchDebugger::~LLTextureFetchDebugger()  {  	mFetchingHistory.clear(); -	stopDebug(); +	mStopDebug = TRUE; +	tryToStopDebug();  }  void LLTextureFetchDebugger::init() @@ -3197,6 +3226,8 @@ void LLTextureFetchDebugger::init()  	mTotalFetchingTime = 0.f;  	mRefetchVisCacheTime = -1.f;  	mRefetchVisHTTPTime = -1.f; +	mRefetchAllCacheTime = -1.f; +	mRefetchAllHTTPTime = -1.f;  	mNumFetchedTextures = 0;  	mNumCacheHits = 0; @@ -3210,10 +3241,56 @@ void LLTextureFetchDebugger::init()  	mRenderedDecodedData = 0;  	mFetchedPixels = 0;  	mRenderedPixels = 0; -	mRefetchedData = 0; -	mRefetchedPixels = 0; +	mRefetchedVisData = 0; +	mRefetchedVisPixels = 0; +	mRefetchedAllData = 0; +	mRefetchedAllPixels = 0;  	mFreezeHistory = FALSE; +	mStopDebug = FALSE; +	mClearHistory = FALSE; +} + +void LLTextureFetchDebugger::startWork(e_debug_state state) +{ +	switch(state) +	{ +		case IDLE: +			break; +		case START_DEBUG: +			startDebug(); +			break; +		case READ_CACHE:			 +			debugCacheRead(); +			break; +		case WRITE_CACHE: +			debugCacheWrite(); +			break; +		case DECODING: +			debugDecoder(); +			break; +		case HTTP_FETCHING: +			debugHTTP(); +			break; +		case GL_TEX: +			debugGLTextureCreation(); +			break; +		case REFETCH_VIS_CACHE: +			debugRefetchVisibleFromCache(); +			break; +		case REFETCH_VIS_HTTP: +			debugRefetchVisibleFromHTTP(); +			break; +		case REFETCH_ALL_CACHE: +			debugRefetchAllFromCache(); +			break; +		case REFETCH_ALL_HTTP: +			debugRefetchAllFromHTTP(); +			break; +		default: +			break; +	} +	return;  }  void LLTextureFetchDebugger::startDebug() @@ -3221,10 +3298,18 @@ void LLTextureFetchDebugger::startDebug()  	//lock the fetcher  	mFetcher->lockFetcher(true);  	mFreezeHistory = TRUE; +	mFetcher->resetLoadSource();  	//clear the current fetching queue  	gTextureList.clearFetchingRequests(); +	mState = START_DEBUG; +} + +bool LLTextureFetchDebugger::processStartDebug(F32 max_time) +{ +	mTimer.reset(); +  	//wait for all works to be done  	while(1)  	{ @@ -3236,6 +3321,11 @@ void LLTextureFetchDebugger::startDebug()  		{  			break;  		} + +		if(mTimer.getElapsedTimeF32() > max_time) +		{ +			return false; +		}  	}  	//collect statistics @@ -3274,10 +3364,17 @@ void LLTextureFetchDebugger::startDebug()  	}  	mNumFetchedTextures = fetched_textures.size(); + +	return true;  } -void LLTextureFetchDebugger::stopDebug() +void LLTextureFetchDebugger::tryToStopDebug()  { +	if(!mStopDebug) +	{ +		return; +	} +  	//clear the current debug work  	S32 size = mFetchingHistory.size();  	switch(mState) @@ -3306,37 +3403,71 @@ void LLTextureFetchDebugger::stopDebug()  		break;  	case GL_TEX:  		break; +	case REFETCH_VIS_CACHE: +		break; +	case REFETCH_VIS_HTTP: +		break; +	case REFETCH_ALL_CACHE: +		mRefetchList.clear(); +		break; +	case REFETCH_ALL_HTTP: +		mRefetchList.clear(); +		break;  	default:  		break;  	} -	while(1) +	if(update(0.005f))  	{ -		if(update()) +		//unlock the fetcher +		mFetcher->lockFetcher(false); +		mFetcher->resetLoadSource(); +		mFreezeHistory = FALSE;		 +		mStopDebug = FALSE; + +		if(mClearHistory)  		{ -			break; +			mFetchingHistory.clear(); +			init();	 +			mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset  		}  	} - -	//unlock the fetcher -	mFetcher->lockFetcher(false); -	mFreezeHistory = FALSE; -	mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset  }  //called in the main thread and when the fetching queue is empty  void LLTextureFetchDebugger::clearHistory()  { -	mFetchingHistory.clear(); -	init(); +	mClearHistory = TRUE;	  }  void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)  { +	if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull()) +	{ +		return; +	} +  	if(mFreezeHistory)  	{ -		mRefetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); -		mRefetchedData += worker->mFormattedImage->getDataSize(); +		if(mState == REFETCH_VIS_CACHE || mState == REFETCH_VIS_HTTP) +		{ +			mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); +			mRefetchedVisData += worker->mFormattedImage->getDataSize(); +		} +		else +		{ +			mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); +			mRefetchedAllData += worker->mFormattedImage->getDataSize(); + +			LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID); +			if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end()) +			{ +				if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel) +				{ +					mRefetchList[tex].erase(mRefetchList[tex].begin()); +				} +			} +		}  		return;  	} @@ -3348,9 +3479,8 @@ void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)  	mDecodedData += worker->mRawImage->getDataSize();  	mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); -	mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); -	//mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mHaveAllData ? 0 : worker->mLoadedDiscard, worker->mFormattedImage->getComponents(), -		//worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize())); +	mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard,  +		worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));  }  void LLTextureFetchDebugger::lockCache() @@ -3367,6 +3497,7 @@ void LLTextureFetchDebugger::debugCacheRead()  	llassert_always(mState == IDLE);  	mTimer.reset();  	mState = READ_CACHE; +	mCacheReadTime = -1.f;  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++) @@ -3402,6 +3533,7 @@ void LLTextureFetchDebugger::debugCacheWrite()  	llassert_always(mState == IDLE);  	mTimer.reset();  	mState = WRITE_CACHE; +	mCacheWriteTime = -1.f;  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++) @@ -3411,7 +3543,7 @@ void LLTextureFetchDebugger::debugCacheWrite()  			mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL,   				mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize,  				mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1,  -				new LLDebuggerCacheWriteResponder(this, i));					 +				NULL, 0, new LLDebuggerCacheWriteResponder(this, i));					  		}  	}  } @@ -3430,6 +3562,7 @@ void LLTextureFetchDebugger::debugDecoder()  	llassert_always(mState == IDLE);  	mTimer.reset();  	mState = DECODING; +	mDecodingTime = -1.f;  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++) @@ -3465,6 +3598,7 @@ void LLTextureFetchDebugger::debugHTTP()  	mTimer.reset();  	mState = HTTP_FETCHING; +	mHTTPTime = -1.f;  	S32 size = mFetchingHistory.size();  	for (S32 i = 0 ; i < size ; i++) @@ -3481,14 +3615,28 @@ void LLTextureFetchDebugger::debugHTTP()  S32 LLTextureFetchDebugger::fillCurlQueue()  { -	if (mNbCurlRequests == 24) -		return mNbCurlRequests; -	 +	if(mStopDebug) //stop +	{ +		mNbCurlCompleted = mFetchingHistory.size(); +		return 0; +	}  	S32 size = mFetchingHistory.size(); + +	if (mNbCurlRequests == size) //all issued +	{ +		return 0; +	}	 +	 +	S32 counter = 8; +	mNbCurlRequests = 0;  	for (S32 i = 0 ; i < size ; i++)  	{		 +		mNbCurlRequests++; +  		if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE) +		{  			continue; +		}  		std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str();  		S32 requestedSize = mFetchingHistory[i].mRequestedSize;  		// We request the whole file if the size was not set. @@ -3497,16 +3645,11 @@ S32 LLTextureFetchDebugger::fillCurlQueue()  		requestedSize = (requestedSize == 33554432 ? 0 : requestedSize);  		std::vector<std::string> headers;  		headers.push_back("Accept: image/x-j2c"); -		bool res = mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, new LLDebuggerHTTPResponder(this, i)); -		if (res) -		{ -			mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; -			mNbCurlRequests++; -			// Hack -			if (mNbCurlRequests == 24) -				break; -		} -		else  +		mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, 0x10000, new LLDebuggerHTTPResponder(this, i)); +		 +		mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS; +		counter--; +		if(counter < 1)  		{  			break;  		} @@ -3519,7 +3662,7 @@ void LLTextureFetchDebugger::debugGLTextureCreation()  {  	llassert_always(mState == IDLE);  	mState = GL_TEX; -	std::vector<LLViewerFetchedTexture*> tex_list; +	mTempTexList.clear();  	S32 size = mFetchingHistory.size();  	for(S32 i = 0 ; i < size ; i++) @@ -3530,28 +3673,54 @@ void LLTextureFetchDebugger::debugGLTextureCreation()  			if(tex && !tex->isForSculptOnly())  			{  				tex->destroyGLTexture() ; -				tex_list.push_back(tex); +				mTempTexList.push_back(tex);  			}  		}  	} +	 +	mGLCreationTime = -1.f; +	mTempIndex = 0; +	mHistoryListIndex = 0; +	 +	return; +} +bool LLTextureFetchDebugger::processGLCreation(F32 max_time) +{  	mTimer.reset(); -	S32 j = 0 ; -	S32 size1 = tex_list.size(); -	for(S32 i = 0 ; i < size && j < size1; i++) + +	bool done = true; +	S32 size = mFetchingHistory.size(); +	S32 size1 = mTempTexList.size(); +	for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++)  	{ -		if(mFetchingHistory[i].mRawImage.notNull()) +		if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull())  		{ -			if(mFetchingHistory[i].mID == tex_list[j]->getID()) +			if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID())  			{ -				tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel()); -				j++; +				mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel,  +					mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel()); +				mTempIndex++;  			}  		} + +		if(mTimer.getElapsedTimeF32() > max_time) +		{ +			done = false; +			break; +		}  	} -	mGLCreationTime = mTimer.getElapsedTimeF32() ; -	return; +	if(mGLCreationTime < 0.f) +	{ +		mGLCreationTime = mTimer.getElapsedTimeF32() ; +	} +	else +	{ +		mGLCreationTime += mTimer.getElapsedTimeF32() ; +	} + +	return done;  }  //clear fetching results of all textures. @@ -3568,15 +3737,62 @@ void LLTextureFetchDebugger::clearTextures()  	}  } +void LLTextureFetchDebugger::makeRefetchList() +{ +	mRefetchList.clear(); +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size; i++) +	{		 +		LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID); +		if(tex && tex->isJustBound()) //visible +		{ +			continue; //the texture fetch pipeline will take care of visible textures. +		} + +		mRefetchList[tex].push_back(i); 		 +	} +} + +void LLTextureFetchDebugger::scanRefetchList() +{ +	if(mStopDebug) +	{ +		return; +	} +	if(!mRefetchNonVis) +	{ +		return; +	} + +	for(std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> >::iterator iter = mRefetchList.begin(); +		iter != mRefetchList.end(); ) +	{ +		if(iter->second.empty()) +		{ +			gTextureList.setDebugFetching(iter->first, -1); +			mRefetchList.erase(iter++);		// This is the correct method to "erase and move on" in an std::map +		} +		else +		{ +			gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel); +			++iter; +		} +	} +} +  void LLTextureFetchDebugger::debugRefetchVisibleFromCache()  {  	llassert_always(mState == IDLE);  	mState = REFETCH_VIS_CACHE;  	clearTextures(); - +	mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); +	  	mTimer.reset();  	mFetcher->lockFetcher(false); +	mRefetchVisCacheTime = -1.f; +	mRefetchedVisData = 0; +	mRefetchedVisPixels = 0;  }  void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() @@ -3584,17 +3800,60 @@ void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP()  	llassert_always(mState == IDLE);  	mState = REFETCH_VIS_HTTP; -	clearCache();  	clearTextures(); +	mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY); + +	mTimer.reset(); +	mFetcher->lockFetcher(false); +	mRefetchVisHTTPTime = -1.f; +	mRefetchedVisData = 0; +	mRefetchedVisPixels = 0; +} + +void LLTextureFetchDebugger::debugRefetchAllFromCache() +{ +	llassert_always(mState == IDLE); +	mState = REFETCH_ALL_CACHE; + +	clearTextures(); +	makeRefetchList(); +	mFetcher->setLoadSource(LLTextureFetch::FROM_ALL); + +	mTimer.reset(); +	mFetcher->lockFetcher(false); +	mRefetchAllCacheTime = -1.f; +	mRefetchedAllData = 0; +	mRefetchedAllPixels = 0; +	mRefetchNonVis = FALSE; +} + +void LLTextureFetchDebugger::debugRefetchAllFromHTTP() +{ +	llassert_always(mState == IDLE); +	mState = REFETCH_ALL_HTTP; + +	clearTextures(); +	makeRefetchList(); +	mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY);  	mTimer.reset();  	mFetcher->lockFetcher(false); +	mRefetchAllHTTPTime = -1.f; +	mRefetchedAllData = 0; +	mRefetchedAllPixels = 0; +	mRefetchNonVis = TRUE;  } -bool LLTextureFetchDebugger::update() +bool LLTextureFetchDebugger::update(F32 max_time)  {  	switch(mState)  	{ +	case START_DEBUG: +		if(processStartDebug(max_time)) +		{ +			mState = IDLE; +		} +		break;  	case READ_CACHE:  		if(!mTextureCache->update(1))  		{ @@ -3621,6 +3880,7 @@ bool LLTextureFetchDebugger::update()  		break;  	case HTTP_FETCHING:  		mCurlGetRequest->process(); +		mCurlGetRequest->nextRequests();  		LLCurl::getCurlThread()->update(1);  		if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size())  		{ @@ -3629,22 +3889,59 @@ bool LLTextureFetchDebugger::update()  		}  		break;  	case GL_TEX: -		mState = IDLE; +		if(processGLCreation(max_time)) +		{ +			mState = IDLE; +			mTempTexList.clear(); +		}  		break;  	case REFETCH_VIS_CACHE:  		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)  		{ -			mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +			mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ;  			mState = IDLE;  			mFetcher->lockFetcher(true); +			mFetcher->resetLoadSource();  		}  		break;  	case REFETCH_VIS_HTTP:  		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)  		{ -			mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +			mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ; +			mState = IDLE; +			mFetcher->lockFetcher(true); +			mFetcher->resetLoadSource(); +		} +		break; +	case REFETCH_ALL_CACHE: +		scanRefetchList(); +		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +		{ +			if(!mRefetchNonVis) +			{ +				mRefetchNonVis = TRUE; //start to fetch non-vis +				scanRefetchList(); +				break; +			} + +			mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ; +			mState = IDLE;  +			mFetcher->lockFetcher(true); +			mFetcher->resetLoadSource(); +			mRefetchList.clear(); +			mRefetchNonVis = FALSE; +		} +		break; +	case REFETCH_ALL_HTTP: +		scanRefetchList(); +		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +		{ +			mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ;  			mState = IDLE;  			mFetcher->lockFetcher(true); +			mFetcher->resetLoadSource(); +			mRefetchList.clear(); +			mRefetchNonVis = FALSE;  		}  		break;  	default: @@ -3685,7 +3982,6 @@ void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& ch  										  const LLIOPipe::buffer_ptr_t& buffer,   										  bool partial, bool success)  { -	mNbCurlRequests--;  	if (success)  	{  		mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; @@ -3699,7 +3995,7 @@ void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& ch  			U8* d_buffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size);  			buffer->readAfter(channels.in(), NULL, d_buffer, data_size); -			llassert_always(mFetchingHistory[id].mFormattedImage.isNull()); +			mFetchingHistory[id].mFormattedImage = NULL;  			{  				// For now, create formatted image based on extension  				std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[id].mID.asString().c_str(); @@ -3721,6 +4017,7 @@ void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& ch  		{  			// Fetch will have to be redone  			mFetchingHistory[id].mCurlState = FetchEntry::CURL_NOT_DONE; +			mNbCurlRequests--;	  		}  		else //skip  		{ diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 107e1623b0..f5072a79f1 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -65,6 +65,7 @@ public:  	bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,  					   S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);  	void deleteRequest(const LLUUID& id, bool cancel); +	void deleteAllRequests();  	bool getRequestFinished(const LLUUID& id, S32& discard_level,  							LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux);  	bool updateRequestPriority(const LLUUID& id, F32 priority); @@ -81,8 +82,6 @@ public:  					  U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http);  	void dump();  	S32 getNumRequests() ; -	S32 getNumHTTPRequests() ; -	U32 getTotalNumHTTPRequests() ;  	// Public for access by callbacks      S32 getPending(); @@ -101,7 +100,7 @@ public:  							LLViewerAssetStats * main_stats);  	void commandDataBreak(); -	LLCurlRequest & getCurlRequest()	{ return *mCurlGetRequest; } +	LLCurlTextureRequest & getCurlRequest()	{ return *mCurlGetRequest; }  	bool isQAMode() const				{ return mQAMode; } @@ -113,7 +112,6 @@ protected:  	void addToNetworkQueue(LLTextureFetchWorker* worker);  	void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);  	void addToHTTPQueue(const LLUUID& id); -	void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0);  	void removeRequest(LLTextureFetchWorker* worker, bool cancel);  	// Overrides from the LLThread tree @@ -172,8 +170,8 @@ private:  	LLTextureCache* mTextureCache;  	LLImageDecodeThread* mImageDecodeThread; -	LLCurlRequest* mCurlGetRequest; -	 +	LLCurlTextureRequest* mCurlGetRequest; +  	// Map of all requests by UUID  	typedef std::map<LLUUID,LLTextureFetchWorker*> map_t;  	map_t mRequestMap; @@ -188,11 +186,6 @@ private:  	F32 mMaxBandwidth;  	LLTextureInfo mTextureInfo; -	U32 mHTTPTextureBits; - -	//debug use -	U32 mTotalHTTPRequests ; -  	// Out-of-band cross-thread command queue.  This command queue  	// is logically tied to LLQueuedThread's list of  	// QueuedRequest instances and so must be covered by the @@ -216,18 +209,34 @@ public:  	// reporting due to either startup or a problem POSTing data.  	static volatile bool svMetricsDataBreak; +public: +	//debug use +	enum e_tex_source +	{ +		FROM_ALL = 0, +		FROM_HTTP_ONLY, +		INVALID_SOURCE +	};  private:  	//debug use  	LLTextureFetchDebugger* mFetchDebugger;  	bool mFetcherLocked; +	 +	e_tex_source mFetchSource; +	e_tex_source mOriginFetchSource;  public:  	//debug use  	LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;}  	void lockFetcher(bool lock) { mFetcherLocked = lock;} + +	void setLoadSource(e_tex_source source) {mFetchSource = source;} +	void resetLoadSource() {mFetchSource = mOriginFetchSource;} +	bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;}  };  //debug use +class LLViewerFetchedTexture;  class LLTextureFetchDebugger  {  	friend class LLTextureFetch; @@ -239,6 +248,7 @@ public:  	enum e_debug_state  	{  		IDLE = 0, +		START_DEBUG,  		READ_CACHE,  		WRITE_CACHE,  		DECODING, @@ -301,13 +311,15 @@ private:  	F32 mTotalFetchingTime;  	F32 mRefetchVisCacheTime;  	F32 mRefetchVisHTTPTime; +	F32 mRefetchAllCacheTime; +	F32 mRefetchAllHTTPTime;  	LLTimer mTimer;  	LLTextureFetch* mFetcher;  	LLTextureCache* mTextureCache;  	LLImageDecodeThread* mImageDecodeThread; -	LLCurlRequest* mCurlGetRequest; +	LLCurlTextureRequest* mCurlGetRequest;  	S32 mNumFetchedTextures;  	S32 mNumCacheHits; @@ -321,34 +333,39 @@ private:  	U32 mRenderedDecodedData;  	U32 mFetchedPixels;  	U32 mRenderedPixels; -	U32 mRefetchedData; -	U32 mRefetchedPixels; +	U32 mRefetchedVisData; +	U32 mRefetchedVisPixels; +	U32 mRefetchedAllData; +	U32 mRefetchedAllPixels;  	BOOL mFreezeHistory; +	BOOL mStopDebug; +	BOOL mClearHistory; +	BOOL mRefetchNonVis;  	std::string mHTTPUrl;  	S32 mNbCurlRequests;  	S32 mNbCurlCompleted; +	std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; +	std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList; +	S32 mTempIndex; +	S32 mHistoryListIndex; +  public: -	bool update(); //called in the main thread once per frame +	bool update(F32 max_time); //called in the main thread once per frame  	//fetching history  	void clearHistory();  	void addHistoryEntry(LLTextureFetchWorker* worker); -	void setCurlGetRequest(LLCurlRequest* request) { mCurlGetRequest = request;} -	 -	void startDebug(); -	void stopDebug(); //stop everything -	void debugCacheRead(); -	void debugCacheWrite();	 -	void debugHTTP(); -	void debugDecoder(); -	void debugGLTextureCreation(); -	void debugRefetchVisibleFromCache(); -	void debugRefetchVisibleFromHTTP(); +	void setCurlGetRequest(LLCurlTextureRequest* request) { mCurlGetRequest = request;} +	LLCurlTextureRequest* getCurlGetRequest() { return mCurlGetRequest;} +	void startWork(e_debug_state state); +	void setStopDebug() {mStopDebug = TRUE;} +	void tryToStopDebug(); //stop everything +	  	void callbackCacheRead(S32 id, bool success, LLImageFormatted* image,  						   S32 imagesize, BOOL islocal);  	void callbackCacheWrite(S32 id, bool success); @@ -372,8 +389,10 @@ public:  	U32  getRenderedDecodedData()        {return mRenderedDecodedData;}  	U32  getFetchedPixels()              {return mFetchedPixels;}  	U32  getRenderedPixels()             {return mRenderedPixels;} -	U32  getRefetchedData()              {return mRefetchedData;} -	U32  getRefetchedPixels()            {return mRefetchedPixels;} +	U32  getRefetchedVisData()              {return mRefetchedVisData;} +	U32  getRefetchedVisPixels()            {return mRefetchedVisPixels;} +	U32  getRefetchedAllData()              {return mRefetchedAllData;} +	U32  getRefetchedAllPixels()            {return mRefetchedAllPixels;}  	F32  getCacheReadTime()     {return mCacheReadTime;}  	F32  getCacheWriteTime()    {return mCacheWriteTime;} @@ -383,11 +402,15 @@ public:  	F32  getTotalFetchingTime() {return mTotalFetchingTime;}  	F32  getRefetchVisCacheTime() {return mRefetchVisCacheTime;}  	F32  getRefetchVisHTTPTime()  {return mRefetchVisHTTPTime;} +	F32  getRefetchAllCacheTime() {return mRefetchAllCacheTime;} +	F32  getRefetchAllHTTPTime()  {return mRefetchAllHTTPTime;}  private:  	void init();  	void clearTextures();//clear fetching results of all textures.  	void clearCache(); +	void makeRefetchList(); +	void scanRefetchList();  	void lockFetcher();  	void unlockFetcher(); @@ -400,6 +423,20 @@ private:  	S32 fillCurlQueue(); +	void startDebug(); +	void debugCacheRead(); +	void debugCacheWrite();	 +	void debugHTTP(); +	void debugDecoder(); +	void debugGLTextureCreation(); +	void debugRefetchVisibleFromCache(); +	void debugRefetchVisibleFromHTTP(); +	void debugRefetchAllFromCache(); +	void debugRefetchAllFromHTTP(); + +	bool processStartDebug(F32 max_time); +	bool processGLCreation(F32 max_time); +  private:  	static bool sDebuggerEnabled;  public: diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 52d085dd2c..c60b4155a0 100644..100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -514,7 +514,7 @@ void LLGLTexMemBar::draw()  	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() ; +	U32 total_http_requests = LLAppViewer::getTextureFetch()->getCurlRequest().getTotalIssuedRequests() ;  	//----------------------------------------------------------------------------  	LLGLSUIDefault gls_ui;  	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f); @@ -552,7 +552,7 @@ void LLGLTexMemBar::draw()  					LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),  					LLLFSThread::sLocal->getPending(),  					LLImageRaw::sRawImageCount, -					LLAppViewer::getTextureFetch()->getNumHTTPRequests(), +					LLAppViewer::getTextureFetch()->getCurlRequest().getNumRequests(),  					LLAppViewer::getImageDecodeThread()->getPending(),   					gTextureList.mCreateTextureList.size()); diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 4c59fd0371..4c59fd0371 100644..100755 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h index 8319752230..8319752230 100644..100755 --- a/indra/newview/llviewerassetstats.h +++ b/indra/newview/llviewerassetstats.h diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index d58ee05fb6..3b486efd7e 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1063,7 +1063,7 @@ void render_hud_attachments()  		gPipeline.pushRenderTypeMask();  		// turn off everything -		gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES); +		gPipeline.clearAllRenderTypes();  		// turn on HUD  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);  		// turn on HUD particles diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index b47a41c44c..b47a41c44c 100644..100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 5d1aa870a3..5d1aa870a3 100644..100755 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index dd5dae1dc1..dd5dae1dc1 100644..100755 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 3515aa4302..885a0721c0 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -139,6 +139,11 @@ bool handle_go_to();  // Export to XML or Collada  void handle_export_selected( void * ); +// Convert strings to internal types +U32 render_type_from_string(std::string render_type); +U32 feature_from_string(std::string feature); +U32 info_display_from_string(std::string info_display); +  class LLViewerMenuHolderGL : public LLMenuHolderGL  {  public: diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 4ad0547379..fe0141e307 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4056,6 +4056,23 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)  } +S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, const std::string &url ) +{ +	S32 retval = 0; +	if (uuid != getTE(te)->getID() || +		uuid == LLUUID::null) +	{ +		retval = LLPrimitive::setTETexture(te, uuid); +		mTEImages[te] = LLViewerTextureManager::getFetchedTextureFromUrl  (url, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid); +		setChanged(TEXTURE); +		if (mDrawable.notNull()) +		{ +			gPipeline.markTextured(mDrawable); +		} +	} +	return retval; +} +  S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host)  {  	S32 retval = 0; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index e60c8a8d52..dc8c7deea9 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -301,6 +301,7 @@ public:  	/*virtual*/	void	setTE(const U8 te, const LLTextureEntry &texture_entry);  	/*virtual*/ S32		setTETexture(const U8 te, const LLUUID &uuid);  	S32 setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host); +	S32 setTETextureCore(const U8 te, const LLUUID& uuid, const std::string &url );  	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);  	/*virtual*/ S32		setTEColor(const U8 te, const LLColor4 &color);  	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index e399b45cba..c036fcc114 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1524,6 +1524,7 @@ static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift");  void LLViewerObjectList::shiftObjects(const LLVector3 &offset)  { +	if (gHeadlessClient) return;  	// This is called when we shift our origin when we cross region boundaries...  	// We need to update many object caches, I'll document this more as I dig through the code  	// cleaning things out... diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 05c7ef5381..fabfde0526 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1578,6 +1578,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)  	capabilityNames.append("UntrustedSimulatorMessage");  	capabilityNames.append("UpdateAgentInformation");  	capabilityNames.append("UpdateAgentLanguage"); +	capabilityNames.append("UpdateAvatarAppearance");  	capabilityNames.append("UpdateGestureAgentInventory");  	capabilityNames.append("UpdateNotecardAgentInventory");  	capabilityNames.append("UpdateScriptAgent"); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 8fef13a6bc..d1c6b7ea79 100644..100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -949,15 +949,8 @@ LLSD LLViewerStats::PhaseMap::dumpPhases()  	for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter)  	{  		const std::string& phase_name = iter->first; -		result[phase_name]["completed"] = !(iter->second.getStarted()); +		result[phase_name]["completed"] = LLSD::Integer(!(iter->second.getStarted()));  		result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32(); -#if 0 // global stats for each phase seem like overkill here -		phase_stats_t::iterator stats_iter = sPhaseStats.find(phase_name); -		if (stats_iter != sPhaseStats.end()) -		{ -			result[phase_name]["stats"] = stats_iter->second.getData(); -		} -#endif  	}  	return result;  } diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 554e4d647e..554e4d647e 100644..100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index e1eb54bd24..8eb8717de2 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -62,6 +62,7 @@  #include "llmediaentry.h"  #include "llvovolume.h"  #include "llviewermedia.h" +#include "lltexturecache.h"  ///////////////////////////////////////////////////////////////////////////////  // statics @@ -409,7 +410,11 @@ void LLViewerTextureManager::cleanup()  void LLViewerTexture::initClass()  {  	LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; -	sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); +	 +	if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) +	{ +		sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio"); +	}  }  // static @@ -1236,7 +1241,7 @@ void LLViewerFetchedTexture::init(bool firstinit)  	mIsMissingAsset = FALSE;  	mLoadedCallbackDesiredDiscardLevel = S8_MAX; -	mPauseLoadedCallBacks = TRUE ; +	mPauseLoadedCallBacks = FALSE ;  	mNeedsCreateTexture = FALSE; @@ -1253,6 +1258,7 @@ void LLViewerFetchedTexture::init(bool firstinit)  	mRequestDeltaTime = 0.f;  	mForSculpt = FALSE ;  	mIsFetched = FALSE ; +	mInFastCacheList = FALSE;  	mCachedRawImage = NULL ;  	mCachedRawDiscardLevel = -1 ; @@ -1266,6 +1272,8 @@ void LLViewerFetchedTexture::init(bool firstinit)  	mLastReferencedSavedRawImageTime = 0.0f ;  	mKeptSavedRawImageTime = 0.f ;  	mLastCallBackActiveTime = 0.f; + +	mInDebug = FALSE;  }  LLViewerFetchedTexture::~LLViewerFetchedTexture() @@ -1310,14 +1318,47 @@ void LLViewerFetchedTexture::cleanup()  	mSavedRawDiscardLevel = -1;  } +//access the fast cache +void LLViewerFetchedTexture::loadFromFastCache() +{ +	if(!mInFastCacheList) +	{ +		return; //no need to access the fast cache. +	} +	mInFastCacheList = FALSE; + +	mRawImage = LLAppViewer::getTextureCache()->readFromFastCache(getID(), mRawDiscardLevel) ; +	if(mRawImage.notNull()) +	{ +		mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; +		mFullHeight = mRawImage->getHeight() << mRawDiscardLevel; +		setTexelsPerImage(); + +		if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE) +		{  +			//discard all oversized textures. +			destroyRawImage(); +			setIsMissingAsset(); +			mRawDiscardLevel = INVALID_DISCARD_LEVEL ; +		} +		else +		{ +			mRequestedDiscardLevel = mDesiredDiscardLevel + 1; +			mIsRawImageValid = TRUE;			 +			addToCreateTexture() ; +		} +	} +} +  void LLViewerFetchedTexture::setForSculpt()  {  	static const S32 MAX_INTERVAL = 8 ; //frames  	mForSculpt = TRUE ; -	if(isForSculptOnly() && !getBoundRecently()) +	if(isForSculptOnly() && hasGLTexture() && !getBoundRecently())  	{  		destroyGLTexture() ; //sculpt image does not need gl texture. +		mTextureState = ACTIVE;  	}  	checkCachedRawSculptImage() ;  	setMaxVirtualSizeResetInterval(MAX_INTERVAL) ; @@ -1735,7 +1776,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()  		S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;  		ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);  		priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR; -		setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far. +		setAdditionalDecodePriority(0.1f) ;//boost the textures without any data so far.  	}  	else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))  	{ @@ -1836,8 +1877,6 @@ F32 LLViewerFetchedTexture::maxDecodePriority()  void LLViewerFetchedTexture::setDecodePriority(F32 priority)  { -	llassert(!mInImageList);  -      	mDecodePriority = priority;  	if(mDecodePriority < F_ALMOST_ZERO) @@ -1898,6 +1937,20 @@ S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching()  	return current_discard ;  } +bool LLViewerFetchedTexture::setDebugFetching(S32 debug_level) +{ +	if(debug_level < 0) +	{ +		mInDebug = FALSE; +		return false; +	} +	mInDebug = TRUE; + +	mDesiredDiscardLevel = debug_level;	 + +	return true; +} +  bool LLViewerFetchedTexture::updateFetch()  {  	static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled"); @@ -1935,6 +1988,10 @@ bool LLViewerFetchedTexture::updateFetch()  	{  		return false; // process any raw image data in callbacks before replacing  	} +	if(mInFastCacheList) +	{ +		return false; +	}  	S32 current_discard = getCurrentDiscardLevelForFetching() ;  	S32 desired_discard = getDesiredDiscardLevel(); @@ -2052,6 +2109,10 @@ bool LLViewerFetchedTexture::updateFetch()  	{  		make_request = false;  	} +	else if(mDesiredDiscardLevel > getMaxDiscardLevel()) +	{ +		make_request = false; +	}  	else if (mNeedsCreateTexture || mIsMissingAsset)  	{  		make_request = false; @@ -2060,6 +2121,11 @@ bool LLViewerFetchedTexture::updateFetch()  	{  		make_request = false;  	} +	else if(mCachedRawImage.notNull() && (current_discard < 0 || current_discard > mCachedRawDiscardLevel)) +	{ +		make_request = false; +		switchToCachedImage() ; //use the cached raw data first +	}  	//else if (!isJustBound() && mCachedRawImageReady)  	//{  	//	make_request = false; @@ -2152,7 +2218,10 @@ bool LLViewerFetchedTexture::updateFetch()  void LLViewerFetchedTexture::clearFetchedResults()  { -	llassert_always(!mNeedsCreateTexture && !mIsFetching); +	if(mNeedsCreateTexture || mIsFetching) +	{ +		return ; +	}  	cleanup();  	destroyGLTexture(); @@ -2167,11 +2236,13 @@ void LLViewerFetchedTexture::forceToDeleteRequest()  {  	if (mHasFetcher)  	{ -		LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);  		mHasFetcher = FALSE;  		mIsFetching = FALSE ; -		resetTextureStats();  	} +		 +	resetTextureStats(); + +	mDesiredDiscardLevel = getMaxDiscardLevel() + 1;  }  void LLViewerFetchedTexture::setIsMissingAsset() @@ -2215,10 +2286,18 @@ void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_call  		mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ;  	} -	if(mPauseLoadedCallBacks && !pause) +	if(mPauseLoadedCallBacks) +	{ +		if(!pause) +		{ +			unpauseLoadedCallbacks(src_callback_list) ; +		} +	} +	else if(pause)  	{ -		unpauseLoadedCallbacks(src_callback_list) ; +		pauseLoadedCallbacks(src_callback_list) ;  	} +  	LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);  	mLoadedCallbackList.push_back(entryp);	 diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index f1105c3705..2ea9a07e9a 100644..100755 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -436,6 +436,8 @@ public:  	void setMinDiscardLevel(S32 discard) 	{ mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }  	bool updateFetch(); +	bool setDebugFetching(S32 debug_level); +	bool isInDebug() {return mInDebug;}  	void clearFetchedResults(); //clear all fetched results, for debug use. @@ -498,6 +500,9 @@ public:  	void        setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}  	void        forceToDeleteRequest(); +	void        loadFromFastCache(); +	void        setInFastCacheList(bool in_list) { mInFastCacheList = in_list; } +	bool        isInFastCacheList() { return mInFastCacheList; }  protected:  	/*virtual*/ void switchToCachedImage();  	S32 getCurrentDiscardLevelForFetching() ; @@ -516,6 +521,8 @@ private:  private:  	BOOL  mFullyLoaded; +	BOOL  mInDebug; +	BOOL  mInFastCacheList;  protected:		  	std::string mLocalFileName; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 9a6c0569a9..e4669cde34 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,7 +58,7 @@  #include "pipeline.h"  #include "llappviewer.h"  #include "llxuiparser.h" -#include "llagent.h" +#include "llviewerdisplay.h"  //////////////////////////////////////////////////////////////////////////// @@ -276,6 +276,7 @@ void LLViewerTextureList::shutdown()  	// Flush all of the references  	mLoadingStreamList.clear();  	mCreateTextureList.clear(); +	mFastCacheList.clear();  	mUUIDMap.clear(); @@ -453,6 +454,8 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,  												   LLGLenum primary_format,  												   LLHost request_from_host)  { +	static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled"); +  	LLPointer<LLViewerFetchedTexture> imagep ;  	switch(texture_type)  	{ @@ -490,6 +493,11 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,  		imagep->forceActive() ;  	} +	if(fast_cache_fetching_enabled) +	{ +		mFastCacheList.insert(imagep); +		imagep->setInFastCacheList(true); +	}  	return imagep ;  } @@ -503,6 +511,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id)  void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)  { +	assert_main_thread();  	llassert_always(mInitialized) ;  	llassert(image);  	if (image->isInImageList()) @@ -519,6 +528,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)  void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)  { +	assert_main_thread();  	llassert_always(mInitialized) ;  	llassert(image);  	if (!image->isInImageList()) @@ -593,16 +603,24 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_MARK_DIRTY("Dirty Images");  static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_PRIORITIES("Prioritize");  static LLFastTimer::DeclareTimer FTM_IMAGE_CALLBACKS("Callbacks");  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");  void LLViewerTextureList::updateImages(F32 max_time)  { -	if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) +	static BOOL cleared = FALSE; +	if(gTeleportDisplay)  	{ -		clearFetchingRequests(); +		if(!cleared) +		{ +			clearFetchingRequests(); +			gPipeline.clearRebuildGroups(); +			cleared = TRUE; +		}  		return;  	} +	cleared = FALSE;  	LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); @@ -613,6 +631,11 @@ void LLViewerTextureList::updateImages(F32 max_time)  	LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));  	LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); +	{ +		//loading from fast cache  +		LLFastTimer t(FTM_FAST_CACHE_IMAGE_FETCH); +		max_time -= updateImagesLoadingFastCache(max_time); +	}  	{  		LLFastTimer t(FTM_IMAGE_UPDATE_PRIORITIES); @@ -673,14 +696,13 @@ void LLViewerTextureList::clearFetchingRequests()  		return;  	} +	LLAppViewer::getTextureFetch()->deleteAllRequests(); +  	for (image_priority_list_t::iterator iter = mImageList.begin();  		 iter != mImageList.end(); ++iter)  	{ -		LLViewerFetchedTexture* image = *iter; -		if(image->hasFetcher()) -		{ -			image->forceToDeleteRequest() ; -		} +		LLViewerFetchedTexture* imagep = *iter; +		imagep->forceToDeleteRequest() ;  	}  } @@ -688,10 +710,11 @@ void LLViewerTextureList::updateImagesDecodePriorities()  {  	// Update the decode priority for N images each frame  	{ -		const size_t max_update_count = llmin((S32) (1024*gFrameIntervalSeconds) + 1, 32); //target 1024 textures per second -		S32 update_counter = llmin(max_update_count, mUUIDMap.size()/10); +        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); +		S32 update_counter = llmin(max_update_count, mUUIDMap.size());  		uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateUUID); -		while(update_counter > 0 && !mUUIDMap.empty()) +		while ((update_counter-- > 0) && !mUUIDMap.empty())  		{  			if (iter == mUUIDMap.end())  			{ @@ -699,7 +722,13 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			}  			mLastUpdateUUID = iter->first;  			LLPointer<LLViewerFetchedTexture> imagep = iter->second; -			++iter; // safe to incrament now +			++iter; // safe to increment now + +			if(imagep->isInDebug()) +			{ +				update_counter--; +				continue; //is in debug, ignore. +			}  			//  			// Flush formatted images using a lazy flush @@ -754,7 +783,16 @@ void LLViewerTextureList::updateImagesDecodePriorities()  					imagep->setInactive() ;										  				}  			} -			 + +			if (!imagep->isInImageList()) +			{ +				continue; +			} +			if(imagep->isInFastCacheList()) +			{ +				continue; //wait for loading from the fast cache. +			} +  			imagep->processTextureStats();  			F32 old_priority = imagep->getDecodePriority();  			F32 old_priority_test = llmax(old_priority, 0.0f); @@ -764,15 +802,35 @@ void LLViewerTextureList::updateImagesDecodePriorities()  			if ((decode_priority_test < old_priority_test * .8f) ||  				(decode_priority_test > old_priority_test * 1.25f))  			{ -				removeImageFromList(imagep); +				mImageList.erase(imagep) ;  				imagep->setDecodePriority(decode_priority); -				addImageToList(imagep); +				mImageList.insert(imagep);  			} -			update_counter--;  		}  	}  } +void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level) +{ +	if(!tex->setDebugFetching(debug_level)) +	{ +		return; +	} + +	const F32 DEBUG_PRIORITY = 100000.f; +	F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f); +	F32 decode_priority_test = DEBUG_PRIORITY; +	 +	// Ignore < 20% difference +	if ((decode_priority_test < old_priority_test * .8f) || +		(decode_priority_test > old_priority_test * 1.25f)) +	{ +		removeImageFromList(tex); +		tex->setDecodePriority(decode_priority_test); +		addImageToList(tex); +	} +} +  /*   static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host)   { @@ -827,6 +885,36 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)  	return create_timer.getElapsedTimeF32();  } +F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) +{ +	if (gGLManager.mIsDisabled) return 0.0f; +	if(mFastCacheList.empty()) +	{ +		return 0.f; +	} +	 +	// +	// loading texture raw data from the fast cache directly. +	// +		 +	LLTimer timer; +	image_list_t::iterator enditer = mFastCacheList.begin(); +	for (image_list_t::iterator iter = mFastCacheList.begin(); +		 iter != mFastCacheList.end();) +	{ +		image_list_t::iterator curiter = iter++; +		enditer = iter; +		LLViewerFetchedTexture *imagep = *curiter; +		imagep->loadFromFastCache(); +		if (timer.getElapsedTimeF32() > max_time) +		{ +			break; +		} +	} +	mFastCacheList.erase(mFastCacheList.begin(), enditer); +	return timer.getElapsedTimeF32(); +} +  void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)  {  	if(!imagep) @@ -850,15 +938,24 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)  {  	LLTimer image_op_timer; -	// Update the decode priority for N images each frame -	// Make a list with 32 high priority entries + 256 cycled entries -	const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); -	const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); +	// Update fetch for N images each frame +	static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority");         // default: 32 +	static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority");       // default: 256 +	static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority");       // default: 32 +	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); +	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); +	max_update_count = llmin(max_update_count, total_update_count);	 -	// 32 high priority entries +	// MAX_HIGH_PRIO_COUNT high priority entries  	typedef std::vector<LLViewerFetchedTexture*> entries_list_t;  	entries_list_t entries; -	size_t update_counter = llmin(max_priority_count, mImageList.size()); +	size_t update_counter = max_priority_count;  	image_priority_list_t::iterator iter1 = mImageList.begin();  	while(update_counter > 0)  	{ @@ -868,43 +965,46 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)  		update_counter--;  	} -	// 256 cycled entries -	update_counter = llmin(max_update_count, mUUIDMap.size());	 +	// MAX_UPDATE_COUNT cycled entries +	update_counter = max_update_count;	  	if(update_counter > 0)  	{  		uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); -		uuid_map_t::iterator iter2p = iter2; -		while(update_counter > 0) +		while ((update_counter > 0) && (total_update_count > 0))  		{  			if (iter2 == mUUIDMap.end())  			{  				iter2 = mUUIDMap.begin();  			} -			entries.push_back(iter2->second); -			iter2p = iter2++; -			update_counter--; +			LLViewerFetchedTexture* imagep = iter2->second; +            // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set. +            if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher()))) +            { +                entries.push_back(imagep); +                update_counter--; +            } + +			iter2++; +			total_update_count--;  		} - -		mLastFetchUUID = iter2p->first;  	}  	S32 fetch_count = 0; -	S32 min_count = max_priority_count + max_update_count/4; +	size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); +	S32 min_count = max_priority_count + min_update_count;  	for (entries_list_t::iterator iter3 = entries.begin();  		 iter3 != entries.end(); )  	{  		LLViewerFetchedTexture* imagep = *iter3++; -		 -		bool fetching = imagep->updateFetch(); -		if (fetching) +		fetch_count += (imagep->updateFetch() ? 1 : 0); +		if (min_count <= min_update_count)  		{ -			fetch_count++; +			mLastFetchUUID = imagep->getID();  		} -		if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time) +		if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))  		{  			break;  		} -		min_count--;  	}  	//if (fetch_count == 0)  	//{ @@ -936,6 +1036,9 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)  {  	LLTimer timer; +	//loading from fast cache  +	updateImagesLoadingFastCache(max_time); +  	// Update texture stats and priorities  	std::vector<LLPointer<LLViewerFetchedTexture> > image_list;  	for (image_priority_list_t::iterator iter = mImageList.begin(); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index e89997fe28..3dda973d3f 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -111,6 +111,7 @@ public:  	void doPrefetchImages();  	void clearFetchingRequests(); +	void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level);  	static S32 getMinVideoRamSetting();  	static S32 getMaxVideoRamSetting(bool get_recommended = false); @@ -120,6 +121,7 @@ private:  	F32  updateImagesCreateTextures(F32 max_time);  	F32  updateImagesFetchTextures(F32 max_time);  	void updateImagesUpdateStats(); +	F32  updateImagesLoadingFastCache(F32 max_time);  	void addImage(LLViewerFetchedTexture *image);  	void deleteImage(LLViewerFetchedTexture *image); @@ -173,6 +175,7 @@ public:  	image_list_t mLoadingStreamList;  	image_list_t mCreateTextureList;  	image_list_t mCallbackList; +	image_list_t mFastCacheList;  	// Note: just raw pointers because they are never referenced, just compared against  	std::set<LLViewerFetchedTexture*> mDirtyTextureList; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index af2eec9ba8..62bdb87022 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1713,6 +1713,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)  void LLViewerWindow::initGLDefaults()  { +	if (gHeadlessClient) return;  	gGL.setSceneBlendType(LLRender::BT_ALPHA);  	if (!LLGLSLShader::sNoFixedFunction) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index c0ef1d7a4b..8d9109d9ff 100644..100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -688,12 +688,13 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mFullyLoaded(FALSE),  	mPreviousFullyLoaded(FALSE),  	mFullyLoadedInitialized(FALSE), -	mSupportsAlphaLayers(FALSE),  	mLoadedCallbacksPaused(FALSE),  	mHasPelvisOffset( FALSE ),  	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")), -	mLastRezzedStatus(-1) - +	mLastRezzedStatus(-1), +	mIsEditingAppearance(FALSE), +	mUseLocalAppearance(FALSE), +	mUseServerBakes(TRUE)  {  	LLMemType mt(LLMemType::MTYPE_AVATAR);  	//VTResume();  // VTune @@ -2381,6 +2382,12 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)  	// to redirect certain avatar texture requests to different sims.  	if (isIndexBakedTexture((ETextureIndex)te))  	{ +		const std::string url = getImageURL(te,uuid); +		if (!url.empty()) +		{ +			return setTETextureCore(te, uuid, url); +		} +  		LLHost target_host = getObjectHost();  		return setTETextureCore(te, uuid, target_host);  	} @@ -4149,7 +4156,7 @@ void LLVOAvatar::updateVisibility()  // private  bool LLVOAvatar::shouldAlphaMask()  { -	const bool should_alpha_mask = mSupportsAlphaLayers && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked +	const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked  							&& !LLDrawPoolAvatar::sSkipTransparent;  	return should_alpha_mask; @@ -4588,6 +4595,7 @@ void LLVOAvatar::updateTextures()  			if (isIndexBakedTexture((ETextureIndex)texture_index)  				&& imagep->getID() != IMG_DEFAULT_AVATAR  				&& imagep->getID() != IMG_INVISIBLE +				&& !mUseServerBakes   				&& !imagep->getTargetHost().isOk())  			{  				LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture " @@ -4682,7 +4690,10 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel  	//the texture pipeline will stop fetching this texture.  	imagep->resetTextureStats(); -	imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures. +	// TODO: currently default to HTTP texture and fall back to UDP if cannot be found there. +	// Once server messaging is in place, we should call setCanUseHTTP(false) for old style +	// appearance requests +	imagep->setCanUseHTTP(true);  	imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);  	imagep->resetMaxVirtualSizeResetCounter() ; @@ -4724,6 +4735,21 @@ void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te)  	setTE(index, te);  } +const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid) +{ +	std::string url = ""; +	if (LLAppearanceMgr::instance().useServerTextureBaking() && !gSavedSettings.getString("AgentAppearanceServiceURL").empty()) +	{ +		const LLVOAvatarDictionary::TextureEntry* texture_entry = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)te); +		if (texture_entry != NULL) +		{ +			url = gSavedSettings.getString("AgentAppearanceServiceURL") + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString(); +			//llinfos << "baked texture url: " << url << llendl; +		} +	} +	return url; +} +  //-----------------------------------------------------------------------------  // resolveHeight()  //----------------------------------------------------------------------------- @@ -6669,14 +6695,13 @@ void LLVOAvatar::updateMeshTextures()  		}  	} -	const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures  	const BOOL other_culled = !isSelf() && mCulled;  	LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;  	BOOL paused = FALSE;  	if(!isSelf())  	{  		src_callback_list = &mCallbackTextureList ; -		paused = mLoadedCallbacksPaused ; +		paused = !isVisible();  	}  	std::vector<BOOL> is_layer_baked; @@ -6709,36 +6734,39 @@ void LLVOAvatar::updateMeshTextures()  		{  			use_lkg_baked_layer[i] = (!is_layer_baked[i]   									  && mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR); -			if (mBakedTextureDatas[i].mTexLayerSet) -			{ -				mBakedTextureDatas[i].mTexLayerSet->destroyComposite(); -			}  		}  	} - -	// Turn on alpha masking correctly for yourself and other avatars on 1.23+ -	mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR]; - -	// Baked textures should be requested from the sim this avatar is on. JC -	const LLHost target_host = getObjectHost(); -	if (!target_host.isOk()) -	{ -		llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl; -	}  	for (U32 i=0; i < mBakedTextureDatas.size(); i++)  	{ -		if (use_lkg_baked_layer[i] && !self_customizing ) +		if (use_lkg_baked_layer[i] && !mUseLocalAppearance )  		{ -			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); +			LLViewerFetchedTexture* baked_img; +			const std::string url = getImageURL(i, mBakedTextureDatas[i].mLastTextureIndex); +			if (!url.empty()) +			{ +				baked_img = LLViewerTextureManager::getFetchedTextureFromUrl(url, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, mBakedTextureDatas[i].mLastTextureIndex); +			} +			else +			{ +				// Baked textures should be requested from the sim this avatar is on. JC +				const LLHost target_host = getObjectHost(); +				if (!target_host.isOk()) +				{ +					llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl; +				} + +				baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host ); +			} +  			mBakedTextureDatas[i].mIsUsed = TRUE;  			for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)  			{  				mBakedTextureDatas[i].mMeshes[k]->setTexture( baked_img );  			}  		} -		else if (!self_customizing && is_layer_baked[i]) +		else if (!mUseLocalAppearance && is_layer_baked[i])  		{  			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;  			if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex ) @@ -6758,8 +6786,7 @@ void LLVOAvatar::updateMeshTextures()  					src_callback_list, paused );  			}  		} -		else if (mBakedTextureDatas[i].mTexLayerSet  -				 && !other_culled)  +		else if (mBakedTextureDatas[i].mTexLayerSet && mUseLocalAppearance)   		{  			mBakedTextureDatas[i].mTexLayerSet->createComposite();  			mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( TRUE ); @@ -6774,7 +6801,7 @@ void LLVOAvatar::updateMeshTextures()  	// set texture and color of hair manually if we are not using a baked image.  	// This can happen while loading hair for yourself, or for clients that did not  	// bake a hair texture. Still needed for yourself after 1.22 is depricated. -	if (!is_layer_baked[BAKED_HAIR] || self_customizing) +	if (!is_layer_baked[BAKED_HAIR] || mIsEditingAppearance)  	{  		const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);  		LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 ); @@ -7221,7 +7248,7 @@ void LLVOAvatar::onFirstTEMessageReceived()  		if(!isSelf())  		{  			src_callback_list = &mCallbackTextureList ; -			paused = mLoadedCallbacksPaused ; +			paused = !isVisible();  		}  		for (U32 i = 0; i < mBakedTextureDatas.size(); i++) @@ -7309,7 +7336,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	if( isSelf() )  	{  		llwarns << avString() << "Received AvatarAppearance for self" << llendl; -		if( mFirstTEMessageReceived ) +		if( mFirstTEMessageReceived && !LLAppearanceMgr::instance().useServerTextureBaking())  		{  //			llinfos << "processAvatarAppearance end  " << mID << llendl;  			return; @@ -7320,9 +7347,44 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  //	llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl;  //	dumpAvatarTEs( "PRE  processAvatarAppearance()" ); -	unpackTEMessage(mesgsys, _PREHASH_ObjectData); +	LLTEContents tec; +	parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, tec);  //	dumpAvatarTEs( "POST processAvatarAppearance()" ); +	U8 appearance_version = 0; +	S32 this_update_cof_version = LLViewerInventoryCategory::VERSION_UNKNOWN; +	S32 last_update_request_cof_version = LLAppearanceMgr::instance().mLastUpdateRequestCOFVersion; +	// For future use: +	//U32 appearance_flags = 0; + +	if (mesgsys->has(_PREHASH_AppearanceData)) +	{ +		mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, appearance_version, 0); +		mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, this_update_cof_version, 0); +		// For future use: +		//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0); +	} + +	if (appearance_version > 0) +	{ +		mUseServerBakes = true; +	} +	else +	{ +		mUseServerBakes = false; +	} + +	// Check for stale update. +	if (mUseServerBakes && isSelf() +		&& this_update_cof_version >= LLViewerInventoryCategory::VERSION_INITIAL +		&& this_update_cof_version < last_update_request_cof_version) +	{ +		llwarns << "Stale appearance update, wanted version " << last_update_request_cof_version +				<< ", got " << this_update_cof_version << llendl; +		return; +	} +	applyParsedTEMessage(tec); +  	// prevent the overwriting of valid baked textures with invalid baked textures  	for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)  	{ @@ -7345,16 +7407,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	}  	setCompositeUpdatesEnabled( FALSE ); -	mMeshTexturesDirty = TRUE;  	gPipeline.markGLRebuild(this); -	// ! BACKWARDS COMPATIBILITY ! -	// Non-self avatars will no longer have component textures -	if (!isSelf()) -	{ -		releaseComponentTextures(); -	} -	  	// parse visual params  	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 @@ -7464,6 +7518,13 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )  	// If all of the avatars are completely baked, release the global image caches to conserve memory.  	LLVOAvatar::cullAvatarsByPixelArea(); +	if (isSelf()) +	{ +		mUseLocalAppearance = false; +	} + +	updateMeshTextures(); +  //	llinfos << "processAvatarAppearance end " << mID << llendl;  } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 1adb680962..a32e7567ad 100644..100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -227,9 +227,6 @@ public:  private: //aligned members  	LL_ALIGN_16(LLVector4a	mImpostorExtents[2]); -private: -	BOOL			mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients -  	//--------------------------------------------------------------------  	// Updates  	//-------------------------------------------------------------------- @@ -617,6 +614,7 @@ protected:  private:  	virtual	void				setImage(const U8 te, LLViewerTexture *imagep, const U32 index);   	virtual LLViewerTexture*	getImage(const U8 te, const U32 index) const; +	const std::string 			getImageURL(const U8 te, const LLUUID &uuid);  	virtual const LLTextureEntry* getTexEntry(const U8 te_num) const;  	virtual void setTexEntry(const U8 index, const LLTextureEntry &te); @@ -716,6 +714,9 @@ private:  	BOOL			mAppearanceAnimating;  	LLFrameTimer	mAppearanceMorphTimer;  	F32				mLastAppearanceBlendTime; +	BOOL			mIsEditingAppearance; +	BOOL			mUseLocalAppearance; +	BOOL			mUseServerBakes;  	//--------------------------------------------------------------------  	// Clothing colors (convenience functions to access visual parameters) diff --git a/indra/newview/llvoavatardefines.cpp b/indra/newview/llvoavatardefines.cpp index 1ed4e3b61c..ef96a9e923 100644 --- a/indra/newview/llvoavatardefines.cpp +++ b/indra/newview/llvoavatardefines.cpp @@ -66,12 +66,12 @@ LLVOAvatarDictionary::Textures::Textures()  	addEntry(TEX_UPPER_TATTOO,                new TextureEntry("upper_tattoo",     TRUE,  BAKED_NUM_INDICES, "",     LLWearableType::WT_TATTOO));  	addEntry(TEX_LOWER_TATTOO,                new TextureEntry("lower_tattoo",     TRUE,  BAKED_NUM_INDICES, "",     LLWearableType::WT_TATTOO)); -	addEntry(TEX_HEAD_BAKED,                  new TextureEntry("head-baked",       FALSE, BAKED_HEAD)); -	addEntry(TEX_UPPER_BAKED,                 new TextureEntry("upper-baked",      FALSE, BAKED_UPPER)); -	addEntry(TEX_LOWER_BAKED,                 new TextureEntry("lower-baked",      FALSE, BAKED_LOWER)); -	addEntry(TEX_EYES_BAKED,                  new TextureEntry("eyes-baked",       FALSE, BAKED_EYES)); -	addEntry(TEX_HAIR_BAKED,                  new TextureEntry("hair-baked",       FALSE, BAKED_HAIR)); -	addEntry(TEX_SKIRT_BAKED,                 new TextureEntry("skirt-baked",      FALSE, BAKED_SKIRT)); +	addEntry(TEX_HEAD_BAKED,                  new TextureEntry("head-baked",       FALSE, BAKED_HEAD, "head")); +	addEntry(TEX_UPPER_BAKED,                 new TextureEntry("upper-baked",      FALSE, BAKED_UPPER, "upper")); +	addEntry(TEX_LOWER_BAKED,                 new TextureEntry("lower-baked",      FALSE, BAKED_LOWER, "lower")); +	addEntry(TEX_EYES_BAKED,                  new TextureEntry("eyes-baked",       FALSE, BAKED_EYES, "eyes")); +	addEntry(TEX_HAIR_BAKED,                  new TextureEntry("hair-baked",       FALSE, BAKED_HAIR, "hair")); +	addEntry(TEX_SKIRT_BAKED,                 new TextureEntry("skirt-baked",      FALSE, BAKED_SKIRT, "skirt"));  }  LLVOAvatarDictionary::BakedTextures::BakedTextures() diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 07b9b78255..b3e5054e78 100644..100755 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -812,7 +812,7 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,  		updateMeshTextures();  		// unpack the texture UUIDs to the texture slots -		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); +		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++) @@ -885,7 +885,10 @@ void LLVOAvatarSelf::removeMissingBakedTextures()  			invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, FALSE);  		}  		updateMeshTextures(); -		requestLayerSetUploads(); +		if (!LLAppearanceMgr::instance().useServerTextureBaking()) +		{ +			requestLayerSetUploads(); +		}  	}  } @@ -1628,7 +1631,7 @@ void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_r  	layerset->requestUpdate();  	layerset->invalidateMorphMasks(); -	if( upload_result ) +	if( upload_result  && !LLAppearanceMgr::instance().useServerTextureBaking())  	{  		llassert(isSelf()); @@ -2130,9 +2133,7 @@ LLSD LLVOAvatarSelf::metricsData()  {  	// runway - add region info  	LLSD result; -	result["id"] = getID();  	result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus()); -	result["is_self"] = isSelf();  	std::vector<S32> rez_counts;  	LLVOAvatar::getNearbyRezzedStats(rez_counts);  	result["nearby"] = LLSD::emptyMap(); @@ -2146,7 +2147,6 @@ LLSD LLVOAvatarSelf::metricsData()  	result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();  	result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32();  	result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32(); -	result["phases"] = getPhases().dumpPhases();  	result["startup"] = LLStartUp::getPhases().dumpPhases();  	return result; @@ -2155,7 +2155,12 @@ LLSD LLVOAvatarSelf::metricsData()  class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder  {  public: -	ViewerAppearanceChangeMetricsResponder() +	ViewerAppearanceChangeMetricsResponder( S32 expected_sequence, +											volatile const S32 & live_sequence, +											volatile bool & reporting_started): +		mExpectedSequence(expected_sequence), +		mLiveSequence(live_sequence), +		mReportingStarted(reporting_started)  	{  	} @@ -2174,14 +2179,44 @@ public:  			error(status,reason);  		}  	} + +	// virtual +	void error(U32 status_num, const std::string & reason) +	{ +	} + +	// virtual +	void result(const LLSD & content) +	{ +		if (mLiveSequence == mExpectedSequence) +		{ +			mReportingStarted = true; +		} +	} + +private: +	S32 mExpectedSequence; +	volatile const S32 & mLiveSequence; +	volatile bool & mReportingStarted;  };  void LLVOAvatarSelf::sendAppearanceChangeMetrics()  {  	// gAgentAvatarp->stopAllPhases(); +	static volatile bool reporting_started(false); +	static volatile S32 report_sequence(0);  	LLSD msg = metricsData();  	msg["message"] = "ViewerAppearanceChangeMetrics"; +	msg["session_id"] = gAgentSessionID; +	msg["agent_id"] = gAgentID; +	msg["sequence"] = report_sequence; +	msg["initial"] = !reporting_started; +	msg["break"] = false; + +	// Update sequence number +	if (S32_MAX == ++report_sequence) +		report_sequence = 0;  	LL_DEBUGS("Avatar") << avString() << "message: " << ll_pretty_print_sd(msg) << LL_ENDL;  	std::string	caps_url; @@ -2194,8 +2229,10 @@ void LLVOAvatarSelf::sendAppearanceChangeMetrics()  	{  		LLCurlRequest::headers_t headers;  		LLHTTPClient::post(caps_url, -							msg, -							new ViewerAppearanceChangeMetricsResponder); +						   msg, +						   new ViewerAppearanceChangeMetricsResponder(report_sequence, +																	  report_sequence, +																	  reporting_started));  	}  } @@ -2666,19 +2703,43 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const  // static -void LLVOAvatarSelf::onCustomizeStart() +void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)  { -	// We're no longer doing any baking or invalidating on entering  -	// appearance editing mode. Leaving function in place in case  -	// further changes require us to do something at this point - Nyx +	if (isAgentAvatarValid()) +	{ +		gAgentAvatarp->mIsEditingAppearance = true; +		gAgentAvatarp->mUseLocalAppearance = true; + +		if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) +		{ +			gAgentCamera.changeCameraToCustomizeAvatar(); +		} + +		gAgentAvatarp->invalidateAll(); +		gAgentAvatarp->updateMeshTextures(); +	}  }  // static -void LLVOAvatarSelf::onCustomizeEnd() +void LLVOAvatarSelf::onCustomizeEnd(bool disable_camera_switch)  { +	gAgentAvatarp->mIsEditingAppearance = false; +	if (!LLAppearanceMgr::instance().useServerTextureBaking()) +	{ +		gAgentAvatarp->mUseLocalAppearance = false; +	} +  	if (isAgentAvatarValid())  	{  		gAgentAvatarp->invalidateAll(); + +		if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch) +		{ +			gAgentCamera.changeCameraToDefault(); +			gAgentCamera.resetView(); +		} + +		LLAppearanceMgr::instance().updateAppearanceFromCOF();  	}  } diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 7bd0c0bf93..e555a566c5 100644..100755 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -340,8 +340,8 @@ private:   **/  public: -	static void		onCustomizeStart(); -	static void		onCustomizeEnd(); +	static void		onCustomizeStart(bool disable_camera_switch = false); +	static void		onCustomizeEnd(bool disable_camera_switch = false);  	//--------------------------------------------------------------------  	// Visibility diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 958282f1eb..b43bdb69f8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -370,7 +370,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,  		// Unpack texture entry data  		// -		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); +		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);  		if (result & teDirtyBits)  		{  			updateTEData(); @@ -822,7 +822,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  				}  			} -			S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture +			S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture  			S32 current_discard = getVolume() ? getVolume()->getSculptLevel() : -2 ;  			if (texture_discard >= 0 && //texture has some data available @@ -1128,7 +1128,7 @@ void LLVOVolume::sculpt()  		S8 sculpt_components = 0;  		const U8* sculpt_data = NULL; -		S32 discard_level = mSculptTexture->getDiscardLevel() ; +		S32 discard_level = mSculptTexture->getCachedRawImageLevel() ;  		LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ;  		S32 max_discard = mSculptTexture->getMaxDiscardLevel(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f6b0d6c5fa..0b98119b19 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -72,6 +72,7 @@  #include "llhudtext.h"  #include "lllightconstants.h"  #include "llmeshrepository.h" +#include "llpipelinelistener.h"  #include "llresmgr.h"  #include "llselectmgr.h"  #include "llsky.h" @@ -378,6 +379,8 @@ BOOL    LLPipeline::sMemAllocationThrottled = FALSE;  S32		LLPipeline::sVisibleLightCount = 0;  F32		LLPipeline::sMinRenderSize = 0.f; +// EventHost API LLPipeline listener. +static LLPipelineListener sPipelineListener;  static LLCullResult* sCull = NULL; @@ -494,19 +497,29 @@ void LLPipeline::init()  	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();  	resetFrameStats(); -	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) +	if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))  	{ -		mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled +		clearAllRenderDebugFeatures();  	} +	else +	{ +		setAllRenderDebugFeatures(); // By default, all debugging features on +	} +	clearAllRenderDebugDisplays(); // All debug displays off -	mRenderDebugFeatureMask = 0xffffffff; // All debugging features on -	mRenderDebugMask = 0;	// All debug starts off - -	// Don't turn on ground when this is set -	// Mac Books with intel 950s need this -	if(!gSavedSettings.getBOOL("RenderGround")) +	if (gSavedSettings.getBOOL("DisableAllRenderTypes"))  	{ -		toggleRenderType(RENDER_TYPE_GROUND); +		clearAllRenderTypes(); +	} +	else +	{ +		setAllRenderTypes(); // By default, all rendering types start enabled +		// Don't turn on ground when this is set +		// Mac Books with intel 950s need this +		if(!gSavedSettings.getBOOL("RenderGround")) +		{ +			toggleRenderType(RENDER_TYPE_GROUND); +		}  	}  	// make sure RenderPerformanceTest persists (hackity hack hack) @@ -1126,6 +1139,7 @@ void LLPipeline::releaseScreenBuffers()  void LLPipeline::createGLBuffers()  { +	if (gHeadlessClient) return;  	stop_glerror();  	LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS);  	assertInitialized(); @@ -2563,6 +2577,31 @@ void LLPipeline::updateGL()  static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups"); +void LLPipeline::clearRebuildGroups() +{ +	mGroupQ1Locked = true; +	// Iterate through all drawables on the priority build queue, +	for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); +		 iter != mGroupQ1.end(); ++iter) +	{ +		LLSpatialGroup* group = *iter; +		group->clearState(LLSpatialGroup::IN_BUILD_Q1); +	} +	mGroupQ1.clear(); +	mGroupQ1Locked = false; + +	mGroupQ2Locked = true; +	for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); +		 iter != mGroupQ2.end(); ++iter) +	{ +		LLSpatialGroup* group = *iter; +		group->clearState(LLSpatialGroup::IN_BUILD_Q2); +	}	 + +	mGroupQ2.clear(); +	mGroupQ2Locked = false; +} +  void LLPipeline::rebuildPriorityGroups()  {  	LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS); @@ -6387,6 +6426,22 @@ void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)  	}  } +void LLPipeline::pushRenderDebugFeatureMask() +{ +	mRenderDebugFeatureStack.push(mRenderDebugFeatureMask); +} + +void LLPipeline::popRenderDebugFeatureMask() +{ +	if (mRenderDebugFeatureStack.empty()) +	{ +		llerrs << "Depleted render feature stack." << llendl; +	} + +	mRenderDebugFeatureMask = mRenderDebugFeatureStack.top(); +	mRenderDebugFeatureStack.pop(); +} +  // static  void LLPipeline::setRenderScriptedBeacons(BOOL val)  { @@ -10362,6 +10417,22 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...)  	}  } +void LLPipeline::setAllRenderTypes() +{ +	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) +	{ +		mRenderTypeEnabled[i] = TRUE; +	} +} + +void LLPipeline::clearAllRenderTypes() +{ +	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) +	{ +		mRenderTypeEnabled[i] = FALSE; +	} +} +  void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color)  {  	DebugBlip blip(position, color); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 0140e24d63..68ae1e7050 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -223,6 +223,7 @@ public:  	void updateGL();  	void rebuildPriorityGroups();  	void rebuildGroups(); +	void clearRebuildGroups();  	//calculate pixel area of given box from vantage point of given camera  	static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); @@ -304,20 +305,28 @@ public:  	BOOL hasRenderDebugFeatureMask(const U32 mask) const	{ return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }  	BOOL hasRenderDebugMask(const U32 mask) const			{ return (mRenderDebugMask & mask) ? TRUE : FALSE; } -	 - +	void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; } +	void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; } +	void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; } +	void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; }  	BOOL hasRenderType(const U32 type) const;  	BOOL hasAnyRenderType(const U32 type, ...) const;  	void setRenderTypeMask(U32 type, ...); -	void orRenderTypeMask(U32 type, ...); +	// This is equivalent to 'setRenderTypeMask' +	//void orRenderTypeMask(U32 type, ...);  	void andRenderTypeMask(U32 type, ...);  	void clearRenderTypeMask(U32 type, ...); +	void setAllRenderTypes(); +	void clearAllRenderTypes();  	void pushRenderTypeMask();  	void popRenderTypeMask(); +	void pushRenderDebugFeatureMask(); +	void popRenderDebugFeatureMask(); +  	static void toggleRenderType(U32 type);  	// For UI control of render features @@ -614,6 +623,7 @@ protected:  	U32						mRenderDebugFeatureMask;  	U32						mRenderDebugMask; +	std::stack<U32>			mRenderDebugFeatureStack;  	U32						mOldRenderDebugMask; diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml index f3f8d4ddca..1ea256b8b3 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml @@ -2,7 +2,7 @@  <floater   legacy_header_height="18"   can_minimize="false" - height="550" + height="600"   layout="topleft"   name="TexFetchDebugger"   help_topic="texfetchdebugger" @@ -195,10 +195,34 @@    height="25"    layout="topleft"    left_delta="0" +  name="total_time_refetch_all_cache_label" +  top_delta="25" +  width="540"> +    16, Refetching all textures from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels +  </text> +  <text +  type="string" +  length="1" +  follows="left|top" +  height="25" +  layout="topleft" +  left_delta="0"    name="total_time_refetch_vis_http_label"    top_delta="25"    width="540"> -    16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels +    17, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels +  </text> +  <text +  type="string" +  length="1" +  follows="left|top" +  height="25" +  layout="topleft" +  left_delta="0" +  name="total_time_refetch_all_http_label" +  top_delta="25" +  width="540"> +    18, Refetching all textures from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels    </text>    <spinner       decimal_digits="2" @@ -206,7 +230,7 @@       height="20"       increment="0.01"       initial_value="1.0" -     label="17, Ratio of Texel/Pixel:" +     label="19, Ratio of Texel/Pixel:"       label_width="130"       layout="topleft"       left_delta="0" @@ -218,14 +242,53 @@      <spinner.commit_callback  		function="TexFetchDebugger.ChangeTexelPixelRatio" />    </spinner> +  <text +  type="string" +  length="1" +  follows="left|top" +  height="25" +  layout="topleft" +  left_delta="0" +  name="texture_source_label" +  top_delta="30" +  width="110"> +    20, Texture Source: +  </text> +  <radio_group +     control_name="TextureFetchSource" +     follows="top|left" +     draw_border="false" +     height="25" +     layout="topleft" +     left_pad="0" +     name="texture_source" +     top_delta="0" +     width="264"> +    <radio_item +     height="16" +     label="Cache + HTTP" +     layout="topleft" +     left="3" +     name="0" +     top="0" +     width="100" /> +    <radio_item +     height="16" +     label="HTTP Only" +     layout="topleft" +     left_delta="100" +     name="1" +     top_delta="0" +     width="200" /> +  </radio_group>    <button     follows="left|top"     height="20"     label="Start"     layout="topleft" -   left_delta="0" +   left="10"     name="start_btn" -   top_delta="30" +   top_delta="20"     width="70">      <button.commit_callback  		function="TexFetchDebugger.Start" /> @@ -261,7 +324,7 @@     layout="topleft"     left="10"     name="cacheread_btn" -   top_delta="30" +   top_delta="20"     width="80">      <button.commit_callback  		function="TexFetchDebugger.CacheRead" /> @@ -321,7 +384,7 @@     layout="topleft"     left="10"     name="refetchviscache_btn" -   top_delta="30" +   top_delta="20"     width="120">      <button.commit_callback  		function="TexFetchDebugger.RefetchVisCache" /> @@ -329,6 +392,18 @@    <button     follows="left|top"     height="20" +   label="Refetch All Cache" +   layout="topleft" +   left_pad="7" +   name="refetchallcache_btn" +   top_delta="0" +   width="120"> +    <button.commit_callback +		function="TexFetchDebugger.RefetchAllCache" /> +  </button> +  <button +   follows="left|top" +   height="20"     label="Refetch Vis HTTP"     layout="topleft"     left_pad="7" @@ -338,4 +413,16 @@      <button.commit_callback  		function="TexFetchDebugger.RefetchVisHTTP" />    </button> +  <button +   follows="left|top" +   height="20" +   label="Refetch All HTTP" +   layout="topleft" +   left_pad="7" +   name="refetchallhttp_btn" +   top_delta="0" +   width="120"> +    <button.commit_callback +		function="TexFetchDebugger.RefetchAllHTTP" /> +  </button>  </floater> diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index f8923b9868..f8923b9868 100644..100755 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp  | 
