diff options
26 files changed, 1273 insertions, 872 deletions
| diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index f0eafa8201..447c7f50f2 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -356,14 +356,15 @@ namespace tut          // Create a script file in a temporary place.          NamedTempFile script("py", +			"from __future__ import print_function" EOL              "import sys" EOL              "import time" EOL              EOL              "time.sleep(2)" EOL -            "print >>sys.stdout, 'stdout after wait'" EOL +            "print('stdout after wait',file=sys.stdout)" EOL              "sys.stdout.flush()" EOL              "time.sleep(2)" EOL -            "print >>sys.stderr, 'stderr after wait'" EOL +            "print('stderr after wait',file=sys.stderr)" EOL              "sys.stderr.flush()" EOL              ); @@ -568,12 +569,12 @@ namespace tut      {          set_test_name("arguments");          PythonProcessLauncher py(get_test_name(), -                                 "from __future__ import with_statement\n" +                                 "from __future__ import with_statement, print_function\n"                                   "import sys\n"                                   // note nonstandard output-file arg!                                   "with open(sys.argv[3], 'w') as f:\n"                                   "    for arg in sys.argv[1:]:\n" -                                 "        print >>f, arg\n"); +                                 "        print(arg,file=f)\n");          // We expect that PythonProcessLauncher has already appended          // its own NamedTempFile to mParams.args (sys.argv[0]).          py.mParams.args.add("first arg");          // sys.argv[1] @@ -857,7 +858,8 @@ namespace tut          set_test_name("'bogus' test");          CaptureLog recorder;          PythonProcessLauncher py(get_test_name(), -                                 "print 'Hello world'\n"); +                                 "from __future__ import print_function\n" +                                 "print('Hello world')\n");          py.mParams.files.add(LLProcess::FileParam("bogus"));          py.mPy = LLProcess::create(py.mParams);          ensure("should have rejected 'bogus'", ! py.mPy); @@ -872,7 +874,8 @@ namespace tut          // Replace this test with one or more real 'file' tests when we          // implement 'file' support          PythonProcessLauncher py(get_test_name(), -                                 "print 'Hello world'\n"); +                                 "from __future__ import print_function\n" +                                 "print('Hello world')\n");          py.mParams.files.add(LLProcess::FileParam());          py.mParams.files.add(LLProcess::FileParam("file"));          py.mPy = LLProcess::create(py.mParams); @@ -887,7 +890,8 @@ namespace tut          // implement 'tpipe' support          CaptureLog recorder;          PythonProcessLauncher py(get_test_name(), -                                 "print 'Hello world'\n"); +                                 "from __future__ import print_function\n" +                                 "print('Hello world')\n");          py.mParams.files.add(LLProcess::FileParam());          py.mParams.files.add(LLProcess::FileParam("tpipe"));          py.mPy = LLProcess::create(py.mParams); @@ -904,7 +908,8 @@ namespace tut          // implement 'npipe' support          CaptureLog recorder;          PythonProcessLauncher py(get_test_name(), -                                 "print 'Hello world'\n"); +                                 "from __future__ import print_function\n" +                                 "print('Hello world')\n");          py.mParams.files.add(LLProcess::FileParam());          py.mParams.files.add(LLProcess::FileParam());          py.mParams.files.add(LLProcess::FileParam("npipe")); @@ -980,7 +985,8 @@ namespace tut      {          set_test_name("get*Pipe() validation");          PythonProcessLauncher py(get_test_name(), -                                 "print 'this output is expected'\n"); +                                 "from __future__ import print_function\n" +                                 "print('this output is expected')\n");          py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for  stdin          py.mParams.files.add(LLProcess::FileParam());       // inherit stdout          py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stderr @@ -1000,14 +1006,15 @@ namespace tut      {          set_test_name("talk to stdin/stdout");          PythonProcessLauncher py(get_test_name(), +                                 "from __future__ import print_function\n"                                   "import sys, time\n" -                                 "print 'ok'\n" +                                 "print('ok')\n"                                   "sys.stdout.flush()\n"                                   "# wait for 'go' from test program\n"                                   "go = sys.stdin.readline()\n"                                   "if go != 'go\\n':\n"                                   "    sys.exit('expected \"go\", saw %r' % go)\n" -                                 "print 'ack'\n"); +                                 "print('ack')\n");          py.mParams.files.add(LLProcess::FileParam("pipe")); // stdin          py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout          py.launch(); @@ -1118,7 +1125,8 @@ namespace tut      {          set_test_name("ReadPipe \"eof\" event");          PythonProcessLauncher py(get_test_name(), -                                 "print 'Hello from Python!'\n"); +                                 "from __future__ import print_function\n" +                                 "print('Hello from Python!')\n");          py.mParams.files.add(LLProcess::FileParam()); // stdin          py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout          py.launch(); diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 673f6cb6df..a269549c49 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -62,6 +62,7 @@  BOOL gDebugSession = FALSE;  BOOL gClothRipple = FALSE;  BOOL gHeadlessClient = FALSE; +BOOL gNonInteractive = FALSE;  BOOL gGLActive = FALSE;  BOOL gGLDebugLoggingEnabled = TRUE; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index a03d5352be..6e1f5e6deb 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -485,6 +485,7 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor  extern BOOL gClothRipple;  extern BOOL gHeadlessClient; +extern BOOL gNonInteractive;  extern BOOL gGLActive;  // Deal with changing glext.h definitions for newer SDK versions, specifically diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 30bc743e72..67ef98d7b3 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -137,6 +137,12 @@ BOOL LLWindow::canDelete()  	return TRUE;  } +//virtual +void LLWindow::setTitle(const std::string title) +{ +    // the action happens in the platform specific impl +} +  // virtual  void LLWindow::incBusyCount()  { diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 1384ddfd82..b76d313011 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -100,6 +100,13 @@ public:  	virtual void showCursorFromMouseMove() = 0;  	virtual void hideCursorUntilMouseMove() = 0; +    // Provide a way to set the Viewer window title after the +    // windows has been created. The initial use case for this +    // is described in SL-16102 (update window title with agent  +    // name, location etc. for non-interactive viewer) but it +    // may also be useful in other cases. +    virtual void setTitle(const std::string title); +  	// These two functions create a way to make a busy cursor instead  	// of an arrow when someone's busy doing something. Draw an  	// arrow/hour if busycount > 0. diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index bf78bcba29..26bb56d72d 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1925,6 +1925,13 @@ void LLWindowWin32::moveWindow( const LLCoordScreen& position, const LLCoordScre  	MoveWindow(mWindowHandle, position.mX, position.mY, size.mX, size.mY, TRUE);  } +void LLWindowWin32::setTitle(const std::string title) +{ +    // TODO: Do we need to use the wide string version of this call +    // to support non-ascii usernames (and region names?) +    SetWindowTextA(mWindowHandle, title.c_str()); +} +  BOOL LLWindowWin32::setCursorPosition(const LLCoordWindow position)  {      ASSERT_MAIN_THREAD(); diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index b44d458fc6..7a9a30ccea 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -94,6 +94,7 @@ public:  	/*virtual*/ BOOL setSizeImpl(LLCoordScreen size);  	/*virtual*/ BOOL setSizeImpl(LLCoordWindow size);  	/*virtual*/ BOOL switchContext(BOOL fullscreen, const LLCoordScreen &size, BOOL disable_vsync, const LLCoordScreen * const posp = NULL); +    /*virtual*/ void setTitle(const std::string title);      void* createSharedContext() override;      void makeContextCurrent(void* context) override;      void destroySharedContext(void* context) override; diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index 4e186292f7..7514913d13 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -217,6 +217,14 @@        <string>NoInventoryLibrary</string>      </map> +    <key>noninteractive</key> +    <map> +      <key>desc</key> +      <string>Run in semi-headless mode where only login and logout need to work.</string> +      <key>map-to</key> +      <string>NonInteractive</string> +    </map> +      <key>nonotifications</key>      <map>        <key>desc</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index eeadea76a2..aeeba58a68 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7015,6 +7015,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>NonInteractive</key> +    <map> +      <key>Comment</key> +      <string>Run in a semi-headless mode where only logging in and logging out needs to work.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +	  <integer>0</integer> +    </map>      <key>NonvisibleObjectsInMemoryTime</key>      <map>        <key>Comment</key> @@ -16644,6 +16655,17 @@        <key>Value</key>        <integer>1</integer>              </map> +    <key>UpdateAppWindowTitleBar</key> +    <map> +      <key>Comment</key> +      <string>Updates the application window title bar with brief information about user/location</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>  </map>  </llsd> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 389448654a..b35eef20f7 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1481,7 +1481,7 @@ void LLAgent::resetControlFlags()  //-----------------------------------------------------------------------------  void LLAgent::setAFK()  { -	if (!gAgent.getRegion()) +	if (gNonInteractive || !gAgent.getRegion())  	{  		// Don't set AFK if we're not talking to a region yet.  		return; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 691c3f3798..8492aba222 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1555,6 +1555,14 @@ bool LLAppViewer::doFrame()  				ms_sleep(yield_time);  			} +			if (gNonInteractive) +			{ +				S32 non_interactive_ms_sleep_time = 100; +				LLAppViewer::getTextureCache()->pause(); +				LLAppViewer::getImageDecodeThread()->pause(); +				ms_sleep(non_interactive_ms_sleep_time); +			} +  			// yield cooperatively when not running as foreground window  			// and when not quiting (causes trouble at mac's cleanup stage)  			if (!LLApp::isExiting() @@ -1562,8 +1570,8 @@ bool LLAppViewer::doFrame()  					|| !gFocusMgr.getAppHasFocus()))  			{  				// Sleep if we're not rendering, or the window is minimized. -				static LLCachedControl<S32> s_bacground_yeild_time(gSavedSettings, "BackgroundYieldTime", 40); -				S32 milliseconds_to_sleep = llclamp((S32)s_bacground_yeild_time, 0, 1000); +				static LLCachedControl<S32> s_background_yield_time(gSavedSettings, "BackgroundYieldTime", 40); +				S32 milliseconds_to_sleep = llclamp((S32)s_background_yield_time, 0, 1000);  				// don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads  				// of equal priority on Windows  				if (milliseconds_to_sleep > 0) @@ -2440,6 +2448,38 @@ namespace      }  } // anonymous namespace +// Set a named control temporarily for this session, as when set via the command line --set option. +// Name can be specified as "<control_group>.<control_name>", with default group being Global. +bool tempSetControl(const std::string& name, const std::string& value) +{ +	std::string name_part; +	std::string group_part; +	LLControlVariable* control = NULL; + +	// Name can be further split into ControlGroup.Name, with the default control group being Global +	size_t pos = name.find('.'); +	if (pos != std::string::npos) +	{ +		group_part = name.substr(0, pos); +		name_part = name.substr(pos+1); +		LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL; +		auto g = LLControlGroup::getInstance(group_part); +		if (g) control = g->getControl(name_part); +	} +	else +	{ +		LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL; +		control = gSavedSettings.getControl(name); +	} + +	if (control) +	{ +		control->setValue(value, false); +		return true; +	} +	return false; +} +  bool LLAppViewer::initConfiguration()  {  	//Load settings files list @@ -2596,9 +2636,10 @@ bool LLAppViewer::initConfiguration()  		disableCrashlogger();  	} +	gNonInteractive = gSavedSettings.getBOOL("NonInteractive");  	// Handle initialization from settings.  	// Start up the debugging console before handling other options. -	if (gSavedSettings.getBOOL("ShowConsoleWindow")) +	if (gSavedSettings.getBOOL("ShowConsoleWindow") && !gNonInteractive)  	{  		initConsole();  	} @@ -2631,33 +2672,9 @@ bool LLAppViewer::initConfiguration()              {                  const std::string& name = *itr;                  const std::string& value = *(++itr); -                std::string name_part; -                std::string group_part; -				LLControlVariable* control = NULL; - -				// Name can be further split into ControlGroup.Name, with the default control group being Global -				size_t pos = name.find('.'); -				if (pos != std::string::npos) -				{ -					group_part = name.substr(0, pos); -					name_part = name.substr(pos+1); -					LL_INFOS() << "Setting " << group_part << "." << name_part << " to " << value << LL_ENDL; -					auto g = LLControlGroup::getInstance(group_part); -					if (g) control = g->getControl(name_part); -				} -				else -				{ -					LL_INFOS() << "Setting Global." << name << " to " << value << LL_ENDL; -					control = gSavedSettings.getControl(name); -				} - -                if (control) -                { -                    control->setValue(value, false); -                } -                else +                if (!tempSetControl(name,value))                  { -					LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL; +                    LL_WARNS() << "Failed --set " << name << ": setting name unknown." << LL_ENDL;                  }              }          } @@ -2743,6 +2760,19 @@ bool LLAppViewer::initConfiguration()  		}  	} +	if (gNonInteractive) +	{ +		tempSetControl("AllowMultipleViewers", "TRUE"); +		tempSetControl("SLURLPassToOtherInstance", "FALSE"); +		tempSetControl("RenderWater", "FALSE"); +		tempSetControl("FlyingAtExit", "FALSE"); +		tempSetControl("WindowWidth", "1024"); +		tempSetControl("WindowHeight", "200"); +		LLError::setEnabledLogTypesMask(0); +		llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance")); +	} + +  	// Handle slurl use. NOTE: Don't let SL-55321 reappear.  	// This initial-SLURL logic, up through the call to  	// sendURLToOtherInstance(), must precede LLSplashScreen::show() -- diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 8b8273d183..31ca2531ba 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -119,8 +119,11 @@ BOOL LLViewerDynamicTexture::render()  void LLViewerDynamicTexture::preRender(BOOL clear_depth)  {  	gPipeline.allocatePhysicsBuffer(); -	llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth())); -	llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight())); +	if (!gNonInteractive) +	{ +		llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth())); +		llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight())); +	}  	if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI)  	{ //using offscreen render target, just use the bottom left corner diff --git a/indra/newview/llteleporthistory.cpp b/indra/newview/llteleporthistory.cpp index 3c3c1c96ef..3ece12931c 100644 --- a/indra/newview/llteleporthistory.cpp +++ b/indra/newview/llteleporthistory.cpp @@ -39,6 +39,11 @@  #include "llviewerregion.h"  #include "llworldmap.h"  #include "llagentui.h" +#include "llwindow.h" +#include "llviewerwindow.h" +#include "llavatarname.h" +#include "llavatarnamecache.h" +  //////////////////////////////////////////////////////////////////////////////  // LLTeleportHistoryItem @@ -113,6 +118,20 @@ void LLTeleportHistory::handleLoginComplete()  	updateCurrentLocation(gAgent.getPositionGlobal());  } +static void on_avatar_name_update_title(const LLAvatarName& av_name) +{ +	if (gAgent.getRegion() && gViewerWindow && gViewerWindow->getWindow()) +	{ +		std::string region = gAgent.getRegion()->getName(); +		std::string username = av_name.getUserName(); + +		// this first pass simply displays username and region name +		// but could easily be extended to include other details like +		// X/Y/Z location within a region etc. +		std::string new_title = STRINGIZE(username << " @ " << region); +		gViewerWindow->getWindow()->setTitle(new_title); +	}	 +}  void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)  { @@ -174,6 +193,14 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)  	if (!mGotInitialUpdate)  		mGotInitialUpdate = true; +    // update Viewer window title with username and region name +    // if we are in "non-interactive mode" (SL-15999) or the debug  +    // setting to allow it is enabled (may be useful in other situations) +    if (gNonInteractive || gSavedSettings.getBOOL("UpdateAppWindowTitleBar")) +    { +		LLAvatarNameCache::get(gAgent.getID(), boost::bind(&on_avatar_name_update_title, _2)); +    } +  	// Signal the interesting party that we've changed.   	onHistoryChanged();  } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 63e561147d..73a25397fd 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1143,6 +1143,10 @@ void LLTextureFetchWorker::startWork(S32 param)  bool LLTextureFetchWorker::doWork(S32 param)  {      LL_PROFILE_ZONE_SCOPED; +	if (gNonInteractive) +	{ +		return true; +	}  	static const LLCore::HttpStatus http_not_found(HTTP_NOT_FOUND);						// 404  	static const LLCore::HttpStatus http_service_unavail(HTTP_SERVICE_UNAVAILABLE);		// 503  	static const LLCore::HttpStatus http_not_sat(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE);	// 416; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 33842497d1..1236695e4f 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -124,7 +124,8 @@ void display_startup()  	if (   !gViewerWindow  		|| !gViewerWindow->getActive()  		|| !gViewerWindow->getWindow()->getVisible()  -		|| gViewerWindow->getWindow()->getMinimized() ) +		|| gViewerWindow->getWindow()->getMinimized() +		|| gNonInteractive)  	{  		return;   	} @@ -313,7 +314,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  	// Attempting to draw into a minimized window causes a GL error. JC  	if (   !gViewerWindow->getActive()  		|| !gViewerWindow->getWindow()->getVisible()  -		|| gViewerWindow->getWindow()->getMinimized() ) +		|| gViewerWindow->getWindow()->getMinimized()  +		|| gNonInteractive)  	{  		// Clean up memory the pools may have allocated  		if (rebuild) diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 5a05f89758..98b76328de 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -192,6 +192,10 @@ LLFloaterOpenHandler gFloaterOpenHandler;  void LLViewerFloaterReg::registerFloaters()  { +	if (gNonInteractive) +	{ +		return; +	}  	// *NOTE: Please keep these alphabetized for easier merges  	LLFloaterAboutUtil::registerFloater(); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index d35dbda907..c347e0eb76 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1216,7 +1216,7 @@ LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders()  /////////////////////////////////////////////////////////////////////////////////////////  void LLViewerMedia::setOpenIDCookie(const std::string& url)  { -	if(!mOpenIDCookie.empty()) +	if(!gNonInteractive && !mOpenIDCookie.empty())  	{          std::string profileUrl = getProfileURL(""); @@ -1687,6 +1687,11 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type)  /*static*/  LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, F64 zoom_factor, const std::string target, bool clean_browser)  { +	if (gNonInteractive) +    { +        return NULL; +    } +  	std::string plugin_basename = LLMIMETypes::implType(media_type);  	LLPluginClassMedia* media_source = NULL; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 94d2d216b9..5e99d13206 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2423,6 +2423,10 @@ void translateFailure(LLChat chat, LLSD toastArgs, int status, const std::string  void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)  { +	if (gNonInteractive) +	{ +		return; +	}  	LLChat	chat;  	std::string		mesg;  	std::string		from_name; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index b88baf6aa7..0832415e1e 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -107,6 +107,7 @@  #include "llcleanup.h"  #include "llcallstack.h"  #include "llmeshrepository.h" +#include "llgl.h"  //#define DEBUG_UPDATE_TYPE @@ -155,11 +156,27 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco  	LLViewerObject *res = NULL;  	LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT); -	 + +	if (gNonInteractive +		&& pcode != LL_PCODE_LEGACY_AVATAR +		&& pcode != LL_VO_SURFACE_PATCH +		&& pcode != LL_VO_WATER +		&& pcode != LL_VO_VOID_WATER +		&& pcode != LL_VO_WL_SKY +		&& pcode != LL_VO_SKY +		&& pcode != LL_VO_GROUND +		&& pcode != LL_VO_PART_GROUP +		) +	{ +		return res; +	}  	switch (pcode)  	{  	case LL_PCODE_VOLUME: -	  res = new LLVOVolume(id, pcode, regionp); break; +	{ +		res = new LLVOVolume(id, pcode, regionp); break; +		break; +	}  	case LL_PCODE_LEGACY_AVATAR:  	{  		if (id == gAgentID) diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 0b20556104..097b5e3645 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -80,6 +80,7 @@  #include "llfloaterperms.h"  #include "llvocache.h"  #include "llcorehttputil.h" +#include "llstartup.h"  #include <algorithm>  #include <iterator> @@ -309,7 +310,7 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry*  	LLDataPacker *cached_dpp = entry->getDP(); -	if (!cached_dpp) +	if (!cached_dpp || gNonInteractive)  	{  		return NULL; //nothing cached.  	} @@ -2063,7 +2064,6 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L  LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp,  												 const LLUUID &uuid, const U32 local_id, const LLHost &sender)  { -	  	LLUUID fullid;  	if (uuid == LLUUID::null)  	{ diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index b6b4d1e41f..a5a1fb2c16 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -1,796 +1,796 @@ -/** 
 - * @file llviewertexture.h
 - * @brief Object for managing images and their textures
 - *
 - * $LicenseInfo:firstyear=2000&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_LLVIEWERTEXTURE_H					
 -#define LL_LLVIEWERTEXTURE_H
 -
 -#include "llgltexture.h"
 -#include "lltimer.h"
 -#include "llframetimer.h"
 -#include "llhost.h"
 -#include "llgltypes.h"
 -#include "llrender.h"
 -#include "llmetricperformancetester.h"
 -#include "httpcommon.h"
 -
 -#include <map>
 -#include <list>
 -
 -extern const S32Megabytes gMinVideoRam;
 -extern const S32Megabytes gMaxVideoRam;
 -
 -class LLFace;
 -class LLImageGL ;
 -class LLImageRaw;
 -class LLViewerObject;
 -class LLViewerTexture;
 -class LLViewerFetchedTexture ;
 -class LLViewerMediaTexture ;
 -class LLTexturePipelineTester ;
 -
 -
 -typedef	void	(*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
 -
 -class LLVFile;
 -class LLMessageSystem;
 -class LLViewerMediaImpl ;
 -class LLVOVolume ;
 -struct LLTextureKey;
 -
 -class LLLoadedCallbackEntry
 -{
 -public:
 -    typedef std::set< LLTextureKey > source_callback_list_t;
 -
 -public:
 -	LLLoadedCallbackEntry(loaded_callback_func cb,
 -						  S32 discard_level,
 -						  BOOL need_imageraw, // Needs image raw for the callback
 -						  void* userdata,
 -						  source_callback_list_t* src_callback_list,
 -						  LLViewerFetchedTexture* target,
 -						  BOOL pause);
 -	~LLLoadedCallbackEntry();
 -	void removeTexture(LLViewerFetchedTexture* tex) ;
 -
 -	loaded_callback_func	mCallback;
 -	S32						mLastUsedDiscard;
 -	S32						mDesiredDiscard;
 -	BOOL					mNeedsImageRaw;
 -	BOOL                    mPaused;
 -	void*					mUserData;
 -	source_callback_list_t* mSourceCallbackList;
 -	
 -public:
 -	static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ;
 -};
 -
 -class LLTextureBar;
 -
 -class LLViewerTexture : public LLGLTexture
 -{
 -public:
 -	enum
 -	{
 -		LOCAL_TEXTURE,		
 -		MEDIA_TEXTURE,
 -		DYNAMIC_TEXTURE,
 -		FETCHED_TEXTURE,
 -		LOD_TEXTURE,
 -		ATLAS_TEXTURE,
 -		INVALID_TEXTURE_TYPE
 -	};
 -
 -	typedef std::vector<class LLFace*> ll_face_list_t;
 -	typedef std::vector<LLVOVolume*> ll_volume_list_t;
 -
 -
 -protected:
 -	virtual ~LLViewerTexture();
 -	LOG_CLASS(LLViewerTexture);
 -
 -public:	
 -	static void initClass();
 -	static void updateClass(const F32 velocity, const F32 angular_velocity) ;
 -	
 -	LLViewerTexture(BOOL usemipmaps = TRUE);
 -	LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ;
 -	LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
 -	LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
 -
 -	virtual S8 getType() const;
 -	virtual BOOL isMissingAsset() const ;
 -	virtual void dump();	// debug info to LL_INFOS()
 -	
 -    virtual bool isViewerMediaTexture() const { return false; }
 -
 -	/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
 -	/*virtual*/ bool bindDebugImage(const S32 stage = 0) ;
 -	/*virtual*/ void forceImmediateUpdate() ;
 -	/*virtual*/ bool isActiveFetching();
 -	
 -	/*virtual*/ const LLUUID& getID() const { return mID; }
 -	void setBoostLevel(S32 level);
 -	S32  getBoostLevel() { return mBoostLevel; }
 -	void setTextureListType(S32 tex_type) { mTextureListType = tex_type; }
 -	S32 getTextureListType() { return mTextureListType; }
 -
 -	void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const;
 -	void resetTextureStats();	
 -	void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;}
 -	void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;}
 -	S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; }
 -
 -	virtual F32  getMaxVirtualSize() ;
 -
 -	LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
 -	
 -	S32 getFullWidth() const { return mFullWidth; }
 -	S32 getFullHeight() const { return mFullHeight; }	
 -	/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
 -
 -	virtual void addFace(U32 channel, LLFace* facep) ;
 -	virtual void removeFace(U32 channel, LLFace* facep) ; 
 -	S32 getTotalNumFaces() const;
 -	S32 getNumFaces(U32 ch) const;
 -	const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];}
 -
 -	virtual void addVolume(U32 channel, LLVOVolume* volumep);
 -	virtual void removeVolume(U32 channel, LLVOVolume* volumep);
 -	S32 getNumVolumes(U32 channel) const;
 -	const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; }
 -
 -	
 -	virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
 -	BOOL isLargeImage() ;	
 -	
 -	void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;}
 -	BOOL hasParcelMedia() const { return mParcelMedia != NULL;}
 -	LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;}
 -
 -	/*virtual*/ void updateBindStatsForTester() ;
 -protected:
 -	void cleanup() ;
 -	void init(bool firstinit) ;
 -	void reorganizeFaceList() ;
 -	void reorganizeVolumeList() ;
 -
 -	void notifyAboutMissingAsset();
 -	void notifyAboutCreatingTexture();
 -
 -private:
 -	friend class LLBumpImageList;
 -	friend class LLUIImageList;
 -
 -	virtual void switchToCachedImage();
 -	
 -	static bool isMemoryForTextureLow() ;
 -	static bool isMemoryForTextureSuficientlyFree();
 -	static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
 -
 -protected:
 -	LLUUID mID;
 -	S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
 -
 -	F32 mSelectedTime;				// time texture was last selected
 -	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?	
 -	mutable S32  mMaxVirtualSizeResetCounter ;
 -	mutable S32  mMaxVirtualSizeResetInterval;
 -	mutable F32 mAdditionalDecodePriority;  // priority add to mDecodePriority.
 -	LLFrameTimer mLastReferencedTimer;	
 -
 -	ll_face_list_t    mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
 -	U32               mNumFaces[LLRender::NUM_TEXTURE_CHANNELS];
 -	LLFrameTimer      mLastFaceListUpdateTimer ;
 -
 -	ll_volume_list_t  mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
 -	U32					mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
 -	LLFrameTimer	  mLastVolumeListUpdateTimer;
 -
 -	//do not use LLPointer here.
 -	LLViewerMediaTexture* mParcelMedia ;
 -
 -	static F32 sTexelPixelRatio;
 -public:
 -	static const U32 sCurrentFileVersion;	
 -	static S32 sImageCount;
 -	static S32 sRawCount;
 -	static S32 sAuxCount;
 -	static LLFrameTimer sEvaluationTimer;
 -	static F32 sDesiredDiscardBias;
 -	static F32 sDesiredDiscardScale;
 -	static S32Bytes sBoundTextureMemory;
 -	static S32Bytes sTotalTextureMemory;
 -	static S32Megabytes sMaxBoundTextureMemory;
 -	static S32Megabytes sMaxTotalTextureMem;
 -	static S32Bytes sMaxDesiredTextureMem ;
 -	static S8  sCameraMovingDiscardBias;
 -	static F32 sCameraMovingBias;
 -	static S32 sMaxSculptRez ;
 -	static U32 sMinLargeImageSize ;
 -	static U32 sMaxSmallImageSize ;
 -	static bool sFreezeImageUpdates;
 -	static F32  sCurrentTime ;
 -
 -	enum EDebugTexels
 -	{
 -		DEBUG_TEXELS_OFF,
 -		DEBUG_TEXELS_CURRENT,
 -		DEBUG_TEXELS_DESIRED,
 -		DEBUG_TEXELS_FULL
 -	};
 -
 -	static EDebugTexels sDebugTexelsMode;
 -
 -	static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects.
 -	static LLPointer<LLViewerTexture> sBlackImagep;	// Texture to show NOTHING (pure black)
 -	static LLPointer<LLViewerTexture> sCheckerBoardImagep;	// Texture to show NOTHING (pure black)
 -};
 -
 -
 -enum FTType
 -{
 -	FTT_UNKNOWN = -1,
 -	FTT_DEFAULT = 0, // standard texture fetched by id.
 -	FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there.
 -	FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host.
 -	FTT_MAP_TILE, // tiles are fetched from map server directly.
 -	FTT_LOCAL_FILE // fetch directly from a local file.
 -};
 -
 -const std::string& fttype_to_string(const FTType& fttype);
 -
 -//
 -//textures are managed in gTextureList.
 -//raw image data is fetched from remote or local cache
 -//but the raw image this texture pointing to is fixed.
 -//
 -class LLViewerFetchedTexture : public LLViewerTexture
 -{
 -	friend class LLTextureBar; // debug info only
 -	friend class LLTextureView; // debug info only
 -
 -protected:
 -	/*virtual*/ ~LLViewerFetchedTexture();
 -public:
 -	LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE);
 -	LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps);
 -	LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
 -
 -public:
 -	static F32 maxDecodePriority();
 -	
 -	struct Compare
 -	{
 -		// lhs < rhs
 -		bool operator()(const LLPointer<LLViewerFetchedTexture> &lhs, const LLPointer<LLViewerFetchedTexture> &rhs) const
 -		{
 -			const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs;
 -			const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs;
 -			// greater priority is "less"
 -			const F32 lpriority = lhsp->getDecodePriority();
 -			const F32 rpriority = rhsp->getDecodePriority();
 -			if (lpriority > rpriority) // higher priority
 -				return true;
 -			if (lpriority < rpriority)
 -				return false;
 -			return lhsp < rhsp;
 -		}
 -	};
 -
 -public:
 -	/*virtual*/ S8 getType() const ;
 -	FTType getFTType() const;
 -	/*virtual*/ void forceImmediateUpdate() ;
 -	/*virtual*/ void dump() ;
 -
 -	// Set callbacks to get called when the image gets updated with higher 
 -	// resolution versions.
 -	void setLoadedCallback(loaded_callback_func cb,
 -						   S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
 -						   void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE);
 -	bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }	
 -	void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
 -	void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
 -	bool doLoadedCallbacks();
 -	void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list);
 -	void clearCallbackEntryList() ;
 -
 -	void addToCreateTexture();
 -
 -    //call to determine if createTexture is necessary
 -    BOOL preCreateTexture(S32 usename = 0);
 -	 // ONLY call from LLViewerTextureList or ImageGL background thread
 -	BOOL createTexture(S32 usename = 0);
 -    void postCreateTexture();
 -    void scheduleCreateTexture();
 -
 -	void destroyTexture() ;
 -
 -	virtual void processTextureStats() ;
 -	F32  calcDecodePriority() ;
 -
 -	BOOL needsAux() const { return mNeedsAux; }
 -
 -	// Host we think might have this image, used for baked av textures.
 -	void setTargetHost(LLHost host)			{ mTargetHost = host; }
 -	LLHost getTargetHost() const			{ return mTargetHost; }
 -	
 -	// Set the decode priority for this image...
 -	// DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up
 -	// the priority list, and cause horrible things to happen.
 -	void setDecodePriority(F32 priority = -1.0f);
 -	F32 getDecodePriority() const { return mDecodePriority; };
 -	F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; };
 -
 -	void setAdditionalDecodePriority(F32 priority) ;
 -	
 -	void updateVirtualSize() ;
 -
 -	S32  getDesiredDiscardLevel()			 { return mDesiredDiscardLevel; }
 -	void setMinDiscardLevel(S32 discard) 	{ mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }
 -
 -	bool updateFetch();
 -	bool setDebugFetching(S32 debug_level);
 -	bool isInDebug() const { return mInDebug; }
 -
 -	void setUnremovable(BOOL value) { mUnremovable = value; }
 -	bool isUnremovable() const { return mUnremovable; }
 -	
 -	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.
 -	/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
 -
 -	void setIsMissingAsset(BOOL is_missing = true);
 -	/*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; }
 -
 -	// returns dimensions of original image for local files (before power of two scaling)
 -	// and returns 0 for all asset system images
 -	S32 getOriginalWidth() { return mOrigWidth; }
 -	S32 getOriginalHeight() { return mOrigHeight; }
 -
 -	BOOL isInImageList() const {return mInImageList ;}
 -	void setInImageList(BOOL flag) {mInImageList = flag ;}
 -
 -	LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;}
 -
 -	U32 getFetchPriority() const { return mFetchPriority ;}
 -	F32 getDownloadProgress() const {return mDownloadProgress ;}
 -
 -	LLImageRaw* reloadRawImage(S8 discard_level) ;
 -	void destroyRawImage();
 -	bool needsToSaveRawImage();
 -
 -	const std::string& getUrl() const {return mUrl;}
 -	//---------------
 -	BOOL isDeleted() ;
 -	BOOL isInactive() ;
 -	BOOL isDeletionCandidate();
 -	void setDeletionCandidate() ;
 -	void setInactive() ;
 -	BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; }	
 -	//---------------
 -
 -	void setForSculpt();
 -	BOOL forSculpt() const {return mForSculpt;}
 -	BOOL isForSculptOnly() const;
 -
 -	//raw image management	
 -	void        checkCachedRawSculptImage() ;
 -	LLImageRaw* getRawImage()const { return mRawImage ;}
 -	S32         getRawImageLevel() const {return mRawDiscardLevel;}
 -	LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;}
 -	S32         getCachedRawImageLevel() const {return mCachedRawDiscardLevel;}
 -	BOOL        isCachedRawImageReady() const {return mCachedRawImageReady ;}
 -	BOOL        isRawImageValid()const { return mIsRawImageValid ; }	
 -	void        forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;
 -	void        forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
 -	/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
 -	void        destroySavedRawImage() ;
 -	LLImageRaw* getSavedRawImage() ;
 -	BOOL        hasSavedRawImage() const ;
 -	F32         getElapsedLastReferencedSavedRawImageTime() const ;
 -	BOOL		isFullyLoaded() const;
 -
 -	BOOL        hasFetcher() const { return mHasFetcher;}
 -	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; }
 -
 -	/*virtual*/bool  isActiveFetching(); //is actively in fetching by the fetching pipeline.
 -
 -protected:
 -	/*virtual*/ void switchToCachedImage();
 -	S32 getCurrentDiscardLevelForFetching() ;
 -
 -private:
 -	void init(bool firstinit) ;	
 -	void cleanup() ;
 -
 -	void saveRawImage() ;
 -	void setCachedRawImage() ;
 -
 -	//for atlas
 -	void resetFaceAtlas() ;
 -	void invalidateAtlas(BOOL rebuild_geom) ;
 -	BOOL insertToAtlas() ;
 -
 -private:
 -	BOOL  mFullyLoaded;
 -	BOOL  mInDebug;
 -	BOOL  mUnremovable;
 -	BOOL  mInFastCacheList;
 -	BOOL  mForceCallbackFetch;
 -
 -protected:		
 -	std::string mLocalFileName;
 -
 -	S32 mOrigWidth;
 -	S32 mOrigHeight;
 -
 -	// 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.
 -	S32 mKnownDrawWidth;
 -	S32	mKnownDrawHeight;
 -	BOOL mKnownDrawSizeChanged ;
 -	std::string mUrl;
 -	
 -	S32 mRequestedDiscardLevel;
 -	F32 mRequestedDownloadPriority;
 -	S32 mFetchState;
 -	U32 mFetchPriority;
 -	F32 mDownloadProgress;
 -	F32 mFetchDeltaTime;
 -	F32 mRequestDeltaTime;
 -	F32 mDecodePriority;			// The priority for decoding this image.
 -	S32	mMinDiscardLevel;
 -	S8  mDesiredDiscardLevel;			// The discard level we'd LIKE to have - if we have it and there's space	
 -	S8  mMinDesiredDiscardLevel;	// The minimum discard level we'd like to have
 -
 -	S8  mNeedsAux;					// We need to decode the auxiliary channels
 -	S8  mHasAux;                    // We have aux channels
 -	S8  mDecodingAux;				// Are we decoding high components
 -	S8  mIsRawImageValid;
 -	S8  mHasFetcher;				// We've made a fecth request
 -	S8  mIsFetching;				// Fetch request is active
 -	bool mCanUseHTTP;              //This texture can be fetched through http if true.
 -	LLCore::HttpStatus mLastHttpGetStatus; // Result of the most recently completed http request for this texture.
 -
 -	FTType mFTType; // What category of image is this - map tile, server bake, etc?
 -	mutable S8 mIsMissingAsset;		// True if we know that there is no image asset with this image id in the database.		
 -
 -	typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
 -	S8              mLoadedCallbackDesiredDiscardLevel;
 -	BOOL            mPauseLoadedCallBacks;
 -	callback_list_t mLoadedCallbackList;
 -	F32             mLastCallBackActiveTime;
 -
 -	LLPointer<LLImageRaw> mRawImage;
 -	S32 mRawDiscardLevel;
 -
 -	// Used ONLY for cloth meshes right now.  Make SURE you know what you're 
 -	// doing if you use it for anything else! - djs
 -	LLPointer<LLImageRaw> mAuxRawImage;
 -
 -	//keep a copy of mRawImage for some special purposes
 -	//when mForceToSaveRawImage is set.
 -	BOOL mForceToSaveRawImage ;
 -	BOOL mSaveRawImage;
 -	LLPointer<LLImageRaw> mSavedRawImage;
 -	S32 mSavedRawDiscardLevel;
 -	S32 mDesiredSavedRawDiscardLevel;
 -	F32 mLastReferencedSavedRawImageTime ;
 -	F32 mKeptSavedRawImageTime ;
 -
 -	//a small version of the copy of the raw image (<= 64 * 64)
 -	LLPointer<LLImageRaw> mCachedRawImage;
 -	S32 mCachedRawDiscardLevel;
 -	BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit.	
 -
 -	LLHost mTargetHost;	// if invalid, just request from agent's simulator
 -
 -	// Timers
 -	LLFrameTimer mLastPacketTimer;		// Time since last packet.
 -	LLFrameTimer mStopFetchingTimer;	// Time since mDecodePriority == 0.f.
 -
 -	BOOL  mInImageList;				// TRUE if image is in list (in which case don't reset priority!)
 -	BOOL  mNeedsCreateTexture;	
 -
 -	BOOL   mForSculpt ; //a flag if the texture is used as sculpt data.
 -	BOOL   mIsFetched ; //is loaded from remote or from cache, not generated locally.
 -
 -public:
 -	static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep;	// Texture to show for an image asset that is not in the database
 -	static LLPointer<LLViewerFetchedTexture> sWhiteImagep;	// Texture to show NOTHING (whiteness)
 -	static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
 -	static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture
 -	static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface
 -};
 -
 -//
 -//the image data is fetched from remote or from local cache
 -//the resolution of the texture is adjustable: depends on the view-dependent parameters.
 -//
 -class LLViewerLODTexture : public LLViewerFetchedTexture
 -{
 -protected:
 -	/*virtual*/ ~LLViewerLODTexture(){}
 -
 -public:
 -	LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE);
 -	LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
 -
 -	/*virtual*/ S8 getType() const;
 -	// Process image stats to determine priority/quality requirements.
 -	/*virtual*/ void processTextureStats();
 -	bool isUpdateFrozen() ;
 -
 -private:
 -	void init(bool firstinit) ;
 -	bool scaleDown() ;		
 -
 -private:
 -	F32 mDiscardVirtualSize;		// Virtual size used to calculate desired discard	
 -	F32 mCalculatedDiscardLevel;    // Last calculated discard level
 -};
 -
 -//
 -//the image data is fetched from the media pipeline periodically
 -//the resolution of the texture is also adjusted by the media pipeline
 -//
 -class LLViewerMediaTexture : public LLViewerTexture
 -{
 -protected:
 -	/*virtual*/ ~LLViewerMediaTexture() ;
 -
 -public:
 -	LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
 -
 -	/*virtual*/ S8 getType() const;
 -	void reinit(BOOL usemipmaps = TRUE);	
 -
 -	BOOL  getUseMipMaps() {return mUseMipMaps ; }
 -	void  setUseMipMaps(BOOL mipmap) ;	
 -	
 -	void setPlaying(BOOL playing) ;
 -	BOOL isPlaying() const {return mIsPlaying;}
 -	void setMediaImpl() ;
 -
 -    virtual bool isViewerMediaTexture() const { return true; }
 -
 -	void initVirtualSize() ;	
 -	void invalidateMediaImpl() ;
 -
 -	void addMediaToFace(LLFace* facep) ;
 -	void removeMediaFromFace(LLFace* facep) ;
 -
 -	/*virtual*/ void addFace(U32 ch, LLFace* facep) ;
 -	/*virtual*/ void removeFace(U32 ch, LLFace* facep) ; 
 -
 -	/*virtual*/ F32  getMaxVirtualSize() ;
 -private:
 -	void switchTexture(U32 ch, LLFace* facep) ;
 -	BOOL findFaces() ;
 -	void stopPlaying() ;
 -
 -private:
 -	//
 -	//an instant list, recording all faces referencing or can reference to this media texture.
 -	//NOTE: it is NOT thread safe. 
 -	//
 -	std::list< LLFace* > mMediaFaceList ; 
 -
 -	//an instant list keeping all textures which are replaced by the current media texture,
 -	//is only used to avoid the removal of those textures from memory.
 -	std::list< LLPointer<LLViewerTexture> > mTextureList ;
 -
 -	LLViewerMediaImpl* mMediaImplp ;	
 -	BOOL mIsPlaying ;
 -	U32  mUpdateVirtualSizeTime ;
 -
 -public:
 -	static void updateClass() ;
 -	static void cleanUpClass() ;	
 -
 -	static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ;
 -	static void removeMediaImplFromTexture(const LLUUID& media_id) ;
 -
 -private:
 -	typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ;
 -	static media_map_t sMediaMap ;	
 -};
 -
 -//just an interface class, do not create instance from this class.
 -class LLViewerTextureManager
 -{
 -private:
 -	//make the constructor private to preclude creating instances from this class.
 -	LLViewerTextureManager(){}
 -
 -public:
 -    //texture pipeline tester
 -	static LLTexturePipelineTester* sTesterp ;
 -
 -	//returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture.
 -	static LLViewerFetchedTexture*    staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ;
 -
 -	//
 -	//"find-texture" just check if the texture exists, if yes, return it, otherwise return null.
 -	//
 -	static void                       findFetchedTextures(const LLUUID& id, std::vector<LLViewerFetchedTexture*> &output);
 -	static void                       findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output);
 -	static LLViewerFetchedTexture*    findFetchedTexture(const LLUUID& id, S32 tex_type);
 -	static LLViewerMediaTexture*      findMediaTexture(const LLUUID& id) ;
 -	
 -	static LLViewerMediaTexture*      createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
 -
 -	//
 -	//"get-texture" will create a new texture if the texture does not exist.
 -	//
 -	static LLViewerMediaTexture*      getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
 -	
 -	static LLPointer<LLViewerTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE);
 -	static LLPointer<LLViewerTexture> getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
 -	static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
 -	static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
 -
 -	static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,									 
 -									 FTType f_type = FTT_DEFAULT,
 -									 BOOL usemipmap = TRUE,
 -									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 -									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 -									 LLGLint internal_format = 0,
 -									 LLGLenum primary_format = 0,
 -									 LLHost request_from_host = LLHost()
 -									 );
 -	
 -	static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,									 
 -									 FTType f_type = FTT_LOCAL_FILE,
 -									 BOOL usemipmap = TRUE,
 -									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
 -									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 -									 LLGLint internal_format = 0,
 -									 LLGLenum primary_format = 0,
 -									 const LLUUID& force_id = LLUUID::null
 -									 );
 -
 -	static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,									 
 -									 FTType f_type,
 -									 BOOL usemipmap = TRUE,
 -									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
 -									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 -									 LLGLint internal_format = 0,
 -									 LLGLenum primary_format = 0,
 -									 const LLUUID& force_id = LLUUID::null
 -									 );
 -
 -	static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ;
 -
 -	static void init() ;
 -	static void cleanup() ;
 -};
 -//
 -//this class is used for test/debug only
 -//it tracks the activities of the texture pipeline
 -//records them, and outputs them to log files
 -//
 -class LLTexturePipelineTester : public LLMetricPerformanceTesterWithSession
 -{
 -	enum
 -	{
 -		MIN_LARGE_IMAGE_AREA = 262144  //512 * 512
 -	};
 -public:
 -	LLTexturePipelineTester() ;
 -	~LLTexturePipelineTester() ;
 -
 -	void update();		
 -	void updateTextureBindingStats(const LLViewerTexture* imagep) ;
 -	void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ;
 -	void updateGrayTextureBinding() ;
 -	void setStablizingTime() ;
 -
 -private:
 -	void reset() ;
 -	void updateStablizingTime() ;
 -
 -	/*virtual*/ void outputTestRecord(LLSD* sd) ;
 -
 -private:
 -	BOOL mPause ;
 -private:
 -	BOOL mUsingDefaultTexture;            //if set, some textures are still gray.
 -
 -	U32Bytes mTotalBytesUsed ;                     //total bytes of textures bound/used for the current frame.
 -	U32Bytes mTotalBytesUsedForLargeImage ;        //total bytes of textures bound/used for the current frame for images larger than 256 * 256.
 -	U32Bytes mLastTotalBytesUsed ;                 //total bytes of textures bound/used for the previous frame.
 -	U32Bytes mLastTotalBytesUsedForLargeImage ;    //total bytes of textures bound/used for the previous frame for images larger than 256 * 256.
 -		
 -	//
 -	//data size
 -	//
 -	U32Bytes mTotalBytesLoaded ;               //total bytes fetched by texture pipeline
 -	U32Bytes mTotalBytesLoadedFromCache ;      //total bytes fetched by texture pipeline from local cache	
 -	U32Bytes mTotalBytesLoadedForLargeImage ;  //total bytes fetched by texture pipeline for images larger than 256 * 256. 
 -	U32Bytes mTotalBytesLoadedForSculpties ;   //total bytes fetched by texture pipeline for sculpties
 -
 -	//
 -	//time
 -	//NOTE: the error tolerances of the following timers is one frame time.
 -	//
 -	F32 mStartFetchingTime ;
 -	F32 mTotalGrayTime ;                  //total loading time when no gray textures.
 -	F32 mTotalStablizingTime ;            //total stablizing time when texture memory overflows
 -	F32 mStartTimeLoadingSculpties ;      //the start moment of loading sculpty images.
 -	F32 mEndTimeLoadingSculpties ;        //the end moment of loading sculpty images.
 -	F32 mStartStablizingTime ;
 -	F32 mEndStablizingTime ;
 -
 -private:
 -	//
 -	//The following members are used for performance analyzing
 -	//
 -	class LLTextureTestSession : public LLTestSession
 -	{
 -	public:
 -		LLTextureTestSession() ;
 -		/*virtual*/ ~LLTextureTestSession() ;
 -
 -		void reset() ;
 -
 -		F32 mTotalFetchingTime ;
 -		F32 mTotalGrayTime ;
 -		F32 mTotalStablizingTime ;
 -		F32 mStartTimeLoadingSculpties ; 
 -		F32 mTotalTimeLoadingSculpties ;
 -
 -		S32 mTotalBytesLoaded ; 
 -		S32 mTotalBytesLoadedFromCache ;
 -		S32 mTotalBytesLoadedForLargeImage ;
 -		S32 mTotalBytesLoadedForSculpties ; 
 -
 -		typedef struct _texture_instant_preformance_t
 -		{
 -			S32 mAverageBytesUsedPerSecond ;         
 -			S32 mAverageBytesUsedForLargeImagePerSecond ;
 -			F32 mAveragePercentageBytesUsedPerSecond ;
 -			F32 mTime ;
 -		}texture_instant_preformance_t ;
 -		std::vector<texture_instant_preformance_t> mInstantPerformanceList ;
 -		S32 mInstantPerformanceListCounter ;
 -	};
 -
 -	/*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ;
 -	/*virtual*/ void compareTestSessions(llofstream* os) ;
 -};
 -
 -#endif
 +/**  + * @file llviewertexture.h + * @brief Object for managing images and their textures + * + * $LicenseInfo:firstyear=2000&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_LLVIEWERTEXTURE_H					 +#define LL_LLVIEWERTEXTURE_H + +#include "llgltexture.h" +#include "lltimer.h" +#include "llframetimer.h" +#include "llhost.h" +#include "llgltypes.h" +#include "llrender.h" +#include "llmetricperformancetester.h" +#include "httpcommon.h" + +#include <map> +#include <list> + +extern const S32Megabytes gMinVideoRam; +extern const S32Megabytes gMaxVideoRam; + +class LLFace; +class LLImageGL ; +class LLImageRaw; +class LLViewerObject; +class LLViewerTexture; +class LLViewerFetchedTexture ; +class LLViewerMediaTexture ; +class LLTexturePipelineTester ; + + +typedef	void	(*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); + +class LLVFile; +class LLMessageSystem; +class LLViewerMediaImpl ; +class LLVOVolume ; +struct LLTextureKey; + +class LLLoadedCallbackEntry +{ +public: +    typedef std::set< LLTextureKey > source_callback_list_t; + +public: +	LLLoadedCallbackEntry(loaded_callback_func cb, +						  S32 discard_level, +						  BOOL need_imageraw, // Needs image raw for the callback +						  void* userdata, +						  source_callback_list_t* src_callback_list, +						  LLViewerFetchedTexture* target, +						  BOOL pause); +	~LLLoadedCallbackEntry(); +	void removeTexture(LLViewerFetchedTexture* tex) ; + +	loaded_callback_func	mCallback; +	S32						mLastUsedDiscard; +	S32						mDesiredDiscard; +	BOOL					mNeedsImageRaw; +	BOOL                    mPaused; +	void*					mUserData; +	source_callback_list_t* mSourceCallbackList; +	 +public: +	static void cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list) ; +}; + +class LLTextureBar; + +class LLViewerTexture : public LLGLTexture +{ +public: +	enum +	{ +		LOCAL_TEXTURE,		 +		MEDIA_TEXTURE, +		DYNAMIC_TEXTURE, +		FETCHED_TEXTURE, +		LOD_TEXTURE, +		ATLAS_TEXTURE, +		INVALID_TEXTURE_TYPE +	}; + +	typedef std::vector<class LLFace*> ll_face_list_t; +	typedef std::vector<LLVOVolume*> ll_volume_list_t; + + +protected: +	virtual ~LLViewerTexture(); +	LOG_CLASS(LLViewerTexture); + +public:	 +	static void initClass(); +	static void updateClass(const F32 velocity, const F32 angular_velocity) ; +	 +	LLViewerTexture(BOOL usemipmaps = TRUE); +	LLViewerTexture(const LLUUID& id, BOOL usemipmaps) ; +	LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) ; +	LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ; + +	virtual S8 getType() const; +	virtual BOOL isMissingAsset() const ; +	virtual void dump();	// debug info to LL_INFOS() +	 +    virtual bool isViewerMediaTexture() const { return false; } + +	/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; +	/*virtual*/ bool bindDebugImage(const S32 stage = 0) ; +	/*virtual*/ void forceImmediateUpdate() ; +	/*virtual*/ bool isActiveFetching(); +	 +	/*virtual*/ const LLUUID& getID() const { return mID; } +	void setBoostLevel(S32 level); +	S32  getBoostLevel() { return mBoostLevel; } +	void setTextureListType(S32 tex_type) { mTextureListType = tex_type; } +	S32 getTextureListType() { return mTextureListType; } + +	void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const; +	void resetTextureStats();	 +	void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;} +	void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;} +	S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; } + +	virtual F32  getMaxVirtualSize() ; + +	LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;} +	 +	S32 getFullWidth() const { return mFullWidth; } +	S32 getFullHeight() const { return mFullHeight; }	 +	/*virtual*/ void setKnownDrawSize(S32 width, S32 height); + +	virtual void addFace(U32 channel, LLFace* facep) ; +	virtual void removeFace(U32 channel, LLFace* facep) ;  +	S32 getTotalNumFaces() const; +	S32 getNumFaces(U32 ch) const; +	const ll_face_list_t* getFaceList(U32 channel) const {llassert(channel < LLRender::NUM_TEXTURE_CHANNELS); return &mFaceList[channel];} + +	virtual void addVolume(U32 channel, LLVOVolume* volumep); +	virtual void removeVolume(U32 channel, LLVOVolume* volumep); +	S32 getNumVolumes(U32 channel) const; +	const ll_volume_list_t* getVolumeList(U32 channel) const { return &mVolumeList[channel]; } + +	 +	virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; +	BOOL isLargeImage() ;	 +	 +	void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;} +	BOOL hasParcelMedia() const { return mParcelMedia != NULL;} +	LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;} + +	/*virtual*/ void updateBindStatsForTester() ; +protected: +	void cleanup() ; +	void init(bool firstinit) ; +	void reorganizeFaceList() ; +	void reorganizeVolumeList() ; + +	void notifyAboutMissingAsset(); +	void notifyAboutCreatingTexture(); + +private: +	friend class LLBumpImageList; +	friend class LLUIImageList; + +	virtual void switchToCachedImage(); +	 +	static bool isMemoryForTextureLow() ; +	static bool isMemoryForTextureSuficientlyFree(); +	static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical); + +protected: +	LLUUID mID; +	S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList + +	F32 mSelectedTime;				// time texture was last selected +	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?	 +	mutable S32  mMaxVirtualSizeResetCounter ; +	mutable S32  mMaxVirtualSizeResetInterval; +	mutable F32 mAdditionalDecodePriority;  // priority add to mDecodePriority. +	LLFrameTimer mLastReferencedTimer;	 + +	ll_face_list_t    mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture +	U32               mNumFaces[LLRender::NUM_TEXTURE_CHANNELS]; +	LLFrameTimer      mLastFaceListUpdateTimer ; + +	ll_volume_list_t  mVolumeList[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; +	U32					mNumVolumes[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; +	LLFrameTimer	  mLastVolumeListUpdateTimer; + +	//do not use LLPointer here. +	LLViewerMediaTexture* mParcelMedia ; + +	static F32 sTexelPixelRatio; +public: +	static const U32 sCurrentFileVersion;	 +	static S32 sImageCount; +	static S32 sRawCount; +	static S32 sAuxCount; +	static LLFrameTimer sEvaluationTimer; +	static F32 sDesiredDiscardBias; +	static F32 sDesiredDiscardScale; +	static S32Bytes sBoundTextureMemory; +	static S32Bytes sTotalTextureMemory; +	static S32Megabytes sMaxBoundTextureMemory; +	static S32Megabytes sMaxTotalTextureMem; +	static S32Bytes sMaxDesiredTextureMem ; +	static S8  sCameraMovingDiscardBias; +	static F32 sCameraMovingBias; +	static S32 sMaxSculptRez ; +	static U32 sMinLargeImageSize ; +	static U32 sMaxSmallImageSize ; +	static bool sFreezeImageUpdates; +	static F32  sCurrentTime ; + +	enum EDebugTexels +	{ +		DEBUG_TEXELS_OFF, +		DEBUG_TEXELS_CURRENT, +		DEBUG_TEXELS_DESIRED, +		DEBUG_TEXELS_FULL +	}; + +	static EDebugTexels sDebugTexelsMode; + +	static LLPointer<LLViewerTexture> sNullImagep; // Null texture for non-textured objects. +	static LLPointer<LLViewerTexture> sBlackImagep;	// Texture to show NOTHING (pure black) +	static LLPointer<LLViewerTexture> sCheckerBoardImagep;	// Texture to show NOTHING (pure black) +}; + + +enum FTType +{ +	FTT_UNKNOWN = -1, +	FTT_DEFAULT = 0, // standard texture fetched by id. +	FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there. +	FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host. +	FTT_MAP_TILE, // tiles are fetched from map server directly. +	FTT_LOCAL_FILE // fetch directly from a local file. +}; + +const std::string& fttype_to_string(const FTType& fttype); + +// +//textures are managed in gTextureList. +//raw image data is fetched from remote or local cache +//but the raw image this texture pointing to is fixed. +// +class LLViewerFetchedTexture : public LLViewerTexture +{ +	friend class LLTextureBar; // debug info only +	friend class LLTextureView; // debug info only + +protected: +	/*virtual*/ ~LLViewerFetchedTexture(); +public: +	LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); +	LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps); +	LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); + +public: +	static F32 maxDecodePriority(); +	 +	struct Compare +	{ +		// lhs < rhs +		bool operator()(const LLPointer<LLViewerFetchedTexture> &lhs, const LLPointer<LLViewerFetchedTexture> &rhs) const +		{ +			const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs; +			const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs; +			// greater priority is "less" +			const F32 lpriority = lhsp->getDecodePriority(); +			const F32 rpriority = rhsp->getDecodePriority(); +			if (lpriority > rpriority) // higher priority +				return true; +			if (lpriority < rpriority) +				return false; +			return lhsp < rhsp; +		} +	}; + +public: +	/*virtual*/ S8 getType() const ; +	FTType getFTType() const; +	/*virtual*/ void forceImmediateUpdate() ; +	/*virtual*/ void dump() ; + +	// Set callbacks to get called when the image gets updated with higher  +	// resolution versions. +	void setLoadedCallback(loaded_callback_func cb, +						   S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, +						   void* userdata, LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause = FALSE); +	bool hasCallbacks() { return mLoadedCallbackList.empty() ? false : true; }	 +	void pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); +	void unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); +	bool doLoadedCallbacks(); +	void deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list); +	void clearCallbackEntryList() ; + +	void addToCreateTexture(); + +    //call to determine if createTexture is necessary +    BOOL preCreateTexture(S32 usename = 0); +	 // ONLY call from LLViewerTextureList or ImageGL background thread +	BOOL createTexture(S32 usename = 0); +    void postCreateTexture(); +    void scheduleCreateTexture(); + +	void destroyTexture() ; + +	virtual void processTextureStats() ; +	F32  calcDecodePriority() ; + +	BOOL needsAux() const { return mNeedsAux; } + +	// Host we think might have this image, used for baked av textures. +	void setTargetHost(LLHost host)			{ mTargetHost = host; } +	LLHost getTargetHost() const			{ return mTargetHost; } +	 +	// Set the decode priority for this image... +	// DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up +	// the priority list, and cause horrible things to happen. +	void setDecodePriority(F32 priority = -1.0f); +	F32 getDecodePriority() const { return mDecodePriority; }; +	F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; }; + +	void setAdditionalDecodePriority(F32 priority) ; +	 +	void updateVirtualSize() ; + +	S32  getDesiredDiscardLevel()			 { return mDesiredDiscardLevel; } +	void setMinDiscardLevel(S32 discard) 	{ mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } + +	bool updateFetch(); +	bool setDebugFetching(S32 debug_level); +	bool isInDebug() const { return mInDebug; } + +	void setUnremovable(BOOL value) { mUnremovable = value; } +	bool isUnremovable() const { return mUnremovable; } +	 +	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. +	/*virtual*/ void setKnownDrawSize(S32 width, S32 height); + +	void setIsMissingAsset(BOOL is_missing = true); +	/*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; } + +	// returns dimensions of original image for local files (before power of two scaling) +	// and returns 0 for all asset system images +	S32 getOriginalWidth() { return mOrigWidth; } +	S32 getOriginalHeight() { return mOrigHeight; } + +	BOOL isInImageList() const {return mInImageList ;} +	void setInImageList(BOOL flag) {mInImageList = flag ;} + +	LLFrameTimer* getLastPacketTimer() {return &mLastPacketTimer;} + +	U32 getFetchPriority() const { return mFetchPriority ;} +	F32 getDownloadProgress() const {return mDownloadProgress ;} + +	LLImageRaw* reloadRawImage(S8 discard_level) ; +	void destroyRawImage(); +	bool needsToSaveRawImage(); + +	const std::string& getUrl() const {return mUrl;} +	//--------------- +	BOOL isDeleted() ; +	BOOL isInactive() ; +	BOOL isDeletionCandidate(); +	void setDeletionCandidate() ; +	void setInactive() ; +	BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; }	 +	//--------------- + +	void setForSculpt(); +	BOOL forSculpt() const {return mForSculpt;} +	BOOL isForSculptOnly() const; + +	//raw image management	 +	void        checkCachedRawSculptImage() ; +	LLImageRaw* getRawImage()const { return mRawImage ;} +	S32         getRawImageLevel() const {return mRawDiscardLevel;} +	LLImageRaw* getCachedRawImage() const { return mCachedRawImage ;} +	S32         getCachedRawImageLevel() const {return mCachedRawDiscardLevel;} +	BOOL        isCachedRawImageReady() const {return mCachedRawImageReady ;} +	BOOL        isRawImageValid()const { return mIsRawImageValid ; }	 +	void        forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ; +	void        forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f); +	/*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ; +	void        destroySavedRawImage() ; +	LLImageRaw* getSavedRawImage() ; +	BOOL        hasSavedRawImage() const ; +	F32         getElapsedLastReferencedSavedRawImageTime() const ; +	BOOL		isFullyLoaded() const; + +	BOOL        hasFetcher() const { return mHasFetcher;} +	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; } + +	/*virtual*/bool  isActiveFetching(); //is actively in fetching by the fetching pipeline. + +protected: +	/*virtual*/ void switchToCachedImage(); +	S32 getCurrentDiscardLevelForFetching() ; + +private: +	void init(bool firstinit) ;	 +	void cleanup() ; + +	void saveRawImage() ; +	void setCachedRawImage() ; + +	//for atlas +	void resetFaceAtlas() ; +	void invalidateAtlas(BOOL rebuild_geom) ; +	BOOL insertToAtlas() ; + +private: +	BOOL  mFullyLoaded; +	BOOL  mInDebug; +	BOOL  mUnremovable; +	BOOL  mInFastCacheList; +	BOOL  mForceCallbackFetch; + +protected:		 +	std::string mLocalFileName; + +	S32 mOrigWidth; +	S32 mOrigHeight; + +	// 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. +	S32 mKnownDrawWidth; +	S32	mKnownDrawHeight; +	BOOL mKnownDrawSizeChanged ; +	std::string mUrl; +	 +	S32 mRequestedDiscardLevel; +	F32 mRequestedDownloadPriority; +	S32 mFetchState; +	U32 mFetchPriority; +	F32 mDownloadProgress; +	F32 mFetchDeltaTime; +	F32 mRequestDeltaTime; +	F32 mDecodePriority;			// The priority for decoding this image. +	S32	mMinDiscardLevel; +	S8  mDesiredDiscardLevel;			// The discard level we'd LIKE to have - if we have it and there's space	 +	S8  mMinDesiredDiscardLevel;	// The minimum discard level we'd like to have + +	S8  mNeedsAux;					// We need to decode the auxiliary channels +	S8  mHasAux;                    // We have aux channels +	S8  mDecodingAux;				// Are we decoding high components +	S8  mIsRawImageValid; +	S8  mHasFetcher;				// We've made a fecth request +	S8  mIsFetching;				// Fetch request is active +	bool mCanUseHTTP;              //This texture can be fetched through http if true. +	LLCore::HttpStatus mLastHttpGetStatus; // Result of the most recently completed http request for this texture. + +	FTType mFTType; // What category of image is this - map tile, server bake, etc? +	mutable S8 mIsMissingAsset;		// True if we know that there is no image asset with this image id in the database.		 + +	typedef std::list<LLLoadedCallbackEntry*> callback_list_t; +	S8              mLoadedCallbackDesiredDiscardLevel; +	BOOL            mPauseLoadedCallBacks; +	callback_list_t mLoadedCallbackList; +	F32             mLastCallBackActiveTime; + +	LLPointer<LLImageRaw> mRawImage; +	S32 mRawDiscardLevel; + +	// Used ONLY for cloth meshes right now.  Make SURE you know what you're  +	// doing if you use it for anything else! - djs +	LLPointer<LLImageRaw> mAuxRawImage; + +	//keep a copy of mRawImage for some special purposes +	//when mForceToSaveRawImage is set. +	BOOL mForceToSaveRawImage ; +	BOOL mSaveRawImage; +	LLPointer<LLImageRaw> mSavedRawImage; +	S32 mSavedRawDiscardLevel; +	S32 mDesiredSavedRawDiscardLevel; +	F32 mLastReferencedSavedRawImageTime ; +	F32 mKeptSavedRawImageTime ; + +	//a small version of the copy of the raw image (<= 64 * 64) +	LLPointer<LLImageRaw> mCachedRawImage; +	S32 mCachedRawDiscardLevel; +	BOOL mCachedRawImageReady; //the rez of the mCachedRawImage reaches the upper limit.	 + +	LLHost mTargetHost;	// if invalid, just request from agent's simulator + +	// Timers +	LLFrameTimer mLastPacketTimer;		// Time since last packet. +	LLFrameTimer mStopFetchingTimer;	// Time since mDecodePriority == 0.f. + +	BOOL  mInImageList;				// TRUE if image is in list (in which case don't reset priority!) +	BOOL  mNeedsCreateTexture;	 + +	BOOL   mForSculpt ; //a flag if the texture is used as sculpt data. +	BOOL   mIsFetched ; //is loaded from remote or from cache, not generated locally. + +public: +	static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep;	// Texture to show for an image asset that is not in the database +	static LLPointer<LLViewerFetchedTexture> sWhiteImagep;	// Texture to show NOTHING (whiteness) +	static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local. +	static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture +	static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface +}; + +// +//the image data is fetched from remote or from local cache +//the resolution of the texture is adjustable: depends on the view-dependent parameters. +// +class LLViewerLODTexture : public LLViewerFetchedTexture +{ +protected: +	/*virtual*/ ~LLViewerLODTexture(){} + +public: +	LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost(), BOOL usemipmaps = TRUE); +	LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE); + +	/*virtual*/ S8 getType() const; +	// Process image stats to determine priority/quality requirements. +	/*virtual*/ void processTextureStats(); +	bool isUpdateFrozen() ; + +private: +	void init(bool firstinit) ; +	bool scaleDown() ;		 + +private: +	F32 mDiscardVirtualSize;		// Virtual size used to calculate desired discard	 +	F32 mCalculatedDiscardLevel;    // Last calculated discard level +}; + +// +//the image data is fetched from the media pipeline periodically +//the resolution of the texture is also adjusted by the media pipeline +// +class LLViewerMediaTexture : public LLViewerTexture +{ +protected: +	/*virtual*/ ~LLViewerMediaTexture() ; + +public: +	LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + +	/*virtual*/ S8 getType() const; +	void reinit(BOOL usemipmaps = TRUE);	 + +	BOOL  getUseMipMaps() {return mUseMipMaps ; } +	void  setUseMipMaps(BOOL mipmap) ;	 +	 +	void setPlaying(BOOL playing) ; +	BOOL isPlaying() const {return mIsPlaying;} +	void setMediaImpl() ; + +    virtual bool isViewerMediaTexture() const { return true; } + +	void initVirtualSize() ;	 +	void invalidateMediaImpl() ; + +	void addMediaToFace(LLFace* facep) ; +	void removeMediaFromFace(LLFace* facep) ; + +	/*virtual*/ void addFace(U32 ch, LLFace* facep) ; +	/*virtual*/ void removeFace(U32 ch, LLFace* facep) ;  + +	/*virtual*/ F32  getMaxVirtualSize() ; +private: +	void switchTexture(U32 ch, LLFace* facep) ; +	BOOL findFaces() ; +	void stopPlaying() ; + +private: +	// +	//an instant list, recording all faces referencing or can reference to this media texture. +	//NOTE: it is NOT thread safe.  +	// +	std::list< LLFace* > mMediaFaceList ;  + +	//an instant list keeping all textures which are replaced by the current media texture, +	//is only used to avoid the removal of those textures from memory. +	std::list< LLPointer<LLViewerTexture> > mTextureList ; + +	LLViewerMediaImpl* mMediaImplp ;	 +	BOOL mIsPlaying ; +	U32  mUpdateVirtualSizeTime ; + +public: +	static void updateClass() ; +	static void cleanUpClass() ;	 + +	static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ; +	static void removeMediaImplFromTexture(const LLUUID& media_id) ; + +private: +	typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ; +	static media_map_t sMediaMap ;	 +}; + +//just an interface class, do not create instance from this class. +class LLViewerTextureManager +{ +private: +	//make the constructor private to preclude creating instances from this class. +	LLViewerTextureManager(){} + +public: +    //texture pipeline tester +	static LLTexturePipelineTester* sTesterp ; + +	//returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. +	static LLViewerFetchedTexture*    staticCastToFetchedTexture(LLTexture* tex, BOOL report_error = FALSE) ; + +	// +	//"find-texture" just check if the texture exists, if yes, return it, otherwise return null. +	// +	static void                       findFetchedTextures(const LLUUID& id, std::vector<LLViewerFetchedTexture*> &output); +	static void                       findTextures(const LLUUID& id, std::vector<LLViewerTexture*> &output); +	static LLViewerFetchedTexture*    findFetchedTexture(const LLUUID& id, S32 tex_type); +	static LLViewerMediaTexture*      findMediaTexture(const LLUUID& id) ; +	 +	static LLViewerMediaTexture*      createMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; + +	// +	//"get-texture" will create a new texture if the texture does not exist. +	// +	static LLViewerMediaTexture*      getMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ; +	 +	static LLPointer<LLViewerTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE); +	static LLPointer<LLViewerTexture> getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; +	static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ; +	static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ; + +	static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,									  +									 FTType f_type = FTT_DEFAULT, +									 BOOL usemipmap = TRUE, +									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation. +									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, +									 LLGLint internal_format = 0, +									 LLGLenum primary_format = 0, +									 LLHost request_from_host = LLHost() +									 ); +	 +	static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,									  +									 FTType f_type = FTT_LOCAL_FILE, +									 BOOL usemipmap = TRUE, +									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, +									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, +									 LLGLint internal_format = 0, +									 LLGLenum primary_format = 0, +									 const LLUUID& force_id = LLUUID::null +									 ); + +	static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,									  +									 FTType f_type, +									 BOOL usemipmap = TRUE, +									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE, +									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE, +									 LLGLint internal_format = 0, +									 LLGLenum primary_format = 0, +									 const LLUUID& force_id = LLUUID::null +									 ); + +	static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ; + +	static void init() ; +	static void cleanup() ; +}; +// +//this class is used for test/debug only +//it tracks the activities of the texture pipeline +//records them, and outputs them to log files +// +class LLTexturePipelineTester : public LLMetricPerformanceTesterWithSession +{ +	enum +	{ +		MIN_LARGE_IMAGE_AREA = 262144  //512 * 512 +	}; +public: +	LLTexturePipelineTester() ; +	~LLTexturePipelineTester() ; + +	void update();		 +	void updateTextureBindingStats(const LLViewerTexture* imagep) ; +	void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, BOOL from_cache) ; +	void updateGrayTextureBinding() ; +	void setStablizingTime() ; + +private: +	void reset() ; +	void updateStablizingTime() ; + +	/*virtual*/ void outputTestRecord(LLSD* sd) ; + +private: +	BOOL mPause ; +private: +	BOOL mUsingDefaultTexture;            //if set, some textures are still gray. + +	U32Bytes mTotalBytesUsed ;                     //total bytes of textures bound/used for the current frame. +	U32Bytes mTotalBytesUsedForLargeImage ;        //total bytes of textures bound/used for the current frame for images larger than 256 * 256. +	U32Bytes mLastTotalBytesUsed ;                 //total bytes of textures bound/used for the previous frame. +	U32Bytes mLastTotalBytesUsedForLargeImage ;    //total bytes of textures bound/used for the previous frame for images larger than 256 * 256. +		 +	// +	//data size +	// +	U32Bytes mTotalBytesLoaded ;               //total bytes fetched by texture pipeline +	U32Bytes mTotalBytesLoadedFromCache ;      //total bytes fetched by texture pipeline from local cache	 +	U32Bytes mTotalBytesLoadedForLargeImage ;  //total bytes fetched by texture pipeline for images larger than 256 * 256.  +	U32Bytes mTotalBytesLoadedForSculpties ;   //total bytes fetched by texture pipeline for sculpties + +	// +	//time +	//NOTE: the error tolerances of the following timers is one frame time. +	// +	F32 mStartFetchingTime ; +	F32 mTotalGrayTime ;                  //total loading time when no gray textures. +	F32 mTotalStablizingTime ;            //total stablizing time when texture memory overflows +	F32 mStartTimeLoadingSculpties ;      //the start moment of loading sculpty images. +	F32 mEndTimeLoadingSculpties ;        //the end moment of loading sculpty images. +	F32 mStartStablizingTime ; +	F32 mEndStablizingTime ; + +private: +	// +	//The following members are used for performance analyzing +	// +	class LLTextureTestSession : public LLTestSession +	{ +	public: +		LLTextureTestSession() ; +		/*virtual*/ ~LLTextureTestSession() ; + +		void reset() ; + +		F32 mTotalFetchingTime ; +		F32 mTotalGrayTime ; +		F32 mTotalStablizingTime ; +		F32 mStartTimeLoadingSculpties ;  +		F32 mTotalTimeLoadingSculpties ; + +		S32 mTotalBytesLoaded ;  +		S32 mTotalBytesLoadedFromCache ; +		S32 mTotalBytesLoadedForLargeImage ; +		S32 mTotalBytesLoadedForSculpties ;  + +		typedef struct _texture_instant_preformance_t +		{ +			S32 mAverageBytesUsedPerSecond ;          +			S32 mAverageBytesUsedForLargeImagePerSecond ; +			F32 mAveragePercentageBytesUsedPerSecond ; +			F32 mTime ; +		}texture_instant_preformance_t ; +		std::vector<texture_instant_preformance_t> mInstantPerformanceList ; +		S32 mInstantPerformanceListCounter ; +	}; + +	/*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ; +	/*virtual*/ void compareTestSessions(llofstream* os) ; +}; + +#endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ce73037006..7dc7b33938 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1516,8 +1516,15 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)  void LLViewerWindow::handleQuit(LLWindow *window)  { -	LL_INFOS() << "Window forced quit" << LL_ENDL; -	LLAppViewer::instance()->forceQuit(); +	if (gNonInteractive) +	{ +		LLAppViewer::instance()->requestQuit(); +	} +	else +	{ +		LL_INFOS() << "Window forced quit" << LL_ENDL; +		LLAppViewer::instance()->forceQuit(); +	}  }  void LLViewerWindow::handleResize(LLWindow *window,  S32 width,  S32 height) @@ -2189,6 +2196,14 @@ void LLViewerWindow::initBase()  void LLViewerWindow::initWorldUI()  { +	if (gNonInteractive) +	{ +		gIMMgr = LLIMMgr::getInstance(); +		LLNavigationBar::getInstance(); +		gFloaterView->pushVisibleAll(FALSE); +		return; +	} +	  	S32 height = mRootView->getRect().getHeight();  	S32 width = mRootView->getRect().getWidth();  	LLRect full_window(0, height, width, 0); @@ -2199,12 +2214,15 @@ void LLViewerWindow::initWorldUI()  	//getRootView()->sendChildToFront(gFloaterView);  	//getRootView()->sendChildToFront(gSnapshotFloaterView); -	LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container"); -	LLChicletBar* chiclet_bar = LLChicletBar::getInstance(); -	chiclet_bar->setShape(chiclet_container->getLocalRect()); -	chiclet_bar->setFollowsAll(); -	chiclet_container->addChild(chiclet_bar); -	chiclet_container->setVisible(TRUE); +	if (!gNonInteractive) +	{ +		LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container"); +		LLChicletBar* chiclet_bar = LLChicletBar::getInstance(); +		chiclet_bar->setShape(chiclet_container->getLocalRect()); +		chiclet_bar->setFollowsAll(); +		chiclet_container->addChild(chiclet_bar); +		chiclet_container->setVisible(TRUE); +	}  	LLRect morph_view_rect = full_window;  	morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); @@ -2293,21 +2311,24 @@ void LLViewerWindow::initWorldUI()  		gToolBarView->setVisible(TRUE);  	} -	LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); -	if (destinations) -	{ -		destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); -		std::string url = gSavedSettings.getString("DestinationGuideURL"); -		url = LLWeb::expandURLSubstitutions(url, LLSD()); -		destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML); -	} -	LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents"); -	if (avatar_picker) +	if (!gNonInteractive)  	{ -		avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); -		std::string url = gSavedSettings.getString("AvatarPickerURL"); -		url = LLWeb::expandURLSubstitutions(url, LLSD()); -		avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML); +		LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); +		if (destinations) +		{ +			destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); +			std::string url = gSavedSettings.getString("DestinationGuideURL"); +			url = LLWeb::expandURLSubstitutions(url, LLSD()); +			destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML); +		} +		LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents"); +		if (avatar_picker) +		{ +			avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); +			std::string url = gSavedSettings.getString("AvatarPickerURL"); +			url = LLWeb::expandURLSubstitutions(url, LLSD()); +			avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML); +		}  	}  } @@ -2551,7 +2572,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)  			mWindow->setMinSize(min_window_width, min_window_height);  			LLCoordScreen window_rect; -			if (mWindow->getSize(&window_rect)) +			if (!gNonInteractive && mWindow->getSize(&window_rect))  			{  			// Only save size if not maximized  				gSavedSettings.setU32("WindowWidth", window_rect.mX); diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 4d2eac8c09..86fe7c19bd 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -5358,7 +5358,9 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)  bool LLVivoxVoiceClient::voiceEnabled()  { -	return gSavedSettings.getBOOL("EnableVoiceChat") && !gSavedSettings.getBOOL("CmdLineDisableVoice"); +    return gSavedSettings.getBOOL("EnableVoiceChat") && +          !gSavedSettings.getBOOL("CmdLineDisableVoice") && +          !gNonInteractive;  }  void LLVivoxVoiceClient::setLipSyncEnabled(BOOL enabled) diff --git a/indra/newview/llworldmapmessage.cpp b/indra/newview/llworldmapmessage.cpp index 8be340de4c..e4a9f9afdb 100644 --- a/indra/newview/llworldmapmessage.cpp +++ b/indra/newview/llworldmapmessage.cpp @@ -150,6 +150,10 @@ void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16  // public static  void LLWorldMapMessage::processMapBlockReply(LLMessageSystem* msg, void**)  { +	if (gNonInteractive) +	{ +		return; +	}  	U32 agent_flags;  	msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c4976c4bbc..7aa05fb22f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -485,6 +485,10 @@ void LLPipeline::init()  	{  		clearAllRenderTypes();  	} +	else if (gNonInteractive) +	{ +		clearAllRenderTypes(); +	}  	else  	{  		setAllRenderTypes(); // By default, all rendering types start enabled @@ -1151,6 +1155,12 @@ void LLPipeline::refreshCachedSettings()  	RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");  	RenderSpotLight = nullptr;  	updateRenderDeferred(); + +	if (gNonInteractive) +	{ +		LLVOAvatar::sMaxNonImpostors = 1; +		LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors); +	}  }  void LLPipeline::releaseGLBuffers() @@ -3997,7 +4007,10 @@ void LLPipeline::postSort(LLCamera& camera)  	{  		mSelectedFaces.clear(); -		LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit()); +		if (!gNonInteractive) +		{ +			LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit()); +		}  		// Draw face highlights for selected faces.  		if (LLSelectMgr::getInstance()->getTEMode()) diff --git a/scripts/perf/perfbot_run.py b/scripts/perf/perfbot_run.py new file mode 100644 index 0000000000..55ea2fae66 --- /dev/null +++ b/scripts/perf/perfbot_run.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python3 +"""\ +@file perfbot_run.py +@brief Run a number of non interactive Viewers (PerfBots) with +       a variety of options and settings. Pass --help for details. + +$LicenseInfo:firstyear=2007&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2021, 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$ +""" + +import argparse +import subprocess +import os +import math +import time + +# Required parameters that are always passed in +# Specify noninteractive mode (SL-15999 for details) +PARAM_NON_INTERACTIVE = "--noninteractive" +# Run multiple Viewers at once +PARAM_MULTI = "--multiple" +# Specify username (first and last) and password +PARAM_LOGIN = "--login" +# SLURL to teleport to after login +PARAM_SLURL = "--slurl" + + +def gen_niv_script(args): +    print(f"Reading creds from {(args.creds)} folder") +    print(f"Using the non interactive Viewer from {(args.viewer)}") +    print(f"Sleeping for {args.sleep}ms between Viewer launches") + +    # Read the lines from the creds file.  Typically this will be +    # stored in the build-secrets-git private repository but you +    # can point to any location with the --creds parameter +    creds_lines = [] +    with open(args.creds) as file: +        creds_lines = file.readlines() +        creds_lines = [line.rstrip() for line in creds_lines] +        creds_lines = [line for line in creds_lines if not line.startswith("#") and len(line)] +    # We cannot log in more users than we have credentials for +    if args.num==0: +        args.num = len(creds_lines) +    if args.num > len(creds_lines): +        print( +            f"The number of agents specified ({(args.num)}) exceeds " +            f"the number of valid entries ({(len(creds_lines))}) in " +            f"the creds file " +        ) +        return + +    print(f"Launching {(args.num)} instances of the Viewer") + +    # The Viewer (in dev environments at least) needs a well specified +    # working directory to function properly. We try to guess what it +    # might be based on the full path to the Viewer executable but +    # you can also specify it explicitly with the --cwd parameter +    # (required for dev builds) +    args.viewer = os.path.abspath(args.viewer) +    if len(args.cwd) == 0: +        working_dir = os.path.dirname(os.path.abspath(args.viewer)) +    else: +        working_dir = os.path.abspath(args.cwd) +    print(f"Working directory is {working_dir}, cwd {args.cwd}") +    os.chdir(working_dir) + +    if args.dryrun: +        print("Running in dry-run mode - no Viewers will be started") +    print("") + +    for inst in range(args.num): + +        # Format of each cred line is username_first username_last password +        # A space is used to separate each and a # at the start of a line +        # removes it from the pool (useful if someone else is using a subset +        # of the available ones) +        creds = creds_lines[inst].split(" ") +        username_first = creds[0] +        username_last = creds[1] +        password = creds[2] + +        # The default layout is an evenly spaced circle in the +        # center of the region.  We may extend this to allow other +        # patterns like a square/rectangle or a spiral. (Hint: it +        # likely won't be needed :)) +        center_x = 128 +        center_y = 128 +        if args.layout == "circle": +            radius = 6 +            angle = (2 * math.pi / args.num) * inst +            region_x = int(math.sin(angle) * radius + center_x) +            region_y = int(math.cos(angle) * radius + center_y) +            region_z = 0 +        elif args.layout == "square": +            region_x = center_x +            region_y = center_y +        elif args.layout == "spiral": +            region_x = center_x +            region_y = center_y +        slurl = f"secondlife://{args.region}/{region_x}/{region_y}/{region_z}" + +        # Build the script line +        script_cmd = [args.viewer] +        script_cmd.append(PARAM_NON_INTERACTIVE) +        script_cmd.append(PARAM_MULTI) +        script_cmd.append(PARAM_LOGIN) +        script_cmd.append(username_first) +        script_cmd.append(username_last) +        script_cmd.append(password) +        script_cmd.append(PARAM_SLURL) +        script_cmd.append(slurl) + +        # Display the script we will execute. +        cmd = "" +        for p in script_cmd: +            cmd = cmd + " " + p +        print(cmd) + +        # If --dry-run is specified, we do everything (including, most +        # usefully, display the script lines) but do not start the Viewer +        if args.dryrun == False: +            print("opening viewer session with",script_cmd) +            viewer_session = subprocess.Popen(script_cmd) + +        # Sleeping a bit between launches seems to help avoid a CPU +        # surge when N Viewers are started simulatanously. The default +        # value can be changed with the --sleep parameter +        time.sleep(args.sleep / 1000) + + +if __name__ == "__main__": +    parser = argparse.ArgumentParser(allow_abbrev=False) +    parser.add_argument( +        "--num", +        type=int, +        default=0, +        dest="num", +        help="How many avatars to add to the script", +    ) +    parser.add_argument( +        "--creds", +        default="../../../build-secrets-git/perf/perfbot_creds.txt", +        dest="creds", +        help="Location of the text file containing user credentials", +    ) +    parser.add_argument( +        "--viewer", +        default="C:/Program Files/SecondLife/SecondLifeViewer.exe", +        dest="viewer", +        help="Location of the non interactive Viewer build", +    ) +    parser.add_argument( +        "--cwd", +        default="", +        dest="cwd", +        help="Location of the current working directory to use", +    ) +    parser.add_argument( +        "--region", +        default="Lag Me 5", +        dest="region", +        help="The SLURL for the Second Life region to visit", +    ) +    parser.add_argument( +        "--layout", +        default="circle", +        dest="layout", +        choices={"circle", "square", "spiral"}, +        help="The geometric layout of the avatar destination locations", +    ) +    parser.add_argument( +        "--sleep", +        type=int, +        default=1000, +        dest="sleep", +        help="Time to sleep between launches in milliseconds", +    ) +    parser.add_argument( +        "--dry-run", +        action="store_true", +        dest="dryrun", +        help="Dryrun mode - display parameters and script lines but do not start any Viewers", +    ) +    args = parser.parse_args() + +    gen_niv_script(args) | 
