summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llrender/llgl.cpp1
-rw-r--r--indra/llrender/llgl.h1
-rw-r--r--indra/llwindow/llwindow.cpp6
-rw-r--r--indra/llwindow/llwindow.h7
-rw-r--r--indra/llwindow/llwindowwin32.cpp7
-rw-r--r--indra/llwindow/llwindowwin32.h1
-rw-r--r--indra/newview/app_settings/cmd_line.xml8
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/llagent.cpp2
-rw-r--r--indra/newview/llappviewer.cpp88
-rw-r--r--indra/newview/lldynamictexture.cpp7
-rw-r--r--indra/newview/llteleporthistory.cpp27
-rw-r--r--indra/newview/lltexturefetch.cpp4
-rw-r--r--indra/newview/llviewerdisplay.cpp6
-rw-r--r--indra/newview/llviewerfloaterreg.cpp4
-rw-r--r--indra/newview/llviewermedia.cpp7
-rw-r--r--indra/newview/llviewermessage.cpp4
-rw-r--r--indra/newview/llviewerobject.cpp21
-rw-r--r--indra/newview/llviewerobjectlist.cpp4
-rw-r--r--indra/newview/llviewertexture.h1592
-rw-r--r--indra/newview/llviewerwindow.cpp67
-rw-r--r--indra/newview/llvoicevivox.cpp4
-rw-r--r--indra/newview/llworldmapmessage.cpp4
-rw-r--r--indra/newview/pipeline.cpp15
-rw-r--r--scripts/perf/perfbot_run.py204
25 files changed, 1253 insertions, 860 deletions
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 0100c3bf0a..c7df729782 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -97,6 +97,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 12d4c6c30e..e668fc1eed 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -1923,6 +1923,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 5f253b5df3..ea1c103bcd 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -93,6 +93,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 82ece85c1b..2342b6219c 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..006d5f8934
--- /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)
+ working_dir = args.cwd
+ if len(args.cwd) == 0:
+ working_dir = os.path.dirname(os.path.abspath(args.viewer))
+ print(f"Working directory is {working_dir} {args.cwd=}")
+ environ = os.environ
+ environ["cwd"] = 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,env=environ)
+
+ # 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)