Newer
Older
average_wind = regionp->mWind.getAverage();
gSky.setWind(average_wind);
//LLVOWater::setWind(average_wind);
}
else
{
gWindVec.setVec(0.0f, 0.0f, 0.0f);
Steven Bennetts
committed
}
Steven Bennetts
committed
//////////////////////////////////////
//
// Sort and cull in the new renderer are moved to pipeline.cpp
// Here, particles are updated and drawables are moved.
//
LL_RECORD_BLOCK_TIME(FTM_WORLD_UPDATE);
gPipeline.updateMove();
Steven Bennetts
committed
worldInst.updateParticles();
Steven Bennetts
committed
Brad Payne (Vir Linden)
committed
if (gAgentPilot.isPlaying() && gAgentPilot.getOverrideCamera())
Steven Bennetts
committed
{
Brad Payne (Vir Linden)
committed
gAgentPilot.moveCamera();
}
else if (LLViewerJoystick::getInstance()->getOverrideCamera())
Steven Bennetts
committed
}
else
{
if (LLToolMgr::getInstance()->inBuildMode())
{
LLViewerJoystick::getInstance()->moveObjects();
}
gAgentCamera.updateCamera();
Steven Bennetts
committed
}
// update media focus
LLViewerMediaFocus::getInstance()->update();
// Update marketplace
Leslie Linden
committed
LLMarketplaceInventoryImporter::update();
LLMarketplaceInventoryNotifications::update();
Steven Bennetts
committed
// objects and camera should be in sync, do LOD calculations now
{
LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE);
Steven Bennetts
committed
gObjectList.updateApparentAngles(gAgent);
}
simon
committed
// Update AV render info
LLAvatarRenderInfoAccountant::getInstance()->idle();
simon
committed
Steven Bennetts
committed
{
LL_RECORD_BLOCK_TIME(FTM_AUDIO_UPDATE);
Steven Bennetts
committed
if (gAudiop)
{
audio_update_volume(false);
audio_update_listener();
audio_update_wind(false);
// this line actually commits the changes we've made to source positions, etc.
const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
gAudiop->idle(max_audio_decode_time);
}
}
// Execute deferred tasks.
LLDeferredTaskList::instance().run();
// Handle shutdown process, for example,
Steven Bennetts
committed
// wait for floaters to close, send quit message,
// forcibly quit if it has taken too long
if (mQuitRequested)
{
Steven Bennetts
committed
idleShutdown();
}
}
void LLAppViewer::idleShutdown()
{
// Wait for all modal alerts to get resolved
if (LLModalDialog::activeCount() > 0)
{
return;
}
// close IM interface
if(gIMMgr)
{
gIMMgr->disconnectAllSessions();
}
Steven Bennetts
committed
// Wait for all floaters to get resolved
if (gFloaterView
&& !gFloaterView->allChildrenClosed())
{
return;
}
Yuri Chebotarev
committed
// ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup()
// *TODO: ugly
static bool saved_teleport_history = false;
if (!saved_teleport_history)
{
saved_teleport_history = true;
LLTeleportHistory::getInstance()->dump();
LLLocationHistory::getInstance()->save(); // *TODO: find a better place for doing this
return;
}
Steven Bennetts
committed
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
static bool saved_snapshot = false;
if (!saved_snapshot)
{
saved_snapshot = true;
saveFinalSnapshot();
return;
}
const F32 SHUTDOWN_UPLOAD_SAVE_TIME = 5.f;
S32 pending_uploads = gAssetStorage->getNumPendingUploads();
if (pending_uploads > 0
&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
&& !logoutRequestSent())
{
static S32 total_uploads = 0;
// Sometimes total upload count can change during logout.
total_uploads = llmax(total_uploads, pending_uploads);
gViewerWindow->setShowProgress(TRUE);
S32 finished_uploads = total_uploads - pending_uploads;
F32 percent = 100.f * finished_uploads / total_uploads;
gViewerWindow->setProgressPercent(percent);
gViewerWindow->setProgressString(LLTrans::getString("SavingSettings"));
Steven Bennetts
committed
return;
}
Brad Payne (Vir Linden)
committed
if (gPendingMetricsUploads > 0
&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
&& !logoutRequestSent())
{
return;
}
Steven Bennetts
committed
// All floaters are closed. Tell server we want to quit.
if( !logoutRequestSent() )
{
sendLogoutRequest();
// Wait for a LogoutReply message
gViewerWindow->setShowProgress(TRUE);
gViewerWindow->setProgressPercent(100.f);
gViewerWindow->setProgressString(LLTrans::getString("LoggingOut"));
Steven Bennetts
committed
return;
}
// Make sure that we quit if we haven't received a reply from the server.
if( logoutRequestSent()
Steven Bennetts
committed
&& gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime )
{
forceQuit();
return;
}
}
void LLAppViewer::sendLogoutRequest()
{
if(!mLogoutRequestSent && gMessageSystem)
Steven Bennetts
committed
{
Oz Linden
committed
//Set internal status variables and marker files before actually starting the logout process
gLogoutInProgress = TRUE;
Oz Linden
committed
{
mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
if (mLogoutMarkerFile.getFileHandle())
{
LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
recordMarkerVersion(mLogoutMarkerFile);
}
else
{
LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
Oz Linden
committed
}
else
{
LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL;
}
Steven Bennetts
committed
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LogoutRequest);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gAgent.sendReliableMessage();
gLogoutTimer.reset();
gLogoutMaxTime = LOGOUT_REQUEST_TIME;
mLogoutRequestSent = TRUE;
if(LLVoiceClient::instanceExists())
{
LLVoiceClient::getInstance()->leaveChannel();
}
Steven Bennetts
committed
}
}
void LLAppViewer::idleNameCache()
{
// Neither old nor new name cache can function before agent has a region
LLViewerRegion* region = gAgent.getRegion();
if (!region) return;
// deal with any queued name requests and replies.
gCacheName->processPending();
// Can't run the new cache until we have the list of capabilities
// for the agent region, and can therefore decide whether to use
// display names or fall back to the old name system.
if (!region->capabilitiesReceived()) return;
// Agent may have moved to a different region, so need to update cap URL
// for name lookups. Can't do this in the cap grant code, as caps are
// granted to neighbor regions before the main agent gets there. Can't
// do it in the move-into-region code because cap not guaranteed to be
// granted yet, for example on teleport.
LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
std::string name_lookup_url;
name_lookup_url.reserve(128); // avoid a memory allocation below
name_lookup_url = region->getCapability("GetDisplayNames");
bool have_capability = !name_lookup_url.empty();
if (have_capability)
{
// we have support for display names, use it
U32 url_size = name_lookup_url.size();
// capabilities require URLs with slashes before query params:
// https://<host>:<port>/cap/<uuid>/?ids=<blah>
// but the caps are granted like:
// https://<host>:<port>/cap/<uuid>
if (url_size > 0 && name_lookup_url[url_size-1] != '/')
{
name_lookup_url += '/';
}
name_cache->setNameLookupURL(name_lookup_url);
else
{
// Display names not available on this region
name_cache->setNameLookupURL( std::string() );
}
// Error recovery - did we change state?
if (had_capability != have_capability)
{
// name tags are persistant on screen, so make sure they refresh
LLVOAvatar::invalidateNameTags();
}
}
Steven Bennetts
committed
//
// Handle messages, and all message related stuff
//
#define TIME_THROTTLE_MESSAGES
#ifdef TIME_THROTTLE_MESSAGES
#define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!)
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
#endif
static LLTrace::BlockTimerStatHandle FTM_IDLE_NETWORK("Idle Network");
static LLTrace::BlockTimerStatHandle FTM_MESSAGE_ACKS("Message Acks");
static LLTrace::BlockTimerStatHandle FTM_RETRANSMIT("Retransmit");
static LLTrace::BlockTimerStatHandle FTM_TIMEOUT_CHECK("Timeout Check");
static LLTrace::BlockTimerStatHandle FTM_DYNAMIC_THROTTLE("Dynamic Throttle");
static LLTrace::BlockTimerStatHandle FTM_CHECK_REGION_CIRCUIT("Check Region Circuit");
Steven Bennetts
committed
void LLAppViewer::idleNetwork()
{
pingMainloopTimeout("idleNetwork");
Steven Bennetts
committed
gObjectList.mNumNewObjects = 0;
S32 total_decoded = 0;
static const LLCachedControl<bool> speedTest(gSavedSettings, "SpeedTest");
if (!speedTest)
Steven Bennetts
committed
{
LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode
Steven Bennetts
committed
LLTimer check_message_timer;
// Read all available packets from network
Steven Bennetts
committed
const S64 frame_count = gFrameCount; // U32->S64
F32 total_time = 0.0f;
Steven Bennetts
committed
{
LockMessageChecker lmc(gMessageSystem);
while (lmc.checkAllMessages(frame_count, gServicePump))
Steven Bennetts
committed
{
if (gDoDisconnect)
{
// We're disconnecting, don't process any more messages from the server
// We're usually disconnecting due to either network corruption or a
// server going down, so this is OK.
break;
}
total_decoded++;
gPacketsIn++;
Steven Bennetts
committed
if (total_decoded > MESSAGE_MAX_PER_FRAME)
{
break;
}
Steven Bennetts
committed
#ifdef TIME_THROTTLE_MESSAGES
// Prevent slow packets from completely destroying the frame rate.
// This usually happens due to clumps of avatars taking huge amount
// of network processing time (which needs to be fixed, but this is
// a good limit anyway).
total_time = check_message_timer.getElapsedTimeF32();
if (total_time >= CheckMessagesMaxTime)
break;
Steven Bennetts
committed
#endif
// Handle per-frame message system processing.
static LLCachedControl<F32> sAckCollectTime(gSavedSettings, "AckCollectTime", 0.1f);
lmc.processAcks(sAckCollectTime);
Steven Bennetts
committed
#ifdef TIME_THROTTLE_MESSAGES
if (total_time >= CheckMessagesMaxTime)
{
// Increase CheckMessagesMaxTime so that we will eventually catch up
CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
}
else
{
// Reset CheckMessagesMaxTime to default value
CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
}
#endif
Steven Bennetts
committed
// we want to clear the control after sending out all necessary agent updates
gAgent.resetControlFlags();
Steven Bennetts
committed
// Decode enqueued messages...
S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
if( remaining_possible_decodes <= 0 )
{
LL_INFOS() << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << LL_ENDL;
Steven Bennetts
committed
}
if (gPrintMessagesThisFrame)
{
LL_INFOS() << "Decoded " << total_decoded << " msgs this frame!" << LL_ENDL;
Steven Bennetts
committed
gPrintMessagesThisFrame = FALSE;
}
}
add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
Steven Bennetts
committed
// Retransmit unacknowledged packets.
gXferManager->retransmitUnackedPackets();
gAssetStorage->checkForTimeouts();
gViewerThrottle.updateDynamicThrottle();
// Check that the circuit between the viewer and the agent's current
// region is still alive
LLViewerRegion *agent_region = gAgent.getRegion();
if (agent_region && (LLStartUp::getStartupState()==STATE_STARTED))
{
LLUUID this_region_id = agent_region->getRegionID();
bool this_region_alive = agent_region->isAlive();
if ((mAgentRegionLastAlive && !this_region_alive) // newly dead
&& (mAgentRegionLastID == this_region_id)) // same region
{
forceDisconnect(LLTrans::getString("AgentLostConnection"));
}
mAgentRegionLastID = this_region_id;
mAgentRegionLastAlive = this_region_alive;
}
Steven Bennetts
committed
}
void LLAppViewer::disconnectViewer()
{
if (gDisconnected)
{
return;
}
//
// Cleanup after quitting.
Steven Bennetts
committed
// Save snapshot for next time, if we made it through initialization
LL_INFOS() << "Disconnecting viewer!" << LL_ENDL;
Steven Bennetts
committed
// Dump our frame statistics
// Remember if we were flying
gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() );
// Un-minimize all windows so they don't get saved minimized
Steven Bennetts
committed
{
gFloaterView->restoreAll();
Steven Bennetts
committed
}
Steven Bennetts
committed
{
LLSelectMgr::getInstance()->deselectAll();
Steven Bennetts
committed
}
James Cook
committed
// save inventory if appropriate
gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
if (gInventory.getLibraryRootFolderID().notNull()
&& gInventory.getLibraryOwnerID().notNull())
Steven Bennetts
committed
{
James Cook
committed
gInventory.cache(
gInventory.getLibraryRootFolderID(),
gInventory.getLibraryOwnerID());
Steven Bennetts
committed
}
saveNameCache();
if (LLExperienceCache::instanceExists())
{
// TODO: LLExperienceCache::cleanup() logic should be moved to
// cleanupSingleton().
LLExperienceCache::instance().cleanup();
}
Steven Bennetts
committed
// close inventory interface, close all windows
LLSidepanelInventory::cleanup();
Steven Bennetts
committed
Kitty Barnett
committed
// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
// Destroying all objects below will trigger attachment detaching code and attempt to remove the COF links for them
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(false);
// [/SL:KB]
Kitty Barnett
committed
// [RLVa:KB] - Checked: RLVa-2.3 (Housekeeping)
SUBSYSTEM_CLEANUP(RlvHandler);
// [/RLVa:KB]
gAgentWearables.cleanup();
gAgentCamera.cleanup();
Steven Bennetts
committed
// Also writes cached agent settings to gSavedSettings
gAgent.cleanup();
// This is where we used to call gObjectList.destroy() and then delete gWorldp.
// Now we just ask the LLWorld singleton to cleanly shut down.
Mark Palange (Mani)
committed
if(LLWorld::instanceExists())
{
LLWorld::getInstance()->destroyClass();
}
LLVOCache::deleteSingleton();
Steven Bennetts
committed
// call all self-registered classes
LLDestroyClassList::instance().fireCallbacks();
Steven Bennetts
committed
cleanup_xfer_manager();
gDisconnected = TRUE;
Seth ProductEngine
committed
// Pass the connection state to LLUrlEntryParcel not to attempt
// parcel info requests while disconnected.
LLUrlEntryParcel::setDisconnected(gDisconnected);
Steven Bennetts
committed
}
void LLAppViewer::forceErrorLLError()
{
LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
Steven Bennetts
committed
}
void LLAppViewer::forceErrorBreakpoint()
{
LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL;
Steven Bennetts
committed
#ifdef LL_WINDOWS
DebugBreak();
Mnikolenko Productengine
committed
#else
asm ("int $3");
Steven Bennetts
committed
#endif
return;
}
void LLAppViewer::forceErrorBadMemoryAccess()
{
LL_WARNS() << "Forcing a deliberate bad memory access" << LL_ENDL;
Steven Bennetts
committed
S32* crash = NULL;
*crash = 0xDEADBEEF;
Steven Bennetts
committed
return;
}
void LLAppViewer::forceErrorInfiniteLoop()
Steven Bennetts
committed
{
LL_WARNS() << "Forcing a deliberate infinite loop" << LL_ENDL;
Steven Bennetts
committed
while(true)
{
;
}
return;
}
Steven Bennetts
committed
void LLAppViewer::forceErrorSoftwareException()
{
LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL;
LLTHROW(LLException("User selected Force Software Exception"));
Steven Bennetts
committed
}
Mark Palange
committed
void LLAppViewer::forceErrorDriverCrash()
{
LL_WARNS() << "Forcing a deliberate driver crash" << LL_ENDL;
Mark Palange
committed
glDeleteTextures(1, NULL);
}
void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs)
if(!mMainloopTimeout)
mMainloopTimeout = new LLWatchdogTimeout();
resumeMainloopTimeout(state, secs);
}
}
void LLAppViewer::destroyMainloopTimeout()
{
if(mMainloopTimeout)
{
delete mMainloopTimeout;
mMainloopTimeout = NULL;
}
}
void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs)
{
if(mMainloopTimeout)
{
if(secs < 0.0f)
{
static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
secs = mainloop_timeout;
mMainloopTimeout->setTimeout(secs);
mMainloopTimeout->start(state);
}
}
void LLAppViewer::pauseMainloopTimeout()
{
if(mMainloopTimeout)
{
mMainloopTimeout->stop();
}
}
void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
// if(!restoreErrorTrap())
// {
// LL_WARNS() << "!!!!!!!!!!!!! Its an error trap!!!!" << state << LL_ENDL;
if(mMainloopTimeout)
{
if(secs < 0.0f)
{
static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
secs = mainloop_timeout;
}
mMainloopTimeout->setTimeout(secs);
mMainloopTimeout->ping(state);
}
void LLAppViewer::handleLoginComplete()
{
gLoggedInTime.start();
initMainloopTimeout("Mainloop Init");
// Store some data to DebugInfo in case of a freeze.
gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::instance().getChannel();
gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::instance().getMajor();
gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::instance().getMinor();
gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::instance().getPatch();
gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::instance().getBuild();
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
{
gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL();
if ( parcel && parcel->getMediaURL()[0])
{
gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL();
}
gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
if(gAgent.getRegion())
{
gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
}
if(LLAppViewer::instance()->mMainloopTimeout)
{
gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
}
gWindowTitle.append(" - ").append(gAgentAvatarp->getFullname());
gViewerWindow->setWindowTitle(gWindowTitle);

Rye Mutt
committed
// [SL:KB] - Patch: Build-AssetRecovery | Checked: 2011-11-24 (Catznip-3.2)
LLAssetRecoverQueue::recoverIfNeeded();
// [/SL:KB]
// we logged in successfully, so save settings on logout
LL_INFOS() << "Login successful, per account settings will be saved on log out." << LL_ENDL;
mSavePerAccountSettings=true;
//virtual
void LLAppViewer::setMasterSystemAudioMute(bool mute)
{
gSavedSettings.setBOOL("MuteAudio", mute);
}
//virtual
bool LLAppViewer::getMasterSystemAudioMute()
{
static const LLCachedControl<bool> mute_audio(gSavedSettings, "MuteAudio");
return mute_audio;
//----------------------------------------------------------------------------
// Metrics-related methods (static and otherwise)
//----------------------------------------------------------------------------
/**
* LLViewerAssetStats collects data on a per-region (as defined by the agent's
* location) so we need to tell it about region changes which become a kind of
* hidden variable/global state in the collectors. For collectors not running
* on the main thread, we need to send a message to move the data over safely
* and cheaply (amortized over a run).
*/
Monty Brandenberg
committed
void LLAppViewer::metricsUpdateRegion(U64 region_handle)
Monty Brandenberg
committed
if (0 != region_handle)
LLViewerAssetStatsFF::set_region(region_handle);
}
}
/**
* Attempts to start a multi-threaded metrics report to be sent back to
* the grid for consumption.
*/
void LLAppViewer::metricsSend(bool enable_reporting)
if (! gViewerAssetStats)
LLViewerRegion * regionp = gAgent.getRegion();
if (enable_reporting && regionp)
std::string caps_url = regionp->getCapability("ViewerMetrics");
Brad Payne (Vir Linden)
committed
LLSD sd = gViewerAssetStats->asLLSD(true);
Brad Payne (Vir Linden)
committed
// Send a report request into 'thread1' to get the rest of the data
// and provide some additional parameters while here.
LLAppViewer::sTextureFetch->commandSendMetrics(caps_url,
gAgentSessionID,
gAgentID,
Brad Payne (Vir Linden)
committed
sd);
LLAppViewer::sTextureFetch->commandDataBreak();
}
}
// Reset even if we can't report. Rather than gather up a huge chunk of
// data, we'll keep to our sampling interval and retain the data
// resolution in time.
Richard Linden
committed
gViewerAssetStats->restart();