diff options
Diffstat (limited to 'indra')
| -rwxr-xr-x | indra/llrender/llimagegl.cpp | 17 | ||||
| -rwxr-xr-x | indra/llrender/llimagegl.h | 1 | ||||
| -rwxr-xr-x | indra/newview/CMakeLists.txt | 2 | ||||
| -rwxr-xr-x | indra/newview/app_settings/settings.xml | 24 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llfloatertexturefetchdebugger.cpp | 390 | ||||
| -rw-r--r-- | indra/newview/llfloatertexturefetchdebugger.h | 71 | ||||
| -rwxr-xr-x | indra/newview/lltexturefetch.cpp | 691 | ||||
| -rw-r--r-- | indra/newview/lltexturefetch.h | 193 | ||||
| -rw-r--r-- | indra/newview/llviewerfloaterreg.cpp | 6 | ||||
| -rw-r--r-- | indra/newview/llviewermenu.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.cpp | 46 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.h | 4 | ||||
| -rw-r--r-- | indra/newview/llviewertexturelist.h | 6 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml | 341 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_viewer.xml | 17 | 
16 files changed, 1810 insertions, 24 deletions
| diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ab744fb7ff..2c13fead97 100755 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1464,13 +1464,24 @@ void LLImageGL::destroyGLTexture()  		}  		LLImageGL::deleteTextures(1, &mTexName);			 -		mTexName = 0;  		mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. +		mTexName = 0;		  		mGLTextureCreated = FALSE ; -	} +	}	  } - +//force to invalidate the gl texture, most likely a sculpty texture +void LLImageGL::forceToInvalidateGLTexture() +{ +	if (mTexName != 0) +	{ +		destroyGLTexture(); +	} +	else +	{ +		mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. +	} +}  //---------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 2060be914b..e515d6b324 100755 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -114,6 +114,7 @@ public:  	// Read back a raw image for this discard level, if it exists  	BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const;  	void destroyGLTexture(); +	void forceToInvalidateGLTexture();  	void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);  	void setComponents(S8 ncomponents) { mComponents = ncomponents; } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index f85b943c70..6db97390aa 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -236,6 +236,7 @@ set(viewer_SOURCE_FILES      llfloatertelehub.cpp      llfloatertestinspectors.cpp      llfloatertestlistview.cpp +	llfloatertexturefetchdebugger.cpp      llfloatertools.cpp      llfloatertopobjects.cpp      llfloatertos.cpp @@ -792,6 +793,7 @@ set(viewer_HEADER_FILES      llfloatertelehub.h      llfloatertestinspectors.h      llfloatertestlistview.h +	llfloatertexturefetchdebugger.h      llfloatertools.h      llfloatertopobjects.h      llfloatertos.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index eb3fcc30ee..c2f3d244f3 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10631,6 +10631,17 @@        <key>Value</key>        <real>20.0</real>      </map> +    <key>TexelPixelRatio</key> +    <map> +      <key>Comment</key> +      <string>texel pixel ratio = texel / pixel</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>F32</string> +      <key>Value</key> +      <real>1.0</real> +    </map>      <key>TextureCameraMotionThreshold</key>      <map>        <key>Comment</key> @@ -10640,7 +10651,7 @@        <key>Type</key>        <string>F32</string>        <key>Value</key> -      <integer>0.2</integer> +      <real>0.2</real>      </map>      <key>TextureCameraMotionBoost</key>      <map> @@ -10686,6 +10697,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>TextureFetchDebuggerEnabled</key> +    <map> +      <key>Comment</key> +      <string>Enable the texture fetching debugger if set</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>TextureLoadFullRes</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a627f3868b..178b96e42e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -93,6 +93,7 @@  #include "llsecondlifeurls.h"  #include "llupdaterservice.h"  #include "llcallfloater.h" +#include "llfloatertexturefetchdebugger.h"  // Linden library includes  #include "llavatarnamecache.h" @@ -1218,7 +1219,7 @@ bool LLAppViewer::mainLoop()  			if(mem_leak_instance)  			{  				mem_leak_instance->idle() ;				 -			}			 +			}							              // canonical per-frame event              mainloop.post(newFrame); @@ -1403,6 +1404,17 @@ bool LLAppViewer::mainLoop()  					LLLFSThread::sLocal->pause();   				}									 +				//texture fetching debugger +				if(LLTextureFetchDebugger::isEnabled()) +				{ +					LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = +						LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); +					if(tex_fetch_debugger_instance) +					{ +						tex_fetch_debugger_instance->idle() ;				 +					} +				} +  				if ((LLStartUp::getStartupState() >= STATE_CLEANUP) &&  					(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD))  				{ diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp new file mode 100644 index 0000000000..2b34b72055 --- /dev/null +++ b/indra/newview/llfloatertexturefetchdebugger.cpp @@ -0,0 +1,390 @@ +/**  + * @file llfloatertexturefetchdebugger.cpp + * @brief LLFloaterTextureFetchDebugger class definition + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatertexturefetchdebugger.h" + +#include "lluictrlfactory.h" +#include "llbutton.h" +#include "llspinctrl.h" +#include "llresmgr.h" + +#include "llmath.h" +#include "llviewerwindow.h" +#include "llappviewer.h" +#include "lltexturefetch.h" +#include "llviewercontrol.h" + +LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key) +	: LLFloater(key), +	mDebugger(NULL) +{ +	setTitle("Texture Fetching Debugger Floater"); +	 +	mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio",	boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this)); + +	mCommitCallbackRegistrar.add("TexFetchDebugger.Start",	boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.Clear",	boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.Close",	boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this)); + +	mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead",	boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite",	boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad",	boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.Decode",	boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture",	boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this)); + +	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this)); +	mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP",	boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this)); +} +//---------------------------------------------- + +BOOL LLFloaterTextureFetchDebugger::postBuild(void)  +{	 +	mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger(); + +	//set states for buttons +	mButtonStateMap["start_btn"] = true; +	mButtonStateMap["close_btn"] = true; +	mButtonStateMap["clear_btn"] = true; +	mButtonStateMap["cacheread_btn"] = false; +	mButtonStateMap["cachewrite_btn"] = false; +	mButtonStateMap["http_btn"] = false; +	mButtonStateMap["decode_btn"] = false; +	mButtonStateMap["gl_btn"] = false; + +	mButtonStateMap["refetchviscache_btn"] = true; +	mButtonStateMap["refetchvishttp_btn"] = true; + +	updateButtons(); + +	getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio")); + +	return TRUE ; +} + +LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger() +{ +	//stop everything +	mDebugger->stopDebug(); +} + +void LLFloaterTextureFetchDebugger::updateButtons() +{ +	for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter) +	{ +		if(iter->second) +		{ +			childEnable(iter->first.c_str()); +		} +		else +		{ +			childDisable(iter->first.c_str()); +		} +	} +} + +void LLFloaterTextureFetchDebugger::disableButtons() +{ +	childDisable("start_btn"); +	childDisable("clear_btn"); +	childDisable("cacheread_btn"); +	childDisable("cachewrite_btn"); +	childDisable("http_btn"); +	childDisable("decode_btn"); +	childDisable("gl_btn"); +	childDisable("refetchviscache_btn"); +	childDisable("refetchvishttp_btn"); +} + +void LLFloaterTextureFetchDebugger::idle() +{	 +	LLTextureFetchDebugger::e_debug_state state = mDebugger->getState(); +	 +	if(mDebugger->update()) +	{ +		switch(state) +		{ +		case LLTextureFetchDebugger::IDLE: +			break; +		case LLTextureFetchDebugger::READ_CACHE: +			mButtonStateMap["cachewrite_btn"] = true; +			mButtonStateMap["decode_btn"] = true; +			updateButtons(); +			break; +		case LLTextureFetchDebugger::WRITE_CACHE: +			updateButtons(); +			break; +		case LLTextureFetchDebugger::DECODING: +			mButtonStateMap["gl_btn"] = true; +			updateButtons(); +			break; +		case LLTextureFetchDebugger::HTTP_FETCHING: +			mButtonStateMap["cacheread_btn"] = true; +			mButtonStateMap["cachewrite_btn"] = true; +			mButtonStateMap["decode_btn"] = true; +			updateButtons(); +			break; +		case LLTextureFetchDebugger::GL_TEX: +			updateButtons(); +			break; +		case LLTextureFetchDebugger::REFETCH_VIS_CACHE: +			updateButtons(); +		case LLTextureFetchDebugger::REFETCH_VIS_HTTP: +			updateButtons(); +			break; +		default: +			break; +		} +	} +} + +//---------------------- +void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio() +{ +	gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal()); +} + +void LLFloaterTextureFetchDebugger::onClickStart() +{ +	disableButtons(); + +	mDebugger->startDebug(); + +	mButtonStateMap["start_btn"] = false; +	mButtonStateMap["cacheread_btn"] = true; +	mButtonStateMap["http_btn"] = true; +	updateButtons(); +} + +void LLFloaterTextureFetchDebugger::onClickClose() +{ +	setVisible(FALSE); +	 +	//stop everything +	mDebugger->stopDebug(); +} + +void LLFloaterTextureFetchDebugger::onClickClear() +{ +	mButtonStateMap["start_btn"] = true; +	mButtonStateMap["close_btn"] = true; +	mButtonStateMap["clear_btn"] = true; +	mButtonStateMap["cacheread_btn"] = false; +	mButtonStateMap["cachewrite_btn"] = false; +	mButtonStateMap["http_btn"] = false; +	mButtonStateMap["decode_btn"] = false; +	mButtonStateMap["gl_btn"] = false; +	mButtonStateMap["refetchviscache_btn"] = true; +	mButtonStateMap["refetchvishttp_btn"] = true; +	updateButtons(); + +	//stop everything +	mDebugger->stopDebug(); +	mDebugger->clearHistory(); +} + +void LLFloaterTextureFetchDebugger::onClickCacheRead() +{ +	disableButtons(); + +	mDebugger->debugCacheRead(); +} + +void LLFloaterTextureFetchDebugger::onClickCacheWrite() +{ +	disableButtons(); + +	mDebugger->debugCacheWrite(); +} + +void LLFloaterTextureFetchDebugger::onClickHTTPLoad() +{ +	disableButtons(); + +	mDebugger->debugHTTP(); +} + +void LLFloaterTextureFetchDebugger::onClickDecode() +{ +	disableButtons(); + +	mDebugger->debugDecoder(); +} + +void LLFloaterTextureFetchDebugger::onClickGLTexture() +{ +	disableButtons(); + +	mDebugger->debugGLTextureCreation(); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchVisCache() +{ +	disableButtons(); + +	mDebugger->debugRefetchVisibleFromCache(); +} + +void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP() +{ +	disableButtons(); + +	mDebugger->debugRefetchVisibleFromHTTP(); +} + +void LLFloaterTextureFetchDebugger::draw() +{ +	//total number of fetched textures +	{ +		getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures())); +	} + +	//total number of fetching requests +	{ +		getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests())); +	} + +	//total number of cache hits +	{ +		getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits())); +	} + +	//total number of visible textures +	{ +		getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures())); +	} + +	//total number of visible texture fetching requests +	{ +		getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests())); +	} + +	//total number of fetched data +	{ +		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10));		 +		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10)); +		getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f)); +	} + +	//total number of visible fetched data +	{		 +		getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10));		 +		getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10)); +	} + +	//total number of rendered fetched data +	{ +		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10));		 +		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10)); +		getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f)); +	} + +	//total time on cache readings +	if(mDebugger->getCacheReadTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime())); +	} + +	//total time on cache writings +	if(mDebugger->getCacheWriteTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime())); +	} + +	//total time on decoding +	if(mDebugger->getDecodeTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime())); +	} + +	//total time on gl texture creation +	if(mDebugger->getGLCreationTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime())); +	} + +	//total time on HTTP fetching +	if(mDebugger->getHTTPTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----")); +	} +	else +	{ +		getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime())); +	} + +	//total time on entire fetching +	{ +		getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime())); +	} + +	//total time on refetching visible textures from cache +	if(mDebugger->getRefetchVisCacheTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----")); +	} +	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)); +	} + +	//total time on refetching visible textures from http +	if(mDebugger->getRefetchVisHTTPTime() < 0.f) +	{ +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----")); +		getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----")); +	} +	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)); +	} + +	LLFloater::draw(); +} diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h new file mode 100644 index 0000000000..33012c6a3d --- /dev/null +++ b/indra/newview/llfloatertexturefetchdebugger.h @@ -0,0 +1,71 @@ +/**  + * @file llfloatertexturefetchdebugger.h + * @brief texture fetching debugger window, debug use only + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H +#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H + +#include "llfloater.h" +class LLTextureFetchDebugger; + +class LLFloaterTextureFetchDebugger : public LLFloater +{ +	friend class LLFloaterReg; +public: +	/// initialize all the callbacks for the menu + +	virtual BOOL postBuild() ; +	virtual void draw() ; +	 +	void onChangeTexelPixelRatio(); +	 +	void onClickStart(); +	void onClickClear(); +	void onClickClose(); + +	void onClickCacheRead(); +	void onClickCacheWrite(); +	void onClickHTTPLoad(); +	void onClickDecode(); +	void onClickGLTexture(); + +	void onClickRefetchVisCache(); +	void onClickRefetchVisHTTP(); +public: +	void idle() ; + +private:	 +	LLFloaterTextureFetchDebugger(const LLSD& key); +	virtual ~LLFloaterTextureFetchDebugger(); + +	void updateButtons(); +	void disableButtons(); + +private:	 +	LLTextureFetchDebugger* mDebugger; +	std::map<std::string, bool> mButtonStateMap; +}; + +#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2e1b409fa7..efb6ed6079 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -54,7 +54,9 @@  #include "llworld.h"  #include "llsdutil.h"  #include "llstartup.h" +#include "llviewerstats.h" +bool LLTextureFetchDebugger::sDebuggerEnabled = false ;  LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128);  LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128); @@ -63,6 +65,7 @@ class LLTextureFetchWorker : public LLWorkerClass  {  	friend class LLTextureFetch;  	friend class HTTPGetResponder; +	friend class LLTextureFetchDebugger;  private:  	class CacheReadResponder : public LLTextureCache::ReadResponder @@ -265,6 +268,7 @@ private:  	BOOL mNeedsAux;  	BOOL mHaveAllData;  	BOOL mInLocalCache; +	BOOL mInCache;  	bool mCanUseHTTP ;  	bool mCanUseNET ; //can get from asset server.  	S32 mHTTPFailCount; @@ -677,6 +681,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mNeedsAux(FALSE),  	  mHaveAllData(FALSE),  	  mInLocalCache(FALSE), +	  mInCache(FALSE),  	  mCanUseHTTP(true),  	  mHTTPFailCount(0),  	  mRetryAttempt(0), @@ -906,6 +911,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		mCacheReadHandle = LLTextureCache::nullHandle();  		mCacheWriteHandle = LLTextureCache::nullHandle();  		mState = LOAD_FROM_TEXTURE_CACHE; +		mInCache = FALSE;  		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; @@ -994,6 +1000,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  			llassert_always(mFormattedImage->getDataSize() > 0);  			mLoadedDiscard = mDesiredDiscard;  			mState = DECODE_IMAGE; +			mInCache = TRUE;  			mWriteToCacheState = NOT_WRITE ;  			LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()  								 << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) @@ -1418,6 +1425,11 @@ bool LLTextureFetchWorker::doWork(S32 param)  	{  		if (mDecoded)  		{ +			if(mFetcher->getFetchDebugger() && !mInLocalCache) +			{ +				mFetcher->getFetchDebugger()->addHistoryEntry(this); +			} +  			if (mDecodedDiscard < 0)  			{  				LL_DEBUGS("Texture") << mID << ": Failed to Decode." << LL_ENDL; @@ -1847,11 +1859,18 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image  	  mHTTPTextureBits(0),  	  mTotalHTTPRequests(0),  	  mCurlGetRequest(NULL), -	  mQAMode(qa_mode) +	  mQAMode(qa_mode), +	  mFetchDebugger(NULL)  {  	mCurlPOSTRequestCount = 0;  	mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");  	mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold")); + +	LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); +	if(LLTextureFetchDebugger::isEnabled()) +	{ +		mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ; +	}  }  LLTextureFetch::~LLTextureFetch() @@ -1866,11 +1885,17 @@ LLTextureFetch::~LLTextureFetch()  	}  	// ~LLQueuedThread() called here + +	delete mFetchDebugger;  }  bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,  								   S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)  { +	if(mFetcherLocked) +	{ +		return false; +	}  	if (mDebugPause)  	{  		return false; @@ -2292,6 +2317,11 @@ void LLTextureFetch::startThread()  {  	// Construct mCurlGetRequest from Worker Thread  	mCurlGetRequest = new LLCurlRequest(); +	 +	if(mFetchDebugger) +	{ +		mFetchDebugger->setCurlGetRequest(mCurlGetRequest); +	}  }  // WORKER THREAD @@ -2300,6 +2330,10 @@ void LLTextureFetch::endThread()  	// Destroy mCurlGetRequest from Worker Thread  	delete mCurlGetRequest;  	mCurlGetRequest = NULL; +	if(mFetchDebugger) +	{ +		mFetchDebugger->setCurlGetRequest(NULL); +	}  }  // WORKER THREAD @@ -2837,7 +2871,6 @@ void LLTextureFetch::cmdDoWork()  	}  } -  //////////////////////////////////////////////////////////////////////////////  // Private (anonymous) class methods implementing the command scheme. @@ -3041,5 +3074,659 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics)  } // end of anonymous namespace +/////////////////////////////////////////////////////////////////////////////////////////// +//Start LLTextureFetchDebugger +/////////////////////////////////////////////////////////////////////////////////////////// +//--------------------- +class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder +{ +public: +	LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image) +		: mDebugger(debugger), mID(id) +	{ +		setImage(image); +	} +	virtual void completed(bool success) +	{ +		mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal); +	} +private: +	LLTextureFetchDebugger* mDebugger; +	S32 mID; +}; + +class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder +{ +public: +	LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id) +		: mDebugger(debugger), mID(id) +	{ +	} +	virtual void completed(bool success) +	{ +		mDebugger->callbackCacheWrite(mID, success); +	} +private: +	LLTextureFetchDebugger* mDebugger; +	S32 mID; +}; + +class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder +{ +public: +	LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id) +		: mDebugger(debugger), mID(id) +	{ +	} +	virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux) +	{ +		mDebugger->callbackDecoded(mID, success, raw, aux); +	} +private: +	LLTextureFetchDebugger* mDebugger; +	S32 mID; +}; + +class LLDebuggerHTTPResponder : public LLCurl::Responder +{ +public: +	LLDebuggerHTTPResponder(LLTextureFetchDebugger* debugger, S32 index) +	: mDebugger(debugger), mIndex(index) +	{ +	} +	virtual void completedRaw(U32 status, const std::string& reason, +							  const LLChannelDescriptors& channels, +							  const LLIOPipe::buffer_ptr_t& buffer) +	{ +		bool success = false; +		bool partial = false; +		if (HTTP_OK <= status &&  status < HTTP_MULTIPLE_CHOICES) +		{ +			success = true; +			if (HTTP_PARTIAL_CONTENT == status) // partial information +			{ +				partial = true; +			} +		} +		if (!success) +		{ +			llinfos << "Fetch Debugger : CURL GET FAILED, index = " << mIndex << ", status:" << status << " reason:" << reason << llendl; +		} +		mDebugger->callbackHTTP(mIndex, channels, buffer, partial, success); +	} +	virtual bool followRedir() +	{ +		return true; +	} +private: +	LLTextureFetchDebugger* mDebugger; +	S32 mIndex; +}; + +LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) : +	mFetcher(fetcher), +	mTextureCache(cache), +	mImageDecodeThread(imagedecodethread), +	mCurlGetRequest(NULL) +{ +	init(); +} +	 +LLTextureFetchDebugger::~LLTextureFetchDebugger() +{ +	mFetchingHistory.clear(); +	stopDebug(); +} + +void LLTextureFetchDebugger::init() +{ +	mState = IDLE; +	 +	mCacheReadTime = -1.f; +	mCacheWriteTime = -1.f; +	mDecodingTime = -1.f; +	mHTTPTime = -1.f; +	mGLCreationTime = -1.f; +	mTotalFetchingTime = 0.f; +	mRefetchVisCacheTime = -1.f; +	mRefetchVisHTTPTime = -1.f; + +	mNumFetchedTextures = 0; +	mNumCacheHits = 0; +	mNumVisibleFetchedTextures = 0; +	mNumVisibleFetchingRequests = 0; +	mFetchedData = 0; +	mDecodedData = 0; +	mVisibleFetchedData = 0; +	mVisibleDecodedData = 0; +	mRenderedData = 0; +	mRenderedDecodedData = 0; +	mFetchedPixels = 0; +	mRenderedPixels = 0; +	mRefetchedData = 0; +	mRefetchedPixels = 0; + +	mFreezeHistory = FALSE; +} + +void LLTextureFetchDebugger::startDebug() +{ +	//lock the fetcher +	mFetcher->lockFetcher(true); +	mFreezeHistory = TRUE; + +	//clear the current fetching queue +	gTextureList.clearFetchingRequests(); + +	//wait for all works to be done +	while(1) +	{ +		S32 pending = 0; +		pending += LLAppViewer::getTextureCache()->update(1);  +		pending += LLAppViewer::getImageDecodeThread()->update(1);  +		pending += LLAppViewer::getTextureFetch()->update(1);  +		if(!pending) +		{ +			break; +		} +	} + +	//collect statistics +	mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +	 +	std::set<LLUUID> fetched_textures; +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size; i++) +	{ +		bool in_list = true; +		if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end()) +		{ +			fetched_textures.insert(mFetchingHistory[i].mID); +			in_list = false; +		} +		 +		LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(mFetchingHistory[i].mID); +		if(tex && tex->isJustBound()) //visible +		{ +			if(!in_list) +			{ +				mNumVisibleFetchedTextures++; +			} +			mNumVisibleFetchingRequests++; +	 +			mVisibleFetchedData += mFetchingHistory[i].mFetchedSize; +			mVisibleDecodedData += mFetchingHistory[i].mDecodedSize; +	 +			if(tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel) +			{ +				mRenderedData += mFetchingHistory[i].mFetchedSize; +				mRenderedDecodedData += mFetchingHistory[i].mDecodedSize; +				mRenderedPixels += tex->getWidth() * tex->getHeight(); +			} +		} +	} + +	mNumFetchedTextures = fetched_textures.size(); +} + +void LLTextureFetchDebugger::stopDebug() +{ +	//clear the current debug work +	S32 size = mFetchingHistory.size(); +	switch(mState) +	{ +	case READ_CACHE:		 +		for(S32 i = 0 ; i < size; i++) +		{ +			if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle()) +			{ +				mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true); +			} +		}	 +		break; +	case WRITE_CACHE: +		for(S32 i = 0 ; i < size; i++) +		{ +			if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle()) +			{ +				mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true); +			} +		} +		break; +	case DECODING: +		break; +	case HTTP_FETCHING: +		break; +	case GL_TEX: +		break; +	default: +		break; +	} + +	while(1) +	{ +		if(update()) +		{ +			break; +		} +	} + +	//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(); +} + +void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker) +{ +	if(mFreezeHistory) +	{ +		mRefetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight(); +		mRefetchedData += worker->mFormattedImage->getDataSize(); +		return; +	} + +	if(worker->mInCache) +	{ +		mNumCacheHits++; +	} +	mFetchedData += worker->mFormattedImage->getDataSize(); +	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())); +} + +void LLTextureFetchDebugger::lockCache() +{ +} +	 +void LLTextureFetchDebugger::unlockCache() +{ +} +	 +void LLTextureFetchDebugger::debugCacheRead() +{ +	lockCache(); +	llassert_always(mState == IDLE); +	mTimer.reset(); +	mState = READ_CACHE; + +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{		 +		mFetchingHistory[i].mFormattedImage = NULL; +		mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize,  +			new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage)); +	} +} +	 +void LLTextureFetchDebugger::clearCache() +{ +	S32 size = mFetchingHistory.size(); +	{ +		std::set<LLUUID> deleted_list; +		for(S32 i = 0 ; i < size ; i++) +		{ +			if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end()) +			{ +				deleted_list.insert(mFetchingHistory[i].mID); +				mTextureCache->removeFromCache(mFetchingHistory[i].mID); +			} +		} +	} +} + +void LLTextureFetchDebugger::debugCacheWrite() +{ +	//remove from cache +	clearCache(); + +	lockCache(); +	llassert_always(mState == IDLE); +	mTimer.reset(); +	mState = WRITE_CACHE; + +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{		 +		if(mFetchingHistory[i].mFormattedImage.notNull()) +		{ +			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));					 +		} +	} +} + +void LLTextureFetchDebugger::lockDecoder() +{ +} +	 +void LLTextureFetchDebugger::unlockDecoder() +{ +} + +void LLTextureFetchDebugger::debugDecoder() +{ +	lockDecoder(); +	llassert_always(mState == IDLE); +	mTimer.reset(); +	mState = DECODING; + +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{		 +		if(mFetchingHistory[i].mFormattedImage.isNull()) +		{ +			continue; +		} + +		mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL,  +			mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux, +			new LLDebuggerDecodeResponder(this, i)); +	} +} + +void LLTextureFetchDebugger::debugHTTP() +{ +	llassert_always(mState == IDLE); + +	LLViewerRegion* region = gAgent.getRegion(); +	if (!region) +	{ +		llinfos << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << llendl; +		return; +	} +	 +	mHTTPUrl = region->getHttpUrl(); +	if (mHTTPUrl.empty()) +	{ +		llinfos << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << llendl; +		return; +	} +	 +	mTimer.reset(); +	mState = HTTP_FETCHING; +	 +	S32 size = mFetchingHistory.size(); +	for (S32 i = 0 ; i < size ; i++) +	{ +		mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE; +		mFetchingHistory[i].mCurlReceivedSize = 0; +		mFetchingHistory[i].mHTTPFailCount = 0; +	} +	mNbCurlRequests = 0; +	mNbCurlCompleted = 0; +	 +	fillCurlQueue(); +} + +S32 LLTextureFetchDebugger::fillCurlQueue() +{ +	if (mNbCurlRequests == 24) +		return mNbCurlRequests; +	 +	S32 size = mFetchingHistory.size(); +	for (S32 i = 0 ; i < size ; i++) +	{		 +		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. +		requestedSize = llmax(0,requestedSize); +		// We request the whole file if the size was set to an absurdly high value (meaning all file) +		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  +		{ +			break; +		} +	} +	//llinfos << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << llendl; +	return mNbCurlRequests; +} + +void LLTextureFetchDebugger::debugGLTextureCreation() +{ +	llassert_always(mState == IDLE); +	mState = GL_TEX; +	std::vector<LLViewerFetchedTexture*> tex_list; + +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{ +		if(mFetchingHistory[i].mRawImage.notNull()) +		{ +			LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; +			if(tex && !tex->isForSculptOnly()) +			{ +				tex->destroyGLTexture() ; +				tex_list.push_back(tex); +			} +		} +	} + +	mTimer.reset(); +	S32 j = 0 ; +	S32 size1 = tex_list.size(); +	for(S32 i = 0 ; i < size && j < size1; i++) +	{ +		if(mFetchingHistory[i].mRawImage.notNull()) +		{ +			if(mFetchingHistory[i].mID == tex_list[j]->getID()) +			{ +				tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel()); +				j++; +			} +		} +	} + +	mGLCreationTime = mTimer.getElapsedTimeF32() ; +	return; +} + +//clear fetching results of all textures. +void LLTextureFetchDebugger::clearTextures() +{ +	S32 size = mFetchingHistory.size(); +	for(S32 i = 0 ; i < size ; i++) +	{ +		LLViewerFetchedTexture* tex = gTextureList.findImage(mFetchingHistory[i].mID) ; +		if(tex) +		{ +			tex->clearFetchedResults() ; +		} +	} +} + +void LLTextureFetchDebugger::debugRefetchVisibleFromCache() +{ +	llassert_always(mState == IDLE); +	mState = REFETCH_VIS_CACHE; + +	clearTextures(); + +	mTimer.reset(); +	mFetcher->lockFetcher(false); +} + +void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP() +{ +	llassert_always(mState == IDLE); +	mState = REFETCH_VIS_HTTP; + +	clearCache(); +	clearTextures(); + +	mTimer.reset(); +	mFetcher->lockFetcher(false); +} + +bool LLTextureFetchDebugger::update() +{ +	switch(mState) +	{ +	case READ_CACHE: +		if(!mTextureCache->update(1)) +		{ +			mCacheReadTime = mTimer.getElapsedTimeF32() ; +			mState = IDLE; +			unlockCache(); +		} +		break; +	case WRITE_CACHE: +		if(!mTextureCache->update(1)) +		{ +			mCacheWriteTime = mTimer.getElapsedTimeF32() ; +			mState = IDLE; +			unlockCache(); +		} +		break; +	case DECODING: +		if(!mImageDecodeThread->update(1)) +		{ +			mDecodingTime =  mTimer.getElapsedTimeF32() ; +			mState = IDLE; +			unlockDecoder(); +		} +		break; +	case HTTP_FETCHING: +		mCurlGetRequest->process(); +		LLCurl::getCurlThread()->update(1); +		if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size()) +		{ +			mHTTPTime =  mTimer.getElapsedTimeF32() ; +			mState = IDLE; +		} +		break; +	case GL_TEX: +		mState = IDLE; +		break; +	case REFETCH_VIS_CACHE: +		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +		{ +			mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +			mState = IDLE; +			mFetcher->lockFetcher(true); +		} +		break; +	case REFETCH_VIS_HTTP: +		if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) +		{ +			mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; +			mState = IDLE; +			mFetcher->lockFetcher(true); +		} +		break; +	default: +		mState = IDLE; +		break; +	} + +	return mState == IDLE; +} + +void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image, +						   S32 imagesize, BOOL islocal) +{ +	if (success) +	{ +		mFetchingHistory[id].mFormattedImage = image; +	} +	mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false); +	mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); +} + +void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success) +{ +	mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle); +	mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle(); +} + +void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux) +{ +	if (success) +	{ +		llassert_always(raw); +		mFetchingHistory[id].mRawImage = raw; +	} +} + +void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& channels, +										  const LLIOPipe::buffer_ptr_t& buffer,  +										  bool partial, bool success) +{ +	mNbCurlRequests--; +	if (success) +	{ +		mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; +		mNbCurlCompleted++; + +		S32 data_size = buffer->countAfter(channels.in(), NULL); +		mFetchingHistory[id].mCurlReceivedSize += data_size; +		//llinfos << "Fetch Debugger : got results for " << id << ", data_size = " << data_size << ", received = " << mFetchingHistory[id].mCurlReceivedSize << ", requested = " << mFetchingHistory[id].mRequestedSize << ", partial = " << partial << llendl; +		if ((mFetchingHistory[id].mCurlReceivedSize >= mFetchingHistory[id].mRequestedSize) || !partial || (mFetchingHistory[id].mRequestedSize == 600)) +		{ +			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()); +			{ +				// For now, create formatted image based on extension +				std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[id].mID.asString().c_str(); +				std::string extension = gDirUtilp->getExtension(texture_url); +				mFetchingHistory[id].mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension)); +				if (mFetchingHistory[id].mFormattedImage.isNull()) +				{ +					mFetchingHistory[id].mFormattedImage = new LLImageJ2C; // default +				} +			} +						 +			mFetchingHistory[id].mFormattedImage->setData(d_buffer, data_size);	 +		} +	} +	else //failed +	{ +		mFetchingHistory[id].mHTTPFailCount++; +		if(mFetchingHistory[id].mHTTPFailCount < 5) +		{ +			// Fetch will have to be redone +			mFetchingHistory[id].mCurlState = FetchEntry::CURL_NOT_DONE; +		} +		else //skip +		{ +			mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE; +			mNbCurlCompleted++; +		} +	} +} + + +//--------------------- +/////////////////////////////////////////////////////////////////////////////////////////// +//End LLTextureFetchDebugger +/////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 710dd67e99..107e1623b0 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -34,14 +34,17 @@  #include "llcurl.h"  #include "lltextureinfo.h"  #include "llapr.h" +#include "llimageworker.h" +//#include "lltexturecache.h"  class LLViewerTexture;  class LLTextureFetchWorker;  class HTTPGetResponder; -class LLTextureCache;  class LLImageDecodeThread;  class LLHost;  class LLViewerAssetStats; +class LLTextureFetchDebugger; +class LLTextureCache;  // Interface class  class LLTextureFetch : public LLWorkerThread @@ -212,7 +215,195 @@ public:  	// attempt to log metrics follows a break in the metrics stream  	// reporting due to either startup or a problem POSTing data.  	static volatile bool svMetricsDataBreak; + +private: +	//debug use +	LLTextureFetchDebugger* mFetchDebugger; +	bool mFetcherLocked; + +public: +	//debug use +	LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;} +	void lockFetcher(bool lock) { mFetcherLocked = lock;}  }; +//debug use +class LLTextureFetchDebugger +{ +	friend class LLTextureFetch; +public: +	LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ; +	~LLTextureFetchDebugger(); + +public: +	enum e_debug_state +	{ +		IDLE = 0, +		READ_CACHE, +		WRITE_CACHE, +		DECODING, +		HTTP_FETCHING, +		GL_TEX, +		REFETCH_VIS_CACHE, +		REFETCH_VIS_HTTP, +		REFETCH_ALL_CACHE, +		REFETCH_ALL_HTTP, +		INVALID +	}; + +private:	 +	struct FetchEntry +	{ +		enum e_curl_state +		{ +			CURL_NOT_DONE = 0, +			CURL_IN_PROGRESS, +			CURL_DONE +		}; +		LLUUID mID; +		S32 mRequestedSize; +		S32 mDecodedLevel; +		S32 mFetchedSize; +		S32 mDecodedSize; +		BOOL mNeedsAux; +		U32 mCacheHandle; +		LLPointer<LLImageFormatted> mFormattedImage; +		LLPointer<LLImageRaw> mRawImage; +		e_curl_state mCurlState; +		S32 mCurlReceivedSize; +		S32 mHTTPFailCount; + +		FetchEntry() : +			mDecodedLevel(-1), +			mFetchedSize(0), +			mDecodedSize(0) +			{} +		FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) : +			mID(id), +			mRequestedSize(r_size), +			mDecodedLevel(level), +			mFetchedSize(f_size), +			mDecodedSize(d_size), +			mNeedsAux(false), +			mHTTPFailCount(0) +			{} +	}; +	std::vector<FetchEntry> mFetchingHistory; +	 +	e_debug_state mState; +	 +	F32 mCacheReadTime; +	F32 mCacheWriteTime; +	F32 mDecodingTime; +	F32 mHTTPTime; +	F32 mGLCreationTime; + +	F32 mTotalFetchingTime; +	F32 mRefetchVisCacheTime; +	F32 mRefetchVisHTTPTime; + +	LLTimer mTimer; +	 +	LLTextureFetch* mFetcher; +	LLTextureCache* mTextureCache; +	LLImageDecodeThread* mImageDecodeThread; +	LLCurlRequest* mCurlGetRequest; +	 +	S32 mNumFetchedTextures; +	S32 mNumCacheHits; +	S32 mNumVisibleFetchedTextures; +	S32 mNumVisibleFetchingRequests; +	U32 mFetchedData; +	U32 mDecodedData; +	U32 mVisibleFetchedData; +	U32 mVisibleDecodedData; +	U32 mRenderedData; +	U32 mRenderedDecodedData; +	U32 mFetchedPixels; +	U32 mRenderedPixels; +	U32 mRefetchedData; +	U32 mRefetchedPixels; + +	BOOL mFreezeHistory; + +	std::string mHTTPUrl; +	S32 mNbCurlRequests; +	S32 mNbCurlCompleted; + +public: +	bool update(); //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 callbackCacheRead(S32 id, bool success, LLImageFormatted* image, +						   S32 imagesize, BOOL islocal); +	void callbackCacheWrite(S32 id, bool success); +	void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux); +	void callbackHTTP(S32 id, const LLChannelDescriptors& channels, +					  const LLIOPipe::buffer_ptr_t& buffer,  +					  bool partial, bool success); +	 + +	e_debug_state getState()             {return mState;} +	S32  getNumFetchedTextures()         {return mNumFetchedTextures;} +	S32  getNumFetchingRequests()        {return mFetchingHistory.size();} +	S32  getNumCacheHits()               {return mNumCacheHits;} +	S32  getNumVisibleFetchedTextures()  {return mNumVisibleFetchedTextures;} +	S32  getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;} +	U32  getFetchedData()                {return mFetchedData;} +	U32  getDecodedData()                {return mDecodedData;} +	U32  getVisibleFetchedData()         {return mVisibleFetchedData;} +	U32  getVisibleDecodedData()         {return mVisibleDecodedData;} +	U32  getRenderedData()               {return mRenderedData;} +	U32  getRenderedDecodedData()        {return mRenderedDecodedData;} +	U32  getFetchedPixels()              {return mFetchedPixels;} +	U32  getRenderedPixels()             {return mRenderedPixels;} +	U32  getRefetchedData()              {return mRefetchedData;} +	U32  getRefetchedPixels()            {return mRefetchedPixels;} + +	F32  getCacheReadTime()     {return mCacheReadTime;} +	F32  getCacheWriteTime()    {return mCacheWriteTime;} +	F32  getDecodeTime()        {return mDecodingTime;} +	F32  getGLCreationTime()    {return mGLCreationTime;} +	F32  getHTTPTime()          {return mHTTPTime;} +	F32  getTotalFetchingTime() {return mTotalFetchingTime;} +	F32  getRefetchVisCacheTime() {return mRefetchVisCacheTime;} +	F32  getRefetchVisHTTPTime()  {return mRefetchVisHTTPTime;} + +private: +	void init(); +	void clearTextures();//clear fetching results of all textures. +	void clearCache(); + +	void lockFetcher(); +	void unlockFetcher(); + +	void lockCache(); +	void unlockCache(); + +	void lockDecoder(); +	void unlockDecoder(); +	 +	S32 fillCurlQueue(); + +private: +	static bool sDebuggerEnabled; +public: +	static bool isEnabled() {return sDebuggerEnabled;} +};  #endif // LL_LLTEXTUREFETCH_H diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index bb870f7651..a7ca7a0836 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -103,6 +103,7 @@  #include "llfloatertelehub.h"  #include "llfloatertestinspectors.h"  #include "llfloatertestlistview.h" +#include "llfloatertexturefetchdebugger.h"  #include "llfloatertools.h"  #include "llfloatertos.h"  #include "llfloatertopobjects.h" @@ -227,6 +228,11 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);  	LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>); + +	if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled")) +	{ +		LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>); +	}  	LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);	  	LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);  	LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 7bdfd6df1d..2a3ba4e603 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2286,6 +2286,14 @@ class LLDevelopSetLoggingLevel : public view_listener_t  	}  }; +class LLDevelopTextureFetchDebugger : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"); +	} +}; +  //////////////////  // ADMIN MENU   //  ////////////////// @@ -8308,6 +8316,9 @@ void initialize_menus()  	// Develop >Set logging level  	view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");  	view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel"); +	 +	//Develop (Texture Fetch Debug Console) +	view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");  	// Admin >Object  	view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy"); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index d5b53f3cb1..ea329f6aac 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -98,6 +98,8 @@ S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;  BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;  F32 LLViewerTexture::sCurrentTime = 0.0f ;  BOOL LLViewerTexture::sUseTextureAtlas        = FALSE ; +F32  LLViewerTexture::sTexelPixelRatio = 1.0f; +  LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;  const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by @@ -178,7 +180,12 @@ LLViewerTexture*  LLViewerTextureManager::findTexture(const LLUUID& id)  	}  	return tex ;  } -		 + +LLViewerFetchedTexture*  LLViewerTextureManager::findFetchedTexture(const LLUUID& id)  +{ +	return gTextureList.findImage(id); +} +  LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)  {  	return LLViewerMediaTexture::findMediaTexture(media_id) ;	 @@ -385,6 +392,7 @@ void LLViewerTextureManager::cleanup()  	LLImageGL::sDefaultGLTexture = NULL ;  	LLViewerTexture::sNullImagep = NULL;  	LLViewerTexture::sBlackImagep = NULL; +	LLViewerTexture::sCheckerBoardImagep = NULL;  	LLViewerFetchedTexture::sDefaultImagep = NULL;	  	LLViewerFetchedTexture::sSmokeImagep = NULL;  	LLViewerFetchedTexture::sMissingAssetImagep = NULL; @@ -401,6 +409,7 @@ void LLViewerTextureManager::cleanup()  void LLViewerTexture::initClass()  {  	LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ; +	sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio");  }  // static @@ -722,6 +731,7 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co  		mNeedsGLTexture = TRUE ;  	} +	virtual_size *= sTexelPixelRatio;  	if(!mMaxVirtualSizeResetCounter)  	{  		//flag to reset the values because the old values are used. @@ -1297,6 +1307,7 @@ void LLViewerFetchedTexture::cleanup()  	mCachedRawDiscardLevel = -1 ;  	mCachedRawImageReady = FALSE ;  	mSavedRawImage = NULL ; +	mSavedRawDiscardLevel = -1;  }  void LLViewerFetchedTexture::setForSculpt() @@ -2139,16 +2150,29 @@ bool LLViewerFetchedTexture::updateFetch()  	return mIsFetching ? true : false;  } -void LLViewerFetchedTexture::forceToDeleteRequest()
 -{
 -	if (mHasFetcher)
 -	{
 -		LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
 -		mHasFetcher = FALSE;
 -		mIsFetching = FALSE ;
 -		resetTextureStats();
 -	}
 -}
 +void LLViewerFetchedTexture::clearFetchedResults() +{ +	llassert_always(!mNeedsCreateTexture && !mIsFetching); +	 +	cleanup(); +	destroyGLTexture(); + +	if(getDiscardLevel() >= 0) //sculpty texture, force to invalidate +	{ +		mGLTexturep->forceToInvalidateGLTexture(); +	} +} + +void LLViewerFetchedTexture::forceToDeleteRequest() +{ +	if (mHasFetcher) +	{ +		LLAppViewer::getTextureFetch()->deleteRequest(getID(), true); +		mHasFetcher = FALSE; +		mIsFetching = FALSE ; +		resetTextureStats(); +	} +}  void LLViewerFetchedTexture::setIsMissingAsset()  { diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 6ddff3e485..41bf625225 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -310,6 +310,7 @@ protected:  	} LLGLTextureState;  	LLGLTextureState  mTextureState ; +	static F32 sTexelPixelRatio;  public:  	static const U32 sCurrentFileVersion;	  	static S32 sImageCount; @@ -433,6 +434,8 @@ public:  	bool updateFetch(); +	void clearFetchedResults(); //clear all fetched results, for debug use. +  	// Override the computation of discard levels if we know the exact output  	// size of the image.  Used for UI textures to not decode, even if we have  	// more data. @@ -701,6 +704,7 @@ public:  	//"find-texture" just check if the texture exists, if yes, return it, otherwise return null.  	//  	static LLViewerTexture*           findTexture(const LLUUID& id) ; +	static LLViewerFetchedTexture*    findFetchedTexture(const LLUUID& id) ;  	static LLViewerMediaTexture*      findMediaTexture(const LLUUID& id) ;  	static LLViewerMediaTexture*      createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 64e2c1f791..7038ea24ce 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -109,6 +109,8 @@ public:  	void doPreloadImages();  	void doPrefetchImages(); +	void clearFetchingRequests(); +  	static S32 getMinVideoRamSetting();  	static S32 getMaxVideoRamSetting(bool get_recommended = false); @@ -163,9 +165,7 @@ private:  	// Request image from a specific host, used for baked avatar textures.  	// Implemented in header in case someone changes default params above. JC  	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host) -	{ return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); } -	 -	void clearFetchingRequests(); +	{ return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }	  public:  	typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;	 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 new file mode 100644 index 0000000000..44b6a63bca --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml @@ -0,0 +1,341 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 +<floater
 + legacy_header_height="18"
 + can_minimize="false"
 + height="550"
 + layout="topleft"
 + name="TexFetchDebugger"
 + help_topic="texfetchdebugger"
 + title="Texture Fetching Debugger"
 + width="540">
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left="10"
 +   name="total_num_fetched_label"
 +   top="30"
 +   width="400">
 +    1, Total number of fetched textures: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_num_fetching_requests_label"
 +   top_delta="25"
 +   width="400">
 +    2, Total number of fetching requests: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_num_cache_hits_label"
 +   top_delta="25"
 +   width="400">
 +    3, Total number of cache hits: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_num_visible_tex_label"
 +   top_delta="25"
 +   width="400">
 +    4, Total number of visible textures: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_num_visible_tex_fetch_req_label"
 +   top_delta="25"
 +   width="450">
 +    5, Total number of visible texture fetching requests: [NUM]
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_fetched_data_label"
 +   top_delta="25"
 +   width="530">
 +    6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_fetched_vis_data_label"
 +   top_delta="25"
 +   width="480">
 +    7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_fetched_rendered_data_label"
 +   top_delta="25"
 +   width="530">
 +    8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_cache_read_label"
 +   top_delta="25"
 +   width="400">
 +    9, Total time on cache readings: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_cache_write_label"
 +   top_delta="25"
 +   width="400">
 +    10, Total time on cache writings: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_decode_label"
 +   top_delta="25"
 +   width="400">
 +    11, Total time on decodings: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_gl_label"
 +   top_delta="25"
 +   width="400">
 +    12, Total time on gl texture creation: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_http_label"
 +   top_delta="25"
 +   width="400">
 +    13, Total time on HTTP fetching: [TIME] seconds
 +  </text>
 +  <text
 +   type="string"
 +   length="1"
 +   follows="left|top"
 +   height="25"
 +   layout="topleft"
 +   left_delta="0"
 +   name="total_time_fetch_label"
 +   top_delta="25"
 +   width="400">
 +    14, Total time on entire fetching: [TIME] seconds
 +  </text>
 +  <text
 +  type="string"
 +  length="1"
 +  follows="left|top"
 +  height="25"
 +  layout="topleft"
 +  left_delta="0"
 +  name="total_time_refetch_vis_cache_label"
 +  top_delta="25"
 +  width="540">
 +    15, Refetching visibles 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
 +  </text>
 +  <spinner
 +     decimal_digits="2"
 +     follows="left|top"
 +     height="20"
 +     increment="0.01"
 +     initial_value="1.0"
 +     label="17, Ratio of Texel/Pixel:"
 +     label_width="130"
 +     layout="topleft"
 +     left_delta="0"
 +     max_val="10.0"
 +     min_val="0.01"
 +     name="texel_pixel_ratio"
 +     top_delta="30"
 +     width="200">
 +    <spinner.commit_callback
 +		function="TexFetchDebugger.ChangeTexelPixelRatio" />
 +  </spinner>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Start"
 +   layout="topleft"
 +   left_delta="0"
 +   name="start_btn"
 +   top_delta="30"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.Start" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Reset"
 +   layout="topleft"
 +   left_pad="7"
 +   name="clear_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.Clear" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Close"
 +   layout="topleft"
 +   left_pad="7"
 +   name="close_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.Close" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Cache Read"
 +   layout="topleft"
 +   left="10"
 +   name="cacheread_btn"
 +   top_delta="30"
 +   width="80">
 +    <button.commit_callback
 +		function="TexFetchDebugger.CacheRead" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Cache Write"
 +   layout="topleft"
 +   left_pad="7"
 +   name="cachewrite_btn"
 +   top_delta="0"
 +   width="80">
 +    <button.commit_callback
 +		function="TexFetchDebugger.CacheWrite" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="HTTP"
 +   layout="topleft"
 +   left_pad="7"
 +   name="http_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.HTTPLoad" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Decode"
 +   layout="topleft"
 +   left_pad="7"
 +   name="decode_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.Decode" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="GL Texture"
 +   layout="topleft"
 +   left_pad="7"
 +   name="gl_btn"
 +   top_delta="0"
 +   width="70">
 +    <button.commit_callback
 +		function="TexFetchDebugger.GLTexture" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Refetch Vis Cache"
 +   layout="topleft"
 +   left="10"
 +   name="refetchviscache_btn"
 +   top_delta="30"
 +   width="120">
 +    <button.commit_callback
 +		function="TexFetchDebugger.RefetchVisCache" />
 +  </button>
 +  <button
 +   follows="left|top"
 +   height="20"
 +   label="Refetch Vis HTTP"
 +   layout="topleft"
 +   left_pad="7"
 +   name="refetchvishttp_btn"
 +   top_delta="0"
 +   width="120">
 +    <button.commit_callback
 +		function="TexFetchDebugger.RefetchVisHTTP" />
 +  </button>
 +</floater>
 diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 8b0152b1a2..5d46b0f98d 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1876,7 +1876,7 @@                  <menu_item_check.on_click                   function="Advanced.ToggleConsole"                   parameter="texture" /> -            </menu_item_check> +            </menu_item_check>                          <menu_item_check               label="Debug Console"               name="Debug Console" @@ -1931,7 +1931,20 @@                 function="Advanced.ToggleConsole"                 parameter="scene view" />              </menu_item_check> - +            <menu_item_call +              enabled="false" +              visible="false" +              label="Texture Fetch Debug Console" +              name="Texture Fetch Debug Console"> +              <menu_item_call.on_click +                function="Floater.Show" +                parameter="tex_fetch_debugger" /> +              <on_enable +                function="Develop.SetTexFetchDebugger" /> +              <on_visible +                function="Develop.SetTexFetchDebugger" /> +            </menu_item_call> +                        <menu_item_separator/>              <menu_item_call | 
